# 2.11BSD#431 - /usr/src/usr.bin/uucp/fio.c

##### Functions

    frddata           X
    frdmsg            X
    fturnoff          X
    fturnon           X
    fwrdata           X
    fwrmsg            X

##### Macros

    FIBUFSIZ          X
    FOBUFSIZ          X
    MAXMSGLEN         X
    MAXRETRIES        X
    TC                X
    TCGETA            X
    TCSETA            X
    termio            X

       1: #ifndef lint
       2: static char sccsid[] = "@(#)fio.c	5.3 (Berkeley) 10/9/85";
       3: #endif
       4:
       5: /*
       6:  * flow control protocol.
       7:  *
       8:  * This protocol relies on flow control of the data stream.
       9:  * It is meant for working over links that can (almost) be
      10:  * guaranteed to be errorfree, specifically X.25/PAD links.
      11:  * A sumcheck is carried out over a whole file only. If a
      12:  * transport fails the receiver can request retransmission(s).
      13:  * This protocol uses a 7-bit datapath only, so it can be
      14:  * used on links that are not 8-bit transparent.
      15:  *
      16:  * When using this protocol with an X.25 PAD:
      17:  * Although this protocol uses no control chars except CR,
      18:  * control chars NULL and ^P are used before this protocol
      19:  * is started; since ^P is the default char for accessing
      20:  * PAD X.28 command mode, be sure to disable that access
      21:  * (PAD par 1). Also make sure both flow control pars
      22:  * (5 and 12) are set. The CR used in this proto is meant
      23:  * to trigger packet transmission, hence par 3 should be
      24:  * set to 2; a good value for the Idle Timer (par 4) is 10.
      25:  * All other pars should be set to 0.
      26:  *
      27:  * Normally a calling site will take care of setting the
      28:  * local PAD pars via an X.28 command and those of the remote
      29:  * PAD via an X.29 command, unless the remote site has a
      30:  * special channel assigned for this protocol with the proper
      31:  * par settings.
      32:  *
      33:  * Additional comments for hosts with direct X.25 access:
      34:  * - the global variable IsTcpIp, when set, excludes the ioctl's,
      35:  *   so the same binary can run on X.25 and non-X.25 hosts;
      36:  * - reads are done in small chunks, which can be smaller than
      37:  *   the packet size; your X.25 driver must support that.
      38:  *
      39:  *
      40:  * Author:
      41:  *	Piet Beertema, CWI, Amsterdam, Sep 1984
      42:  * Modified for X.25 hosts:
      43:  *	Robert Elz, Melbourne Univ, Mar 1985
      44:  */
      45:
      46: #include "uucp.h"
      47: #include <signal.h>
      48: #ifdef USG
      49: #include <termio.h>
      50: #else !USG
      51: #include <sgtty.h>
      52: #endif !USG
      53: #include <setjmp.h>
      54:
      55: #define FIBUFSIZ    256 /* for X.25 interfaces: set equal to packet size,
      56: 				 * but see comment above
      57: 				 */
      58:
      59: #define FOBUFSIZ    256 /* for X.25 interfaces: set equal to packet size;
      60: 				 * otherwise make as large as feasible to reduce
      61: 				 * number of write system calls
      62: 				 */
      63:
      64: #ifndef MAXMSGLEN
      65: #define MAXMSGLEN   BUFSIZ
      66: #endif MAXMSGLEN
      67:
      68: static int fchksum;
      69: static jmp_buf Ffailbuf;
      70:
      71: static
      72: falarm()
      73: {
      74:     signal(SIGALRM, falarm);
      75:     longjmp(Ffailbuf, 1);
      76: }
      77:
      78: static int (*fsig)();
      79:
      80: #ifndef USG
      81: #define TCGETA  TIOCGETP
      82: #define TCSETA  TIOCSETP
      83: #define termio  sgttyb
      84: #endif USG
      85:
      86: fturnon()
      87: {
      88:     int ret;
      89:     struct termio ttbuf;
      90:
      91:     if (!IsTcpIp) {
      92:         ioctl(Ifn, TCGETA, &ttbuf);
      93: #ifdef USG
      94:         ttbuf.c_iflag = IXOFF|IXON|ISTRIP;
      95:         ttbuf.c_cc[VMIN] = FIBUFSIZ > 64 ? 64 : FIBUFSIZ;
      96:         ttbuf.c_cc[VTIME] = 5;
      97: #else !USG
      98:         ttbuf.sg_flags = ANYP|CBREAK|TANDEM;
      99: #endif USG
     100:         ret = ioctl(Ifn, TCSETA, &ttbuf);
     101:         ASSERT(ret >= 0, "STTY FAILED", "", ret);
     102:     }
     103:     fsig = signal(SIGALRM, falarm);
     104:     /* give the other side time to perform its ioctl;
     105: 	 * otherwise it may flush out the first data this
     106: 	 * side is about to send.
     107: 	 */
     108:     sleep(2);
     109:     return SUCCESS;
     110: }
     111:
     112: fturnoff()
     113: {
     114:     (void) signal(SIGALRM, fsig);
     115:     return SUCCESS;
     116: }
     117:
     118: fwrmsg(type, str, fn)
     119: register char *str;
     120: int fn;
     121: char type;
     122: {
     123:     register char *s;
     124:     char bufr[MAXMSGLEN];
     125:
     126:     s = bufr;
     127:     *s++ = type;
     128:     while (*str)
     129:         *s++ = *str++;
     130:     if (*(s-1) == '\n')
     131:         s--;
     132:     *s++ = '\r';
     133:     *s = 0;
     134:     (void) write(fn, bufr, s - bufr);
     135:     return SUCCESS;
     136: }
     137:
     138: frdmsg(str, fn)
     139: register char *str;
     140: register int fn;
     141: {
     142:     register char *smax;
     143:
     144:     if (setjmp(Ffailbuf))
     145:         return FAIL;
     146:     smax = str + MAXMSGLEN - 1;
     147:     (void) alarm(2*MAXMSGTIME);
     148:     for (;;) {
     149:         if (read(fn, str, 1) <= 0)
     150:             goto msgerr;
     151:         *str &= 0177;
     152:         if (*str == '\r')
     153:             break;
     154:         if (*str < ' ') {
     155:             continue;
     156:         }
     157:         if (str++ >= smax)
     158:             goto msgerr;
     159:     }
     160:     *str = '\0';
     161:     (void) alarm(0);
     162:     return SUCCESS;
     163: msgerr:
     164:     (void) alarm(0);
     165:     return FAIL;
     166: }
     167:
     168: fwrdata(fp1, fn)
     169: FILE *fp1;
     170: int fn;
     171: {
     172:     register int alen, ret;
     173:     register char *obp;
     174:     char ack, ibuf[MAXMSGLEN];
     175:     int flen, mil, retries = 0;
     176:     long abytes, fbytes;
     177:     struct timeb t1, t2;
     178:
     179:     ret = FAIL;
     180: retry:
     181:     fchksum = 0xffff;
     182:     abytes = fbytes = 0L;
     183:     ack = '\0';
     184: #ifdef USG
     185:     time(&t1.time);
     186:     t1.millitm = 0;
     187: #else !USG
     188:     ftime(&t1);
     189: #endif !USG
     190:     do {
     191:         alen = fwrblk(fn, fp1, &flen);
     192:         fbytes += flen;
     193:         if (alen <= 0) {
     194:             abytes -= alen;
     195:             goto acct;
     196:         }
     197:         abytes += alen;
     198:     } while (!feof(fp1) && !ferror(fp1));
     199:     DEBUG(8, "\nchecksum: %04x\n", fchksum);
     200:     if (frdmsg(ibuf, fn) != FAIL) {
     201:         if ((ack = ibuf[0]) == 'G')
     202:             ret = SUCCESS;
     203:         DEBUG(4, "ack - '%c'\n", ack);
     204:     }
     205: acct:
     206: #ifdef USG
     207:     time(&t2.time);
     208:     t2.millitm = 0;
     209: #else !USG
     210:     ftime(&t2);
     211: #endif !USG
     212:     Now = t2;
     213:     t2.time -= t1.time;
     214:     mil = t2.millitm - t1.millitm;
     215:     if (mil < 0) {
     216:         --t2.time;
     217:         mil += 1000;
     218:     }
     219:     sprintf(ibuf, "sent data %ld bytes %ld.%02d secs",
     220:         fbytes, (long)t2.time, mil / 10);
     221:     sysacct(abytes, t2.time);
     222:     if (retries > 0)
     223:         sprintf(&ibuf[strlen(ibuf)], ", %d retries", retries);
     224:     DEBUG(1, "%s\n", ibuf);
     225:     syslog(ibuf);
     226:     if (ack == 'R') {
     227:         DEBUG(4, "RETRY:\n", 0);
     228:         fseek(fp1, 0L, 0);
     229:         retries++;
     230:         goto retry;
     231:     }
     232: #ifdef SYSACCT
     233:     if (ret == FAIL)
     234:         sysaccf(NULL);      /* force accounting */
     235: #endif SYSACCT
     236:     return ret;
     237: }
     238:
     239: /* max. attempts to retransmit a file: */
     240: #define MAXRETRIES  (fbytes < 10000L ? 2 : 1)
     241:
     242: frddata(fn, fp2)
     243: register int fn;
     244: register FILE *fp2;
     245: {
     246:     register int flen;
     247:     register char eof;
     248:     char ibuf[FIBUFSIZ];
     249:     int ret, mil, retries = 0;
     250:     long alen, abytes, fbytes;
     251:     struct timeb t1, t2;
     252:
     253:     ret = FAIL;
     254: retry:
     255:     fchksum = 0xffff;
     256:     abytes = fbytes = 0L;
     257: #ifdef USG
     258:     time(&t1.time);
     259:     t1.millitm = 0;
     260: #else !USG
     261:     ftime(&t1);
     262: #endif !USG
     263:     do {
     264:         flen = frdblk(ibuf, fn, &alen);
     265:         abytes += alen;
     266:         if (flen < 0)
     267:             goto acct;
     268:         if (eof = flen > FIBUFSIZ)
     269:             flen -= FIBUFSIZ + 1;
     270:         fbytes += flen;
     271:         if (fwrite(ibuf, sizeof (char), flen, fp2) != flen)
     272:             goto acct;
     273:     } while (!eof);
     274:     ret = SUCCESS;
     275: acct:
     276: #ifdef USG
     277:     time(&t2.time);
     278:     t2.millitm = 0;
     279: #else !USG
     280:     ftime(&t2);
     281: #endif !USG
     282:     Now = t2;
     283:     t2.time -= t1.time;
     284:     mil = t2.millitm - t1.millitm;
     285:     if (mil < 0) {
     286:         --t2.time;
     287:         mil += 1000;
     288:     }
     289:     sprintf(ibuf, "received data %ld bytes %ld.%02d secs",
     290:         fbytes, (long)t2.time, mil/10);
     291:     if (retries > 0)
     292:         sprintf(&ibuf[strlen(ibuf)]," %d retries", retries);
     293:     sysacct(abytes, t2.time);
     294:     DEBUG(1, "%s\n", ibuf);
     295:     syslog(ibuf);
     296:     if (ret == FAIL) {
     297:         if (retries++ < MAXRETRIES) {
     298:             DEBUG(8, "send ack: 'R'\n", 0);
     299:             fwrmsg('R', "", fn);
     300:             fseek(fp2, 0L, 0);
     301:             DEBUG(4, "RETRY:\n", 0);
     302:             goto retry;
     303:         }
     304:         DEBUG(8, "send ack: 'Q'\n", 0);
     305:         fwrmsg('Q', "", fn);
     306: #ifdef SYSACCT
     307:         sysaccf(NULL);      /* force accounting */
     308: #endif SYSACCT
     309:     }
     310:     else {
     311:         DEBUG(8, "send ack: 'G'\n", 0);
     312:         fwrmsg('G', "", fn);
     313:     }
     314:     return ret;
     315: }
     316:
     317: static
     318: frdbuf(blk, len, fn)
     319: register char *blk;
     320: register int len;
     321: register int fn;
     322: {
     323:     static int ret = FIBUFSIZ / 2;
     324:
     325:     if (setjmp(Ffailbuf))
     326:         return FAIL;
     327:     (void) alarm(MAXMSGTIME);
     328:     ret = read(fn, blk, len);
     329:     alarm(0);
     330:     return ret <= 0 ? FAIL : ret;
     331: }
     332:
     333: #if !defined(BSD4_2) && !defined(USG)
     334: /* call ultouch every TC calls to either frdblk or fwrblk  */
     335: #define TC  20
     336: static int tc = TC;
     337: #endif !defined(BSD4_2) && !defined(USG)
     338:
     339: /* Byte conversion:
     340:  *
     341:  *   from	 pre	   to
     342:  * 000-037	 172	 100-137
     343:  * 040-171		 040-171
     344:  * 172-177	 173	 072-077
     345:  * 200-237	 174	 100-137
     346:  * 240-371	 175	 040-171
     347:  * 372-377	 176	 072-077
     348:  */
     349:
     350: static
     351: fwrblk(fn, fp, lenp)
     352: int fn;
     353: register FILE *fp;
     354: int *lenp;
     355: {
     356:     register char *op;
     357:     register int c, sum, nl, len;
     358:     char obuf[FOBUFSIZ + 8];
     359:     int ret;
     360:
     361: #if !defined(BSD4_2) && !defined(USG)
     362:     /* call ultouch occasionally */
     363:     if (--tc < 0) {
     364:         tc = TC;
     365:         ultouch();
     366:     }
     367: #endif !defined(BSD4_2) && !defined(USG)
     368:     op = obuf;
     369:     nl = 0;
     370:     len = 0;
     371:     sum = fchksum;
     372:     while ((c = getc(fp)) != EOF) {
     373:         len++;
     374:         if (sum & 0x8000) {
     375:             sum <<= 1;
     376:             sum++;
     377:         } else
     378:             sum <<= 1;
     379:         sum += c;
     380:         sum &= 0xffff;
     381:         if (c & 0200) {
     382:             c &= 0177;
     383:             if (c < 040) {
     384:                 *op++ = '\174';
     385:                 *op++ = c + 0100;
     386:             } else
     387:             if (c <= 0171) {
     388:                 *op++ = '\175';
     389:                 *op++ = c;
     390:             }
     391:             else {
     392:                 *op++ = '\176';
     393:                 *op++ = c - 0100;
     394:             }
     395:             nl += 2;
     396:         } else {
     397:             if (c < 040) {
     398:                 *op++ = '\172';
     399:                 *op++ = c + 0100;
     400:                 nl += 2;
     401:             } else
     402:             if (c <= 0171) {
     403:                 *op++ = c;
     404:                 nl++;
     405:             } else {
     406:                 *op++ = '\173';
     407:                 *op++ = c - 0100;
     408:                 nl += 2;
     409:             }
     410:         }
     411:         if (nl >= FOBUFSIZ - 1) {
     412:             /*
     413: 			 * peek at next char, see if it will fit
     414: 			 */
     415:             c = getc(fp);
     416:             if (c == EOF)
     417:                 break;
     418:             (void) ungetc(c, fp);
     419:             if (nl >= FOBUFSIZ || c < 040 || c > 0171)
     420:                 goto writeit;
     421:         }
     422:     }
     423:     /*
     424: 	 * At EOF - append checksum, there is space for it...
     425: 	 */
     426:     sprintf(op, "\176\176%04x\r", sum);
     427:     nl += strlen(op);
     428: writeit:
     429:     *lenp = len;
     430:     fchksum = sum;
     431:     DEBUG(8, "%d/", len);
     432:     DEBUG(8, "%d,", nl);
     433:     ret = write(fn, obuf, nl);
     434:     return ret == nl ? nl : ret < 0 ? 0 : -ret;
     435: }
     436:
     437: static
     438: frdblk(ip, fn, rlen)
     439: register char *ip;
     440: int fn;
     441: long *rlen;
     442: {
     443:     register char *op, c;
     444:     register int sum, len, nl;
     445:     char buf[5], *erbp = ip;
     446:     int i;
     447:     static char special = 0;
     448:
     449: #if !defined(BSD4_2) && !defined(USG)
     450:     /* call ultouch occasionally */
     451:     if (--tc < 0) {
     452:         tc = TC;
     453:         ultouch();
     454:     }
     455: #endif !defined(BSD4_2) && !defined(USG)
     456:     if ((len = frdbuf(ip, FIBUFSIZ, fn)) == FAIL) {
     457:         *rlen = 0;
     458:         goto dcorr;
     459:     }
     460:     *rlen = len;
     461:     DEBUG(8, "%d/", len);
     462:     op = ip;
     463:     nl = 0;
     464:     sum = fchksum;
     465:     do {
     466:         if ((*ip &= 0177) >= '\172') {
     467:             if (special) {
     468:                 DEBUG(8, "%d", nl);
     469:                 special = 0;
     470:                 op = buf;
     471:                 if (*ip++ != '\176' || (i = --len) > 5)
     472:                     goto dcorr;
     473:                 while (i--)
     474:                     *op++ = *ip++ & 0177;
     475:                 while (len < 5) {
     476:                     i = frdbuf(&buf[len], 5 - len, fn);
     477:                     if (i == FAIL) {
     478:                         len = FAIL;
     479:                         goto dcorr;
     480:                     }
     481:                     DEBUG(8, ",%d", i);
     482:                     len += i;
     483:                     *rlen += i;
     484:                     while (i--)
     485:                         *op++ &= 0177;
     486:                 }
     487:                 if (buf[4] != '\r')
     488:                     goto dcorr;
     489:                 sscanf(buf, "%4x", &fchksum);
     490:                 DEBUG(8, "\nchecksum: %04x\n", sum);
     491:                 if (fchksum == sum)
     492:                     return FIBUFSIZ + 1 + nl;
     493:                 else {
     494:                     DEBUG(8, "\n", 0);
     495:                     DEBUG(4, "Bad checksum\n", 0);
     496:                     return FAIL;
     497:                 }
     498:             }
     499:             special = *ip++;
     500:         } else {
     501:             if (*ip < '\040') {
     502:                 /* error: shouldn't get control chars */
     503:                 goto dcorr;
     504:             }
     505:             switch (special) {
     506:             case 0:
     507:                 c = *ip++;
     508:                 break;
     509:             case '\172':
     510:                 c = *ip++ - 0100;
     511:                 break;
     512:             case '\173':
     513:                 c = *ip++ + 0100;
     514:                 break;
     515:             case '\174':
     516:                 c = *ip++ + 0100;
     517:                 break;
     518:             case '\175':
     519:                 c = *ip++ + 0200;
     520:                 break;
     521:             case '\176':
     522:                 c = *ip++ + 0300;
     523:                 break;
     524:             }
     525:             *op++ = c;
     526:             if (sum & 0x8000) {
     527:                 sum <<= 1;
     528:                 sum++;
     529:             } else
     530:                 sum <<= 1;
     531:             sum += c & 0377;
     532:             sum &= 0xffff;
     533:             special = 0;
     534:             nl++;
     535:         }
     536:     } while (--len);
     537:     fchksum = sum;
     538:     DEBUG(8, "%d,", nl);
     539:     return nl;
     540: dcorr:
     541:     DEBUG(8, "\n", 0);
     542:     DEBUG(4, "Data corrupted\n", 0);
     543:     while (len != FAIL) {
     544:         if ((len = frdbuf(erbp, FIBUFSIZ, fn)) != FAIL)
     545:             *rlen += len;
     546:     }
     547:     return FAIL;
     548: }

#### Defined functions

falarm defined in line 71; used 2 times

- in line 74, 103

frdblk defined in line 437; used 1 times

- in line 264

frdbuf defined in line 317; used 3 times

- in line 456, 476, 544

frddata defined in line 242; used 2 times

- in /usr/src/usr.bin/uucp/cntrl.c line 34, 43

frdmsg defined in line 138; used 3 times

- in line 200
- in /usr/src/usr.bin/uucp/cntrl.c line 34, 43

fturnoff defined in line 112; used 2 times

- in /usr/src/usr.bin/uucp/cntrl.c line 33, 43

fturnon defined in line 86; used 2 times

- in /usr/src/usr.bin/uucp/cntrl.c line 33, 43

fwrblk defined in line 350; used 1 times

- in line 191

fwrdata defined in line 168; used 2 times

- in /usr/src/usr.bin/uucp/cntrl.c line 35, 43

fwrmsg defined in line 118; used 5 times

- in line 299, 305, 312
- in /usr/src/usr.bin/uucp/cntrl.c line 35, 43

#### Defined variables

Ffailbuf defined in line 69; used 3 times

- in line 75, 144, 325

fchksum defined in line 68; used 9 times

- in line 181, 199, 255, 371, 430, 464, 489-491(2), 537

sccsid defined in line 2; never used
tc defined in line 336; used 4 times

- in line 363-364(2), 451-452(2)

#### Defined macros

FIBUFSIZ defined in line 55; used 9 times

- in line 95(2), 248, 268-269(2), 323, 456, 492, 544

FOBUFSIZ defined in line 59; used 3 times

- in line 358, 411, 419

MAXMSGLEN defined in line 65; used 4 times

- in line 64, 124, 146, 174

MAXRETRIES defined in line 240; used 1 times

- in line 297

TC defined in line 335; used 3 times

- in line 336, 364, 452

TCGETA defined in line 81; used 1 times

- in line 92

TCSETA defined in line 82; used 1 times

- in line 100

termio defined in line 83; never used

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1132 |