home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume15 / xmodem3.6 / part03 < prev    next >
Text File  |  1988-06-13  |  24KB  |  860 lines

  1. Subject:  v15i072:  Xmodem release 3.6, Part03/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Steve Grandi <grandi@noao.arizona.edu>
  7. Posting-number: Volume 15, Issue 72
  8. Archive-name: xmodem3.6/part03
  9.  
  10. : This is a shar archive.  Extract with sh, not csh.
  11. echo x - getput.c
  12. sed -e 's/^X//' > getput.c << '!Funky!Stuff!'
  13. X/*
  14. X * Contains system routines to get and put bytes, change tty modes, etc
  15. X * Most of the routines are VERY 4.2BSD Specific!!!
  16. X */
  17. X
  18. X#include "xmodem.h"
  19. X
  20. X/*
  21. X *
  22. X *    Get a byte from the specified file.  Buffer the read so we don't
  23. X *    have to use a system call for each character.
  24. X *
  25. X */
  26. Xgetbyte(fildes, ch)                /* Buffered disk read */
  27. Xint fildes;
  28. Xchar *ch;
  29. X
  30. X    {
  31. X    static char buf[BUFSIZ];    /* Remember buffer */
  32. X    static char *bufp = buf;    /* Remember where we are in buffer */
  33. X    
  34. X    if (nbchr == 0)            /* Buffer exausted; read some more */
  35. X        {
  36. X        if ((nbchr = read(fildes, buf, BUFSIZ)) < 0)
  37. X            error("File Read Error", TRUE);
  38. X        bufp = buf;        /* Set pointer to start of array */
  39. X        }
  40. X    if (--nbchr >= 0)
  41. X        {
  42. X        *ch = *bufp++;
  43. X        return(0);
  44. X        }
  45. X    else
  46. X        {
  47. X        return(EOF);
  48. X        }
  49. X    }
  50. X
  51. X/* Count the number of newlines in a file so we know the REAL file size */
  52. X
  53. Xlong
  54. Xcountnl(fd)
  55. Xint fd;
  56. X{
  57. X    char buf[BUFSIZ];
  58. X    char *bufp;
  59. X    long nltot = 0;
  60. X    int numchar;
  61. X    long lseek();
  62. X
  63. X    while (numchar = read(fd, buf, BUFSIZ))        /* cycle through file */
  64. X        for (bufp=buf; numchar--; bufp++)
  65. X            if (*bufp == '\n')
  66. X                nltot++;
  67. X
  68. X    (void) lseek (fd, 0l, 0);            /* rewind file */
  69. X    if (DEBUG)
  70. X        fprintf(LOGFP, "DEBUG: countnl--%ld newlines counted\n", nltot);
  71. X    return (nltot);
  72. X}
  73. X
  74. X/*   CRC-16 constant array...
  75. X     from Usenet contribution by Mark G. Mendel, Network Systems Corp.
  76. X     (ihnp4!umn-cs!hyper!mark)
  77. X*/
  78. X
  79. X/* crctab as calculated by initcrctab() */
  80. Xunsigned short crctab[1<<B] = { 
  81. X    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  82. X    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  83. X    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  84. X    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  85. X    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  86. X    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  87. X    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  88. X    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  89. X    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  90. X    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  91. X    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  92. X    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  93. X    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  94. X    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  95. X    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  96. X    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  97. X    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  98. X    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  99. X    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
  100. X    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
  101. X    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
  102. X    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
  103. X    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
  104. X    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
  105. X    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  106. X    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
  107. X    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  108. X    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  109. X    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  110. X    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  111. X    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  112. X    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  113. X    };
  114. X
  115. X/* get a byte from data stream -- timeout if "seconds" elapses */
  116. X/* This routine is VERY 4.2 specific */
  117. X
  118. Xint
  119. Xreadbyte(seconds)
  120. Xint seconds;
  121. X    {
  122. X    int readfd;
  123. X    char c;
  124. X    struct timeval tmout;
  125. X
  126. X    tmout.tv_sec = seconds;
  127. X    tmout.tv_usec = 0;
  128. X
  129. X    readfd = 1<<0;
  130. X
  131. X    if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
  132. X        return(TIMEOUT);
  133. X
  134. X    read(0, &c, 1);
  135. X
  136. X    if (DEBUG)
  137. X        fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
  138. X
  139. X    return(c & 0xff);  /* return the char */
  140. X    }
  141. X
  142. X/* flush input stream by reading pending characters */
  143. X
  144. Xflushin()
  145. X    {
  146. X    int readfd;
  147. X    char inbuf[BBUFSIZ];
  148. X    struct timeval tmout;
  149. X
  150. X    /* set up a usec timeout on stdin */
  151. X    tmout.tv_sec = 0;
  152. X    tmout.tv_usec = 1;
  153. X    readfd = 1<<0;
  154. X
  155. X    /* any characters pending?; return if none */
  156. X    if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
  157. X        return;
  158. X
  159. X    /* read the characters to flush them (assume there are fewer than BBUFSIZ */
  160. X    (void) read(0, inbuf, BBUFSIZ);
  161. X    }
  162. X
  163. X/* 
  164. X get a buffer (length bufsize) from data stream -- timeout if "seconds" elapses.
  165. X Read bunches of characters to save system overhead;
  166. X Further process data while kernel is reading stream (calculating "checksum").
  167. X Try to nap long enough so kernel collects 100 characters or so until we wake up
  168. X unless TOOBUSY is set.
  169. X*/
  170. X
  171. X/* This routine is VERY 4.2 specific */
  172. X
  173. Xint
  174. Xreadbuf(bufsize, seconds, tmode, amode, recvsectcnt, checksum, bufctr)
  175. X
  176. Xint bufsize,    /* number of chars to be read */
  177. Xseconds,     /* timeout period for each read */
  178. Xtmode,         /* transmission mode: TRUE if text */
  179. Xamode,         /* transmission mode: TRUE if apple macintosh */
  180. X*checksum,     /* pointer to checksum value */
  181. X*bufctr;    /* length of actual data string in buffer */
  182. Xlong recvsectcnt;    /* running sector count (128 byte sectors) */
  183. X
  184. X{
  185. X    int readfd;        /* mask for select call */
  186. X    struct timeval tmout;    /* timeout structure for select */
  187. X    int numread;        /* number of chars read */
  188. X    int left;        /* number of chars left to read */
  189. X    int recfin = FALSE;        /* flag that EOF read */
  190. X    char inbuf[BBUFSIZ];    /* buffer for incoming packet */
  191. X    register unsigned char c;    /* character being processed */
  192. X    register unsigned short chksm;    /* working copy of checksum */
  193. X    register int bfctr;    /* working copy of bufctr */
  194. X    int j;            /* loop index */
  195. X    char *sectdisp();
  196. X
  197. X    tmout.tv_sec = seconds;
  198. X    tmout.tv_usec = 0;
  199. X    readfd = 1<<0;
  200. X    chksm = 0;
  201. X    bfctr = 0;
  202. X
  203. X    for (left = bufsize; left > 0;) {
  204. X
  205. X        /* read however many chars are waiting */
  206. X
  207. X        if ((select(1, &readfd, (int *)0, (int *)0, &tmout)) == 0)
  208. X            return(TIMEOUT);
  209. X
  210. X        numread = read(0, inbuf, left);
  211. X        left -= numread;
  212. X
  213. X        if (DEBUG)
  214. X            fprintf(LOGFP, "DEBUG: readbuf--read %d characters\n", numread);
  215. X
  216. X        /* now process part of packet we just read */
  217. X
  218. X        for (j =  0; j < numread; j++) 
  219. X            {  
  220. X                buff[bfctr] = c = inbuf[j] & 0xff;
  221. X                fileread++;
  222. X
  223. X                if (CRCMODE)  /* CRC */
  224. X                    chksm = (chksm<<B) ^ crctab[(chksm>>(W-B)) ^ c];
  225. X
  226. X                else        /* checksum */
  227. X                           chksm = ((chksm+c) & 0xff);
  228. X
  229. X                if (CHECKLENGTH && fileread > filelength)    /* past EOF ? */
  230. X                    continue;
  231. X
  232. X                if (tmode)         /* text mode processing */
  233. X                    {
  234. X                    buff[bfctr] &= 0x7f;    /* nuke bit 8 */
  235. X                    if (c == CR || c == 0)    /* skip CRs and nulls */
  236. X                        continue;
  237. X                    else if (c == CTRLZ)    /* CP/M EOF char */
  238. X                        {  
  239. X                        recfin = TRUE;
  240. X                               continue;
  241. X                               }
  242. X                           else if (!recfin)    /* don't increment if past EOF */
  243. X                        bfctr++;
  244. X                    }
  245. X                else if (amode)     /* Apple macintosh text mode processing */
  246. X                    {
  247. X                    buff[bfctr] &= 0x7f;    /* nuke bit 8 */
  248. X                    if (c == 0)        /* skip nulls */
  249. X                        continue;
  250. X                    else if (c == CR)    /* translate CR to LF */
  251. X                        buff[bfctr] = LF;
  252. X                    else if (c == CTRLZ)    /* CP/M EOF char */
  253. X                        {  
  254. X                        recfin = TRUE;
  255. X                               continue;
  256. X                               }
  257. X                           if (!recfin)        /* don't increment if past EOF */
  258. X                        bfctr++;
  259. X                    }
  260. X                else            /* binary */
  261. X                    bfctr++;
  262. X
  263. X                 }    
  264. X
  265. X        /* go to sleep to save uneeded system calls while kernel
  266. X           is reading data from serial line; 
  267. X           fudge constant from 10000 to 9000 to avoid sleeping too long.
  268. X        */
  269. X        if (left && !TOOBUSY)
  270. X            napms( (left<SLEEPNUM ? left:SLEEPNUM) * 9000/ttyspeed);
  271. X
  272. X    }
  273. X
  274. X    if (CHECKLENGTH && fileread >= filelength)
  275. X        logitarg("File end from YMODEM length found in sector %s\n",
  276. X          sectdisp(recvsectcnt,bufsize,1));
  277. X    *checksum = chksm;
  278. X    *bufctr = bfctr;
  279. X    return(0);
  280. X}
  281. X
  282. X/* send a byte to data stream */
  283. X
  284. Xsendbyte(data)
  285. Xchar data;
  286. X    {
  287. X    if (DEBUG)
  288. X        fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
  289. X
  290. X    if (write(1, &data, 1) != 1)      /* write the byte (assume it goes NOW; no flushing needed) */
  291. X        error ("Write error on stream", TRUE);
  292. X    return;
  293. X    }
  294. X
  295. X/* send a buffer to data stream */
  296. X
  297. Xwritebuf(buffer, nbytes)
  298. Xchar *buffer;
  299. Xint  nbytes;
  300. X    {
  301. X    if (DEBUG)
  302. X        fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
  303. X
  304. X    if (write(1, buffer, nbytes) != nbytes)        /* write the buffer (assume no TIOCFLUSH needed) */
  305. X        error ("Write error on stream", TRUE);
  306. X    return;
  307. X    }
  308. X
  309. X/*
  310. X * "nap" for specified time -- VERY 4.2BSD specific
  311. X */
  312. X
  313. Xnapms (milliseconds)
  314. Xint    milliseconds;
  315. X{
  316. X    struct    timeval    timeout;
  317. X    int readfd;
  318. X
  319. X    if (milliseconds == 0)
  320. X        return;
  321. X    if (DEBUG)
  322. X        fprintf (LOGFP, "DEBUG: napping for %d ms\n", milliseconds);
  323. X    timeout.tv_sec = 0;
  324. X    timeout.tv_usec = milliseconds * 1000;
  325. X    readfd = 0;
  326. X
  327. X    (void) select(1, &readfd, (int *)0, (int *)0, &timeout);
  328. X}
  329. X
  330. X/* set and restore tty modes for XMODEM transfers */
  331. X/* These routines are 4.2/v7(?) specific */
  332. X
  333. Xstruct sgttyb ttys, ttysnew;    /* for stty terminal mode calls */
  334. Xstruct stat statbuf;        /* for terminal message on/off control */
  335. X
  336. Xint wason;            /* holds status of tty read write/modes */
  337. Xchar *tty;            /* current tty name */
  338. X
  339. X
  340. Xsetmodes()
  341. X    {
  342. X    char *ttyname();
  343. X
  344. X    int n;
  345. X
  346. X    extern onintr();
  347. X
  348. X    sleep(2);            /* let the output appear */
  349. X    if (ioctl(0,TIOCGETP,&ttys)<0)  /* get tty params [V7] */
  350. X        error("Can't get TTY Parameters", TRUE);
  351. X
  352. X    tty = ttyname(0);  /* identify current tty */
  353. X    
  354. X    ttysnew.sg_ispeed = ttys.sg_ispeed;    /* copy input speed */
  355. X    ttysnew.sg_ospeed = ttys.sg_ospeed;    /* copy input speed */
  356. X    ttysnew.sg_flags |= RAW;    /* set for RAW Mode */
  357. X    ttysnew.sg_flags &= ~ECHO;    /* set for no echoing */
  358. X    ttysnew.sg_flags &= ~TANDEM;    /* turn off flow control */
  359. X
  360. X    /* set new paramters */
  361. X    if (ioctl(0,TIOCSETP,&ttysnew) < 0)
  362. X        error("Can't set new TTY Parameters", TRUE);
  363. X
  364. X    /* Flush characters waiting for read or write */
  365. X    n = 0;
  366. X    if (ioctl(0,TIOCFLUSH,&n) < 0)
  367. X        error("Can't flush terminal queue", TRUE);
  368. X
  369. X    /* get tty status */ 
  370. X    if (stat(tty, &statbuf) < 0)  
  371. X        error("Can't get your TTY Status", TRUE);
  372. X
  373. X    if (statbuf.st_mode & 022)    /* Need to turn messages off */
  374. X        if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
  375. X            error("Can't change  TTY mode", TRUE);
  376. X        else 
  377. X            wason = TRUE;
  378. X    else 
  379. X        wason = FALSE;
  380. X
  381. X    /* set up signal catcher to restore tty state if we are KILLed */
  382. X
  383. X    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  384. X        signal(SIGTERM, onintr);
  385. X    }
  386. X
  387. X/* restore normal tty modes */
  388. X
  389. Xrestoremodes(errcall)
  390. Xint errcall;
  391. X    {
  392. X    if (wason)
  393. X        if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
  394. X            error("Can't change TTY mode", FALSE);
  395. X    if (ioctl(0,TIOCSETP,&ttys) < 0)
  396. X        { if (!errcall)
  397. X           error("RESET - Can't restore normal TTY Params", FALSE);
  398. X        else
  399. X             printf("RESET - Can't restore normal TTY Params\n");
  400. X        }
  401. X    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  402. X        signal(SIGTERM, SIG_DFL);
  403. X    return;
  404. X    }
  405. X
  406. X
  407. X
  408. X
  409. X/* signal catcher */
  410. Xonintr()
  411. X    {
  412. X    error("Kill signal; bailing out", TRUE);
  413. X    }
  414. X
  415. X/* create string with a timestamp for log file */
  416. X
  417. Xchar *stamptime()
  418. X{
  419. X    char *asctime();        /* stuff to get timestamp */
  420. X    struct tm *localtime(), *tp;
  421. X    struct timeval tv;
  422. X    struct timezone tz;
  423. X
  424. X    gettimeofday (&tv, &tz);        /* fill in timestamp */
  425. X    tp = localtime ((time_t *)&tv.tv_sec);
  426. X    return(asctime(tp));
  427. X}
  428. X
  429. X
  430. X
  431. X/* get tty speed for time estimates */
  432. X
  433. Xgetspeed()
  434. X    {
  435. X    static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600, 
  436. X       1200, 1800, 2400, 4800, 9600, 19200, 0};
  437. X    if (ioctl(0,TIOCGETP,&ttys) < 0)    /* get tty structure */
  438. X        error("Can't get TTY parameters", FALSE);
  439. X
  440. X    if (ttys.sg_ispeed >= 0 && ttys.sg_ispeed <= 14)
  441. X        {
  442. X        ttyspeed = speedtbl[ttys.sg_ispeed];
  443. X        logitarg ("Line speed = %d bits per second\n", ttyspeed);
  444. X        }
  445. X    else
  446. X        {
  447. X        ttyspeed = 1200;
  448. X        logit ("Can't determine line speed; assuming 1200 bps\n");
  449. X        }
  450. X    }
  451. !Funky!Stuff!
  452. echo x - getput.sysv.c
  453. sed -e 's/^X//' > getput.sysv.c << '!Funky!Stuff!'
  454. X/*
  455. X * Contains system routines to get and put bytes, change tty modes, etc
  456. X * Sys V version.  UNTESTED!!!!!!
  457. X */
  458. X
  459. X#include "xmodem.h"
  460. X
  461. X/*
  462. X *
  463. X *    Get a byte from the specified file.  Buffer the read so we don't
  464. X *    have to use a system call for each character.
  465. X *
  466. X */
  467. Xgetbyte(fildes, ch)                /* Buffered disk read */
  468. Xint fildes;
  469. Xchar *ch;
  470. X
  471. X    {
  472. X    static char buf[BUFSIZ];    /* Remember buffer */
  473. X    static char *bufp = buf;    /* Remember where we are in buffer */
  474. X    
  475. X    if (nbchr == 0)            /* Buffer exausted; read some more */
  476. X        {
  477. X        if ((nbchr = read(fildes, buf, BUFSIZ)) < 0)
  478. X            error("File Read Error", TRUE);
  479. X        bufp = buf;        /* Set pointer to start of array */
  480. X        }
  481. X    if (--nbchr >= 0)
  482. X        {
  483. X        *ch = *bufp++;
  484. X        return(0);
  485. X        }
  486. X    else
  487. X        {
  488. X        return(EOF);
  489. X        }
  490. X    }
  491. X
  492. X/* Count the number of newlines in a file so we know the REAL file size */
  493. X
  494. Xlong
  495. Xcountnl(fd)
  496. Xint fd;
  497. X{
  498. X    char buf[BUFSIZ];
  499. X    char *bufp;
  500. X    long nltot = 0;
  501. X    int numchar;
  502. X    long lseek();
  503. X
  504. X    while (numchar = read(fd, buf, BUFSIZ))        /* cycle through file */
  505. X        for (bufp=buf; numchar--; bufp++)
  506. X            if (*bufp == '\n')
  507. X                nltot++;
  508. X
  509. X    (void) lseek (fd, 0l, 0);            /* rewind file */
  510. X    if (DEBUG)
  511. X        fprintf(LOGFP, "DEBUG: countnl--%ld newlines counted\n", nltot);
  512. X    return (nltot);
  513. X}
  514. X
  515. X/*   CRC-16 constant array...
  516. X     from Usenet contribution by Mark G. Mendel, Network Systems Corp.
  517. X     (ihnp4!umn-cs!hyper!mark)
  518. X*/
  519. X
  520. X/* crctab as calculated by initcrctab() */
  521. Xunsigned short crctab[1<<B] = { 
  522. X    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
  523. X    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
  524. X    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
  525. X    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
  526. X    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
  527. X    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
  528. X    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
  529. X    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
  530. X    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
  531. X    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
  532. X    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
  533. X    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
  534. X    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
  535. X    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
  536. X    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
  537. X    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
  538. X    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
  539. X    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
  540. X    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
  541. X    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
  542. X    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
  543. X    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
  544. X    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
  545. X    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
  546. X    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
  547. X    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
  548. X    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
  549. X    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
  550. X    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
  551. X    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
  552. X    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
  553. X    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
  554. X    };
  555. X
  556. X/* get a byte from data stream -- timeout if "seconds" elapses */
  557. X
  558. Xint timedout;
  559. Xint
  560. Xreadbyte(seconds)
  561. Xint seconds;
  562. X{
  563. X    int force_it();
  564. X    char c;
  565. X    signal(SIGALRM, force_it);
  566. X
  567. X    timedout = 0;
  568. X    alarm(seconds);
  569. X    read(0, &c, 1);
  570. X    alarm(0);
  571. X    if (timedout)
  572. X        return(TIMEOUT);
  573. X    if (DEBUG)
  574. X        fprintf(LOGFP, "DEBUG: readbyte %02xh\n", c & 0xff);
  575. X    return(c & 0xff);
  576. X}
  577. X
  578. Xint
  579. Xforce_it()
  580. X{
  581. X    timedout++;
  582. X    return;
  583. X}
  584. X
  585. X
  586. X/* flush input stream */
  587. X
  588. Xflushin()
  589. X    {
  590. X/* No good way to do this without select */
  591. X/* Perhaps....but we waste 1 second with every call!
  592. X    while (readbyte(1) != TIMEOUT)
  593. X        ;
  594. X*/
  595. X    }
  596. X
  597. X/* 
  598. X get a buffer (length bufsize) from data stream -- timeout if "seconds" elapses.
  599. X Read bunches of characters to save system overhead;
  600. X Further process data while kernel is reading stream (calculating "checksum").
  601. X Try to nap long enough so kernel collects 100 characters or so until we wake up
  602. X unless TOOBUSY is set.
  603. X*/
  604. X
  605. X
  606. Xint
  607. Xreadbuf(bufsize, seconds, tmode, amode, recvsectcnt, checksum, bufctr)
  608. X
  609. Xint bufsize,    /* number of chars to be read */
  610. Xseconds,     /* timeout period for each read */
  611. Xtmode,         /* transmission mode: TRUE if text */
  612. Xamode,         /* transmission mode: TRUE if apple macintosh */
  613. X*checksum,     /* pointer to checksum value */
  614. X*bufctr;    /* length of actual data string in buffer */
  615. Xlong recvsectcnt;    /* running sector count (128 byte sectors) */
  616. X
  617. X{
  618. X    int force_it();
  619. X    int numread;        /* number of chars read */
  620. X    int left;        /* number of chars left to read */
  621. X    int recfin = 0;        /* flag that EOF read */
  622. X    char inbuf[BBUFSIZ];    /* buffer for incoming packet */
  623. X    register unsigned char c;    /* character being processed */
  624. X    register unsigned short chksm;    /* working copy of checksum */
  625. X    register int bfctr;    /* working copy of bufctr */
  626. X    int j;            /* loop index */
  627. X    char *sectdisp();
  628. X
  629. X    signal(SIGALRM, force_it);
  630. X    chksm = 0;
  631. X    bfctr = 0;
  632. X
  633. X    for (left = bufsize; left > 0;) {
  634. X
  635. X        /* read however many chars are waiting */
  636. X        timedout = 0;
  637. X        alarm(seconds);
  638. X        numread = read(0, inbuf, left);
  639. X        alarm(0);
  640. X        if (timedout)
  641. X            return(TIMEOUT);
  642. X        left -= numread;
  643. X
  644. X        if (DEBUG)
  645. X            fprintf(LOGFP, "DEBUG: readbuf--read %d characters\n", numread);
  646. X
  647. X        /* now process part of packet we just read */
  648. X
  649. X        for (j =  0; j < numread; j++) 
  650. X            {  
  651. X                buff[bfctr] = c = inbuf[j] & 0xff;
  652. X                fileread++;
  653. X
  654. X                if (CRCMODE)  /* CRC */
  655. X                    chksm = (chksm<<B) ^ crctab[(chksm>>(W-B)) ^ c];
  656. X
  657. X                else        /* checksum */
  658. X                           chksm = ((chksm+c) & 0xff);
  659. X
  660. X                if (CHECKLENGTH && fileread > filelength)    /* past EOF ? */
  661. X                    continue;
  662. X
  663. X                if (tmode)         /* text mode processing */
  664. X                    {
  665. X                    buff[bfctr] &= 0x7f;    /* nuke bit 8 */
  666. X                    if (c == CR || c == 0)    /* skip CRs and nulls */
  667. X                        continue;
  668. X                    else if (c == CTRLZ)    /* CP/M EOF char */
  669. X                        {  
  670. X                        recfin = TRUE;
  671. X                               continue;
  672. X                               }
  673. X                           else if (!recfin)    /* don't increment if past EOF */
  674. X                        bfctr++;
  675. X                    }
  676. X                else if (amode)     /* Apple macintosh text mode processing */
  677. X                    {
  678. X                    buff[bfctr] &= 0x7f;    /* nuke bit 8 */
  679. X                    if (c == 0)        /* skip nulls */
  680. X                        continue;
  681. X                    else if (c == CR)    /* translate CR to LF */
  682. X                        buff[bfctr] = LF;
  683. X                    else if (c == CTRLZ)    /* CP/M EOF char */
  684. X                        {  
  685. X                        recfin = TRUE;
  686. X                               continue;
  687. X                               }
  688. X                           if (!recfin)    /* don't increment if past EOF */
  689. X                        bfctr++;
  690. X                    }
  691. X                else            /* binary */
  692. X                    bfctr++;
  693. X
  694. X                 }    
  695. X
  696. X        /* go to sleep to save uneeded system calls while kernel
  697. X           is reading data from serial line, fudge constant from 10 to
  698. X           9 to avoid sleeping too long
  699. X        */
  700. X        if (left && !TOOBUSY)
  701. X            sleep ((left<SLEEPNUM ? left:SLEEPNUM) * 9/ttyspeed);
  702. X    }
  703. X
  704. X    if (CHECKLENGTH && fileread >= filelength)
  705. X        logitarg("File end from YMODEM length found in sector %s\n",
  706. X          sectdisp(recvsectcnt,bufsize,1));
  707. X    *checksum = chksm;
  708. X    *bufctr = bfctr;
  709. X    return(0);
  710. X}
  711. X
  712. X/* send a byte to data stream */
  713. X
  714. Xsendbyte(data)
  715. Xchar data;
  716. X    {
  717. X    if (DEBUG)
  718. X        fprintf(LOGFP, "DEBUG: sendbyte %02xh\n", data & 0xff);
  719. X
  720. X    if (write(1, &data, 1) != 1)      /* write the byte (assume it goes NOW; no flushing needed) */
  721. X        error ("Write error on stream", TRUE);
  722. X    return;
  723. X    }
  724. X
  725. X/* send a buffer to data stream */
  726. X
  727. Xwritebuf(buffer, nbytes)
  728. Xchar *buffer;
  729. Xint  nbytes;
  730. X    {
  731. X    if (DEBUG)
  732. X        fprintf(LOGFP, "DEBUG: writebuf (%d bytes)\n", nbytes);
  733. X
  734. X    if (write(1, buffer, nbytes) != nbytes)        /* write the buffer (assume no TIOCFLUSH needed) */
  735. X        error ("Write error on stream", TRUE);
  736. X    return;
  737. X    }
  738. X
  739. X/* set and restore tty modes for XMODEM transfers */
  740. X
  741. Xstruct termio ttys;
  742. Xstruct stat statbuf;        /* for terminal message on/off control */
  743. X
  744. Xint wason;            /* holds status of tty read write/modes */
  745. Xchar *tty;            /* current tty name */
  746. X
  747. X
  748. Xsetmodes()
  749. X    {
  750. X    char *ttyname();
  751. X    struct termio ttysnew;
  752. X
  753. X    extern onintr();
  754. X
  755. X    sleep(2);            /* let the output appear */
  756. X    if (ioctl(0,TCGETA,&ttys)<0)  /* get tty params */
  757. X        error("Can't get TTY Parameters", TRUE);
  758. X
  759. X    tty = ttyname(0);  /* identify current tty */
  760. X    
  761. X    if (ioctl(0,TCGETA,&ttysnew)<0)  /* get tty params */
  762. X        error("Can't get TTY Parameters", TRUE);
  763. X    ttysnew.c_cc[4] = 1;        /* VMIN */
  764. X    ttysnew.c_cc[5] = 0;        /* VTIME */
  765. X    ttysnew.c_iflag = 0;
  766. X    ttysnew.c_oflag = 0;
  767. X    ttysnew.c_lflag = 0;
  768. X    ttysnew.c_cflag &= ~CSIZE;
  769. X    ttysnew.c_cflag |= CS8;
  770. X    ttysnew.c_cflag &= ~PARENB;
  771. X    if (ioctl(0,TCSETA,&ttysnew)<0)  /* set new paramters */
  772. X        error("Can't set new TTY Parameters", TRUE);
  773. X
  774. X    if (stat(tty, &statbuf) < 0)  /* get tty status */ 
  775. X        error("Can't get your TTY Status", TRUE);
  776. X
  777. X    if (statbuf.st_mode & 022)    /* Need to turn messages off */
  778. X        if (chmod(tty, (int)statbuf.st_mode & ~022) < 0)
  779. X            error("Can't change  TTY mode", TRUE);
  780. X        else 
  781. X            wason = TRUE;
  782. X    else 
  783. X        wason = FALSE;
  784. X
  785. X    /* set up signal catcher to restore tty state if we are KILLed */
  786. X
  787. X    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  788. X        signal(SIGTERM, onintr);
  789. X    }
  790. X
  791. X/* restore normal tty modes */
  792. X
  793. Xrestoremodes(errcall)
  794. Xint errcall;
  795. X    {
  796. X    if (wason)
  797. X        if (chmod(tty, (int)statbuf.st_mode | 022) < 0)
  798. X            error("Can't change TTY mode", FALSE);
  799. X    if (ioctl(0,TCSETA,&ttys) < 0)
  800. X        { if (!errcall)
  801. X           error("RESET - Can't restore normal TTY Params", FALSE);
  802. X        else
  803. X             printf("RESET - Can't restore normal TTY Params\n");
  804. X        }
  805. X    if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
  806. X        signal(SIGTERM, SIG_DFL);
  807. X    return;
  808. X    }
  809. X
  810. X
  811. X
  812. X
  813. X/* signal catcher */
  814. Xonintr()
  815. X    {
  816. X    error("Kill signal; bailing out", TRUE);
  817. X    }
  818. X
  819. X/* create string with a timestamp for log file */
  820. X
  821. Xchar *stamptime()
  822. X{
  823. X    char *asctime();        /* stuff to get timestamp */
  824. X    struct tm *localtime(), *tp;
  825. X    long now;
  826. X
  827. X    time(&now);
  828. X    tp = localtime(&now);
  829. X    return(asctime(tp));
  830. X}
  831. X
  832. X
  833. X
  834. X/* get tty speed for time estimates */
  835. X
  836. Xgetspeed()
  837. X    {
  838. X    static int speedtbl[] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
  839. X    1200, 1800, 2400, 4800, 9600, 19200, 0};
  840. X    struct termio ttystemp;
  841. X
  842. X    if (ioctl(0,TCGETA,&ttystemp) < 0)    /* get tty structure */
  843. X        error("Can't get TTY parameters", FALSE);
  844. X    if ((ttystemp.c_cflag & 017) >= 0 && (ttystemp.c_cflag & 017) <= 14)
  845. X        {
  846. X        ttyspeed = speedtbl[ttystemp.c_cflag & 017];
  847. X        logitarg ("Line speed = %d bits per second\n", ttyspeed);
  848. X        }
  849. X    else
  850. X        {
  851. X        ttyspeed = 1200;
  852. X        logit ("Can't determine line speed; assuming 1200 bps\n");
  853. X        }
  854. X    }
  855. !Funky!Stuff!
  856. exit
  857.  
  858.