# 2.11BSD#431 - /usr/src/new/kermit5.188/ckcfns.c

##### Functions

    adjpkl            X
    cwd               X
    decode            X
    encode            X
    encstr            X
    getpkt            X
    gnfile            X
    kgetf             X
    kgetm             X
    lslook            X
    pktinit           X
    putfil            X
    putsrv            X
    puttrm            X
    rcvfil            X
    remset            X
    reof              X
    reot              X
    resetc            X
    rinit             X
    rpar              X
    sdata             X
    seof              X
    seot              X
    sfile             X
    sinit             X
    sipkt             X
    sndhlp            X
    sndspace          X
    spar              X
    sxeof             X
    syscmd            X
    szeof             X
    tinit             X
    xsinit            X
    zdstuff           X

##### Variables

    VOID              X
    cmargbuf          X
    cmargp            X
    dada              X
    encbuf            X
    fnsv              X
    memstr            X
    myinit            X
    sndsrc            X

##### Macros

    ENCBUFL           X
    PKTNL             X
    XNAMLEN           X

       1: char *fnsv = "C-Kermit functions, 5A(079) 23 Nov 92";
       2:
       3: /*  C K C F N S  --  System-independent Kermit protocol support functions.  */
       4:
       5: /*  ...Part 1 (others moved to ckcfn2,3 to make this module small enough) */
       6:
       7: /*
       8:   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
       9:   Columbia University Center for Computing Activities.
      10:   First released January 1985.
      11:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
      12:   York.  Permission is granted to any individual or institution to use this
      13:   software as long as it is not sold for profit.  This copyright notice must be
      14:   retained.  This software may not be included in commercial products without
      15:   written permission of Columbia University.
      16: */
      17: /*
      18:  System-dependent primitives defined in:
      19:
      20:    ck?tio.c -- terminal i/o
      21:    cx?fio.c -- file i/o, directory structure
      22: */
      23: #include "ckcsym.h"         /* Once needed this for Mac... */
      24: #include "ckcasc.h"         /* ASCII symbols */
      25: #include "ckcdeb.h"         /* Debug formats, typedefs, etc. */
      26: #include "ckcker.h"         /* Symbol definitions for Kermit */
      27: #include "ckcxla.h"         /* Character set symbols */
      28:
      29: /* Externals from ckcmai.c */
      30: extern int spsiz, spmax, rpsiz, timint, srvtim, rtimo, npad, ebq, ebqflg,
      31:  rpt, rptq, rptflg, capas, keep, fncact, pkttim, autopar, spsizr;
      32: extern int pktnum, bctr, bctu, bctl, fmask, clfils, sbufnum,
      33:  size, osize, spktl, nfils, warn, timef, spsizf, sndtyp, success;
      34: extern int parity, turn, network, what, fsecs,
      35:  delay, displa, xflg, mypadn;
      36: extern long filcnt, ffc, flci, flco, tlci, tlco, tfc, fsize, speed;
      37: extern int fblksiz, frecl, frecfm, forg, fcctrl;
      38: extern int spackets, rpackets, timeouts, retrans, crunched, wmax;
      39: extern int hcflg, binary, savmod, fncnv, local, server, cxseen, czseen;
      40: extern int nakstate, discard;
      41: extern int rq, rqf, sq, wslots, wslotn, wslotr, winlo, urpsiz, rln;
      42: extern int atcapr, atcapb, atcapu;
      43: extern int lpcapr, lpcapb, lpcapu;
      44: extern int swcapr, swcapb, swcapu;
      45: extern int lscapr, lscapb, lscapu;
      46: extern int bsave, bsavef;
      47: extern int sseqtbl[];
      48: extern int numerrs;
      49: extern long rptn;
      50: extern int maxtry;
      51:
      52: #ifndef NOCSETS
      53: extern int tcharset, fcharset;
      54: extern int ntcsets;
      55: extern struct csinfo tcsinfo[], fcsinfo[];
      56: #endif /* NOCSETS */
      57:
      58: extern int
      59:   atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko,
      60:   attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;
      61:
      62: extern int bigsbsiz, bigrbsiz;
      63:
      64: #ifdef DYNAMIC
      65:   extern CHAR *srvcmd;
      66: #else
      67:   extern CHAR srvcmd[];
      68: #endif /* DYNAMIC */
      69: extern CHAR padch, mypadc, eol, seol, ctlq, myctlq, sstate;
      70: extern CHAR *recpkt, *data, padbuf[], stchr, mystch;
      71: extern CHAR *srvptr;
      72: extern CHAR *rdatap;
      73: extern char *cmarg, *cmarg2, *hlptxt, **cmlist, filnam[], fspec[];
      74:
      75: _PROTOTYP( CHAR *rpar, (void) );
      76: _PROTOTYP( int lslook, (unsigned int b) );  /* Locking Shift Lookahead */
      77: _PROTOTYP( int szeof, (CHAR *s) );
      78:
      79: /* International character sets */
      80:
      81: #ifndef NOCSETS
      82: /* Pointers to translation functions */
      83: #ifdef CK_ANSIC
      84: extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
      85: extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
      86: #else
      87: extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
      88: extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
      89: #endif /* CK_ANSIC */
      90: _PROTOTYP( CHAR (*rx), (CHAR) );    /* Input translation function */
      91: _PROTOTYP( CHAR (*sx), (CHAR) );    /* Output translation function */
      92: _PROTOTYP( CHAR ident, (CHAR) );    /* Identity translation function */
      93: #endif /* NOCSETS */
      94:
      95: /* Windowing things */
      96:
      97: extern int rseqtbl[];           /* Rec'd-packet sequence # table */
      98:
      99: /* (PWP) external def. of things used in buffered file input and output */
     100:
     101: #ifdef DYNAMIC
     102: extern char *zinbuffer, *zoutbuffer;
     103: #else
     104: extern char zinbuffer[], zoutbuffer[];
     105: #endif
     106: extern char *zinptr, *zoutptr;
     107: extern int zincnt, zoutcnt;
     108:
     109: /* Variables defined in this module, but shared by ckcfn3, to which */
     110: /* several functions have been moved... */
     111:
     112: int sndsrc;     /* Flag for where to get names of files to send: */
     113:                     /* -1: znext() function */
     114:                     /*  0: stdin */
     115:                     /* >0: list in cmlist */
     116:
     117: int  memstr;                /* Flag for input from memory string */
     118:
     119: #ifdef pdp11
     120: CHAR myinit[25];            /* Copy of my Send-Init data */
     121: #else
     122: CHAR myinit[100];           /* Copy of my Send-Init data */
     123: #endif /* pdp11 */
     124:
     125: /* Variables local to this module */
     126:
     127: static char *memptr;            /* Pointer for memory strings */
     128:
     129: #ifdef pdp11
     130: static char cmdstr[50];         /* System command string. */
     131: #else
     132: static char cmdstr[100];
     133: #endif /* pdp11 */
     134:
     135: static int drain;           /* For draining stacked-up ACKs. */
     136:
     137: static int first;           /* Flag for first char from input */
     138: static CHAR t,              /* Current character */
     139:     next;               /* Next character */
     140:
     141: static int lsstate = 0;         /* Locking shift state */
     142: static int lsquote = 0;         /* Locking shift quote */
     143:
     144: #ifdef datageneral
     145: extern int quiet;
     146: #endif
     147:
     148: /*  E N C S T R  --  Encode a string from memory. */
     149:
     150: /*
     151:   Call this instead of getpkt() if source is a string, rather than a file.
     152:   Note: Character set translation is never done in this case.
     153: */
     154:
     155: #ifdef pdp11
     156: #define ENCBUFL 100
     157: #else
     158: #define ENCBUFL 200
     159: #endif /* pdp11 */
     160: CHAR encbuf[ENCBUFL];
     161:
     162: int
     163: encstr(s) CHAR* s; {
     164:     int m; char *p;
     165:     CHAR *dsave;
     166:
     167:     if ((m = (int)strlen((char *)s)) > ENCBUFL) {
     168:     debug(F111,"encstr string too long for buffer",s,ENCBUFL);
     169:     s[ENCBUFL] = '\0';
     170:     }
     171:     if (m > spsiz-bctl-3) {
     172:     debug(F111,"encstr string too long for packet",s,spsiz-bctl-3);
     173:     s[spsiz-bctl-3] = '\0';
     174:     }
     175:     m = memstr; p = memptr;     /* Save these. */
     176:
     177:     memptr = (char *)s;         /* Point to the string. */
     178:     memstr = 1;             /* Flag memory string as source. */
     179:     first = 1;              /* Initialize character lookahead. */
     180:     dsave = data;           /* Boy is this ugly... */
     181:     data = encbuf + 7;          /* Why + 7?  See spack()... */
     182: #ifdef COMMENT
     183:     getpkt(spsiz-bctl-3,0);     /* Fill a packet from the string. */
     184: #else
     185:     getpkt(spsiz,0);
     186: #endif /* COMMENT */
     187:     data = dsave;           /* (sorry...) */
     188:     memstr = m;             /* Restore memory string flag */
     189:     memptr = p;             /* and pointer */
     190:     first = 1;              /* Put this back as we found it. */
     191:     return(0);
     192: }
     193:
     194: #ifdef COMMENT
     195: /*
     196:   We don't use this routine any more -- the code has been incorporated
     197:   directly into getpkt() to reduce per-character function call overhead.
     198:   Also, watch out: it hasn't been updated since it was commented out a
     199:   long time ago.
     200: */
     201: /* E N C O D E - Kermit packet encoding procedure */
     202:
     203: VOID
     204: encode(a) CHAR a; {         /* The current character */
     205:     int a7;             /* Low order 7 bits of character */
     206:     int b8;             /* 8th bit of character */
     207:
     208: #ifndef NOCSETS
     209:     if (!binary && sx) a = (*sx)(a);    /* Translate. */
     210: #endif /* NOCSETS */
     211:
     212:     if (rptflg) {                   /* Repeat processing? */
     213:         if (a == next && (first == 0)) { /* Got a run... */
     214:         if (++rpt < 94)     /* Below max, just count */
     215:                 return;
     216:         else if (rpt == 94) {   /* Reached max, must dump */
     217:                 data[size++] = rptq;
     218:                 data[size++] = tochar(rpt);
     219:         rptn += rpt;        /* Count, for stats */
     220:                 rpt = 0;
     221:         }
     222:         } else if (rpt == 1) {      /* Run broken, only 2? */
     223:             rpt = 0;            /* Yes, reset repeat flag & count. */
     224:         encode(a);          /* Do the character twice. */
     225:         if (size <= maxsize) osize = size;
     226:         rpt = 0;
     227:         encode(a);
     228:         return;
     229:     } else if (rpt > 1) {       /* More than two */
     230:             data[size++] = rptq;    /* Insert the repeat prefix */
     231:             data[size++] = tochar(++rpt); /* and count. */
     232:         rptn += rpt;
     233:             rpt = 0;            /* Reset repeat counter. */
     234:         }
     235:     }
     236:     a7 = a & 0177;          /* Isolate ASCII part */
     237:     b8 = a & 0200;          /* and 8th (parity) bit. */
     238:
     239:     if (ebqflg && b8) {         /* Do 8th bit prefix if necessary. */
     240:         data[size++] = ebq;
     241:         a = a7;
     242:     }
     243:     if ((a7 < SP) || (a7==DEL)) {   /* Do control prefix if necessary */
     244:         data[size++] = myctlq;
     245:     a = ctl(a);
     246:     }
     247:     if (a7 == myctlq)           /* Prefix the control prefix */
     248:         data[size++] = myctlq;
     249:
     250:     if ((rptflg) && (a7 == rptq))   /* If it's the repeat prefix, */
     251:         data[size++] = myctlq;      /* quote it if doing repeat counts. */
     252:
     253:     if ((ebqflg) && (a7 == ebq))    /* Prefix the 8th bit prefix */
     254:         data[size++] = myctlq;      /* if doing 8th-bit prefixes */
     255:
     256:     data[size++] = a;           /* Finally, insert the character */
     257:     data[size] = '\0';          /* itself, and mark the end. */
     258: }
     259: #endif /* COMMENT */
     260:
     261: /*  Output functions passed to 'decode':  */
     262:
     263: int                /*  Put character in server command buffer  */
     264: #ifdef CK_ANSIC
     265: putsrv(char c)
     266: #else
     267: putsrv(c) register char c;
     268: #endif /* CK_ANSIC */
     269: /* putsrv */ {
     270:     *srvptr++ = c;
     271:     *srvptr = '\0';     /* Make sure buffer is null-terminated */
     272:     return(0);
     273: }
     274:
     275: int                 /*  Output character to console.  */
     276: #ifdef CK_ANSIC
     277: puttrm(char c)
     278: #else
     279: puttrm(c) register char c;
     280: #endif /* CK_ANSIC */
     281: /* puttrm */ {
     282:     conoc(c);
     283:     return(0);
     284: }
     285:
     286: int                 /*  Output char to file. */
     287: #ifdef CK_ANSIC
     288: putfil(char c)
     289: #else
     290: putfil(c) register char c;
     291: #endif /* CK_ANSIC */
     292: /* putfil */ {
     293:     if (zchout(ZOFILE, (char) (c & fmask)) < 0) {
     294:     czseen = 1;             /* If write error... */
     295:     debug(F101,"putfil zchout write error, setting czseen","",1);
     296:     return(-1);
     297:     }
     298:     return(0);
     299: }
     300:
     301: /* D E C O D E  --  Kermit packet decoding procedure */
     302:
     303: /*
     304:  Call with string to be decoded and an output function.
     305:  Returns 0 on success, -1 on failure (e.g. disk full).
     306:
     307:  This is the "inner loop" when receiving files, and must be coded as
     308:  efficiently as possible.  Note some potential problems:  if a packet
     309:  is badly formed, having a prefixed sequence ending prematurely, this
     310:  function, as coded, could read past the end of the packet.  This has
     311:  never happened, thus the additional (time-consuming) tests have not
     312:  been added.
     313: */
     314:
     315: static CHAR *xdbuf; /* Global version of decode()'s buffer pointer */
     316:                         /* for use by translation functions. */
     317:
     318: /* Function for pushing a character onto decode()'s input stream. */
     319:
     320: VOID
     321: #ifdef CK_ANSIC
     322: zdstuff(CHAR c)
     323: #else
     324: zdstuff(c) CHAR c;
     325: #endif /* CK_ANSIC */
     326: /* zdstuff */ {
     327:     xdbuf--;                /* Back up the pointer. */
     328:     *xdbuf = c;             /* Stuff the character. */
     329: }
     330:
     331: int
     332: #ifdef CK_ANSIC
     333: decode(CHAR *buf, int (*fn)(char), int xlate)
     334: #else
     335: decode(buf,fn,xlate) register CHAR *buf; register int (*fn)(); int xlate;
     336: #endif /* CK_ANSIC */
     337: /* decode */ {
     338:     register unsigned int a, a7, a8, b8; /* Various copies of current char */
     339:     int t;              /* Int version of character */
     340:     int ssflg;              /* Character was single-shifted */
     341:
     342: /*
     343:   Catch the case in which we are asked to decode into a file that is not open,
     344:   for example, if the user interrupted the transfer, but the other Kermit
     345:   keeps sending.
     346: */
     347:     if ((cxseen || czseen || discard) && (fn == putfil))
     348:       return(0);
     349:
     350:     xdbuf = buf;            /* Make global copy of pointer. */
     351:     rpt = 0;                /* Initialize repeat count. */
     352:
     353:     while ((a = *xdbuf++ & 0xFF) != '\0') { /* Get next character. */
     354:     if (a == rptq && rptflg) {  /* Got a repeat prefix? */
     355:         rpt = xunchar(*xdbuf++ & 0xFF); /* Yes, get the repeat count, */
     356:         rptn += rpt;
     357:         a = *xdbuf++ & 0xFF;    /* and get the prefixed character. */
     358:     }
     359:     b8 = lsstate ? 0200 : 0;    /* 8th-bit value from SHIFT-STATE */
     360:     if (ebqflg && a == ebq) {   /* Have 8th-bit prefix? */
     361:         b8 ^= 0200;         /* Yes, invert the 8th bit's value, */
     362:         ssflg = 1;          /* remember we did this, */
     363:         a = *xdbuf++ & 0xFF;    /* and get the prefixed character. */
     364:     } else ssflg = 0;
     365:
     366:     if (a == ctlq) {        /* If control prefix, */
     367:         a  = *xdbuf++ & 0xFF;   /* get its operand */
     368:         a7 = a & 0x7F;      /* and its low 7 bits. */
     369:         if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') /* Controllify */
     370:           a = ctl(a);       /* if in control range. */
     371:         if (lscapu) {       /* If doing locking shifts... */
     372:         if (lsstate)        /* If SHIFTED */
     373:           a8 = (a & ~b8) & 0xFF; /* Invert meaning of 8th bit */
     374:         else            /* otherwise */
     375:           a8 = a | b8;      /* OR in 8th bit */
     376:         /* If we're not in a quoted sequence */
     377:         if (!lsquote && (!lsstate || !ssflg)) {
     378:             if (a8 == DLE) {    /* Check for DLE quote */
     379:             lsquote = 1;    /* prefixed by single shift! */
     380:             continue;
     381:             } else if (a8 == SO) { /* Check for Shift-Out */
     382:             lsstate = 1;    /* SHIFT-STATE = SHIFTED */
     383:             continue;
     384:             } else if (a8 == SI) { /* or Shift-In */
     385:             lsstate = 0;    /* SHIFT-STATE = UNSHIFTED */
     386:             continue;
     387:             }
     388:         } else lsquote = 0;
     389:         }
     390:     }
     391:     a |= b8;            /* OR in the 8th bit */
     392:     if (rpt == 0) rpt = 1;      /* If no repeats, then one */
     393:     if (!binary) {          /* If in text mode, */
     394: #ifdef NLCHAR
     395:         if (a == CR) continue;  /* Discard carriage returns, */
     396:             if (a == LF) a = NLCHAR;    /* convert LF to system's newline. */
     397: #endif /* NLCHAR */
     398:
     399: #ifndef NOCSETS             /* Character-set translation */
     400: #ifdef KANJI                /* For Kanji transfers, */
     401:         if (tcharset != TC_JEUC)    /* postpone translation. */
     402: #endif /* KANJI */
     403:           if (xlate && rx) a = (*rx)((CHAR) a); /* Translate charset */
     404: #endif /* NOCSETS */
     405:         }
     406:     if (fn == putfil) { /* (PWP) speedup via buffered output and a macro */
     407:         for (; rpt > 0; rpt--) {    /* Output the char RPT times */
     408: #ifndef NOCSETS
     409: #ifdef KANJI
     410:         if (!binary && tcharset == TC_JEUC &&
     411:             fcharset != FC_JEUC) { /* Translating from J-EUC */
     412:             if (ffc == 0L) xkanjf();
     413:             if (xkanji(a,fn) < 0)  /* to something else? */
     414:               return(-1);
     415:         } else
     416: #endif /* KANJI */
     417: #endif /* NOCSETS */
     418:         if ((t = zmchout(a & fmask)) < 0) { /* zmchout is a macro */
     419: #ifdef COMMENT
     420: /* Too costly, uncomment these if you really need them. */
     421:             debug(F101,"decode zmchout","",t);
     422:             debug(F101,"decode zoutcnt","",zoutcnt);
     423:             debug(F101,"decode a","",a);
     424: #endif /* COMMENT */
     425:             return(-1);
     426:         }
     427:         ffc++;          /* Count the character */
     428:         }
     429:     } else {            /* Output to something else. */
     430:         a &= fmask;         /* Apply file mask */
     431:         for (; rpt > 0; rpt--) {    /* Output the char RPT times */
     432:         if ((*fn)((char) a) < 0) return(-1); /* Send to output func. */
     433:         ffc++;
     434:         }
     435:     }
     436:     }
     437:     return(0);
     438: }
     439:
     440: /*  G E T P K T -- Fill a packet data field  */
     441:
     442: /*
     443:  Gets characters from the current source -- file or memory string.
     444:  Encodes the data into the packet, filling the packet optimally.
     445:  Set first = 1 when calling for the first time on a given input stream
     446:  (string or file).
     447:
     448:  Call with:
     449:  bufmax -- current send-packet size
     450:  xlate  -- flag: 0 to skip character-set translation, 1 to translate
     451:
     452:  Uses global variables:
     453:  t     -- current character.
     454:  first -- flag: 1 to start up, 0 for input in progress, -1 for EOF.
     455:  next  -- next character.
     456:  data  -- pointer to the packet data buffer.
     457:  size  -- number of characters in the data buffer.
     458:  memstr - flag that input is coming from a memory string instead of a file.
     459:  memptr - pointer to string in memory.
     460:  (*sx)()  character set translation function
     461:
     462: Returns the size as value of the function, and also sets global "size",
     463: and fills (and null-terminates) the global data array.  Returns 0 upon eof.
     464:
     465: Rewritten by Paul W. Placeway (PWP) of Ohio State University, March 1989.
     466: Incorporates old getchx() and encode() inline to reduce function calls,
     467: uses buffered input for much-improved efficiency, and clears up some
     468: confusion with line termination (CRLF vs LF vs CR).
     469:
     470: Rewritten again by Frank da Cruz to incorporate locking shift mechanism,
     471: May 1991.
     472: */
     473:
     474: /*
     475:   Lookahead function to decide whether locking shift is worth it.  Looks at
     476:   the next four input characters to see if all of their 8th bits match the
     477:   argument.  Call with 0 or 0200.  Returns 1 if so, 0 if not.  If we don't
     478:   happen to have at least 4 more characters waiting in the input buffer,
     479:   returns 1.  Note that zinptr points two characters ahead of the current
     480:   character because of repeat-count lookahead.
     481: */
     482:
     483: #ifdef KANJI
     484: int
     485: kgetf() {
     486:     return(zminchar());
     487: }
     488:
     489: int
     490: kgetm() {
     491:     int x;
     492:     if (x = *memptr++) return(x);
     493:     else return(-1);
     494: }
     495: #endif /* KANJI */
     496:
     497: int
     498: lslook(b) unsigned int b; {     /* Locking Shift Lookahead */
     499:     int i;
     500:     if (zincnt < 3)         /* If not enough chars in buffer, */
     501:       return(1);            /* force shift-state switch. */
     502:     b &= 0200;              /* Force argument to proper form. */
     503:     for (i = -1; i < 3; i++)        /* Look at next 5 characters to */
     504:       if (((*(zinptr+i)) & 0200) != b)  /* see if all their 8th bits match.  */
     505:     return(0);          /* They don't. */
     506:     return(1);              /* They do. */
     507: }
     508:
     509: int
     510: getpkt(bufmax,xlate) int bufmax, xlate; { /* Fill one packet buffer */
     511:     register CHAR rt = t, rnext = next; /* register shadows of the globals */
     512:     register CHAR *dp, *odp, *odp2, *p1, *p2; /* pointers... */
     513:     register int x;         /* Loop index. */
     514:     register int a7;            /* Low 7 bits of character */
     515:     static CHAR leftover[9] = { '\0','\0','\0','\0','\0','\0','\0','\0','\0' };
     516:     CHAR xxls, xxdl, xxrc, xxss, xxcq;  /* Pieces of prefixed sequence */
     517:     int n;              /* worker */
     518:
     519: /*
     520:   Assume bufmax is the receiver's total receive-packet buffer length.
     521:   Our whole packet has to fit into it, so we adjust the data field length.
     522:   We also decide optimally whether it is better to use a short-format or
     523:   long-format packet when we're near the borderline.
     524: */
     525:     n = bufmax - 5;         /* Space for Data and Checksum */
     526:     if (n > 92 && n < 96) n = 92;   /* "Short" Long packets don't pay */
     527:     if (n > 92 && lpcapu == 0)      /* If long packets needed, */
     528:       n = 92;               /* make sure they've been negotiated */
     529:     bufmax = n - bctl;          /* Space for data */
     530:     if (n > 92) bufmax -= 3;        /* Long packet needs header chksum */
     531:
     532:     if (first == 1) {       /* If first character of this file... */
     533:     ffc = 0L;       /* Reset file character counter */
     534:     first = 0;      /* Next character won't be first */
     535:     *leftover = '\0';   /* Discard any interrupted leftovers, */
     536:
     537:     /* get first character of file into rt, watching out for null file */
     538:
     539: #ifndef NOCSETS
     540: #ifdef KANJI
     541:     if (!binary && tcharset == TC_JEUC && xlate) {
     542:         x = zkanjf();
     543:         if ((x = zkanji( memstr ? kgetm : kgetf )) < 0) {
     544:             first = -1;
     545:             size = 0;
     546:             if (x == -2) {
     547:                 debug(F100,"getpkt(zkanji): input error","",0);
     548:                 cxseen = 1;
     549:             } else debug(F100,"getpkt(zkanji): empty string/file","",0);
     550:             return (0);
     551:         }
     552:         ffc++;
     553:         rt = x;
     554:     } else {
     555: #endif /* KANJI */
     556: #endif /* not NOCSETS */
     557:     if (memstr) {           /* Reading data from memory string */
     558:         if ((rt = *memptr++) == '\0') { /* end of string ==> EOF */
     559:         first = -1;
     560:             size = 0;
     561:         debug(F100,"getpkt: empty string","",0);
     562:         return (0);
     563:         }
     564:
     565:     } else {            /* Reading data from a file */
     566:
     567:         if ((x = zminchar()) < 0) { /* End of file or input error */
     568:         first = -1;
     569:             size = 0;
     570:         if (x == -2) {      /* Error */
     571:             debug(F100,"getpkt: input error","",0);
     572:             cxseen = 1;     /* Interrupt the file transfer */
     573:         } else debug(F100,"getpkt: empty file","",0); /* Empty file */
     574:         return(0);
     575:         }
     576:         ffc++;          /* Count a file character */
     577:         rt = x;         /* Convert int to char */
     578:         debug(F101,"getpkt zminchar","",rt);
     579:     }
     580: #ifndef NOCSETS
     581: #ifdef KANJI
     582:     }
     583: #endif /* KANJI */
     584: #endif /* not NOCSETS */
     585:
     586:     rt &= fmask;            /* Apply SET FILE BYTESIZE mask */
     587:     debug(F101,"getpkt fmask","",fmask);
     588:     debug(F101,"getpkt new rt","",rt);
     589:
     590: #ifndef NOCSETS
     591:     if (xlate) {
     592:         debug(F101,"getpkt about to call translate function","",rt);
     593:         debug(F101,"tcharset","",tcharset);
     594:         debug(F101,"fcharset","",fcharset);
     595:     }
     596: #ifdef KANJI
     597:     if (tcharset != TC_JEUC)
     598: #endif /* KANJI */
     599:       if (!binary && sx && xlate) {
     600:           rt = (*sx)(rt); /* Translate */
     601:           debug(F101," translate function returns","",rt);
     602:       }
     603: #endif /* not NOCSETS */
     604:
     605:     /* PWP: handling of NLCHAR is done later (in the while loop)... */
     606:
     607:     } else if ((first == -1) && (*leftover == '\0')) /* EOF from last time? */
     608:         return(size = 0);
     609: /*
     610:   Here we handle characters that were encoded for the last packet but
     611:   did not fit, and so were saved in the "leftover" array.
     612: */
     613:     dp = data;              /* Point to packet data buffer */
     614:     for (p1 = leftover; (*dp = *p1) != '\0'; p1++, dp++) /* Copy leftovers */
     615:         ;
     616:     *leftover = '\0';           /* Delete leftovers */
     617:     if (first == -1)            /* Handle EOF */
     618:       return(size = (dp - data));
     619:
     620: /* Now fill up the rest of the packet. */
     621:
     622:     rpt = 0;                /* Initialize character repeat count */
     623:
     624:     while (first > -1) {        /* Until EOF... */
     625: #ifndef NOCSETS
     626: #ifdef KANJI
     627:     if (!binary && xlate && tcharset == TC_JEUC) {
     628:         if ((x = zkanji( memstr ? kgetm : kgetf )) < 0) {
     629:             first = -1;
     630:             if (x == -2) cxseen = 1;
     631:         }
     632:         ffc++;
     633:         rnext = x & fmask;
     634:     } else {
     635: #endif /* KANJI */
     636: #endif /* not NOCSETS */
     637:     if (memstr) {           /* Get next char from memory string */
     638:         if ((x = *memptr++) == '\0') /* End of string means EOF */
     639:           first = -1;       /* Flag EOF for next time. */
     640:         rnext = x & fmask;      /* Apply file mask */
     641:     } else {
     642:         if ((x = zminchar()) < 0) { /* Real file, check for EOF */
     643:         first = -1;     /* Flag eof for next time. */
     644:         if (x == -2) cxseen = 1; /* If error, cancel this file. */
     645:         }
     646:         rnext = x & fmask;      /* Apply file mask */
     647:     }
     648:     ffc++;              /* Count the character */
     649: #ifndef NOCSETS
     650: #ifdef KANJI
     651:     }
     652: #endif /* KANJI */
     653: #endif /* not NOCSETS */
     654:
     655:     /*** debug(F101,"getpkt rnext","",rnext); ***/
     656:
     657: #ifndef NOCSETS
     658: #ifdef KANJI
     659:     if (tcharset != TC_JEUC)
     660: #endif /* KANJI */
     661:         if (!binary && sx && xlate) {
     662:         rnext = (*sx)(rnext); /* Translate */
     663:         debug(F101,"getpkt xlated rnext to","",rnext);
     664:         }
     665: #endif /* not NOCSETS */
     666:
     667:     odp = dp;           /* Remember where we started. */
     668:     xxls = xxdl = xxrc = xxss = xxcq = NUL; /* Clear these. */
     669:
     670: /*
     671:   Now encode the character according to the options that are in effect:
     672:     binary: text or binary mode.
     673:     rptflg: repeat counts enabled.
     674:     ebqflg: 8th-bit prefixing enabled.
     675:     lscapu: locking shifts enabled.
     676: */
     677:     if (rptflg) {           /* Repeat processing is on? */
     678:         if (
     679: #ifdef NLCHAR
     680:         /*
     681: 		 * If the next char is really CRLF, then we cannot
     682: 		 * be doing a repeat (unless CR,CR,LF which becomes
     683: 		 * "~ <n-1> CR CR LF", which is OK but not most efficient).
     684: 		 * I just plain don't worry about this case.  The actual
     685: 		 * conversion from NL to CRLF is done after the rptflg if...
     686: 		 */
     687:         (binary || (rnext != NLCHAR)) &&
     688: #endif /* NLCHAR */
     689:         (rt == rnext) && (first == 0)) { /* Got a run... */
     690:         if (++rpt < 94) {   /* Below max, just count */
     691:             continue;       /* go back and get another */
     692:         }
     693:         else if (rpt == 94) {   /* Reached max, must dump */
     694:             xxrc = tochar(rpt); /* Put the repeat count here */
     695:             rptn += rpt;    /* Accumulate it for statistics */
     696:             rpt = 0;        /* And reset it */
     697:         }
     698:         } else if (rpt > 1) {   /* More than two */
     699:         xxrc = tochar(++rpt);   /* and count. */
     700:         rptn += rpt;
     701:         rpt = 0;        /* Reset repeat counter. */
     702:         }
     703:         /*
     704: 	      If (rpt == 1) we must encode exactly two characters.
     705: 	      This is done later, after the first character is encoded.
     706: 	    */
     707:     }
     708:
     709: #ifdef NLCHAR
     710:     if (!binary && (rt == NLCHAR)) { /* It's the newline character */
     711:         if (lscapu && lsstate) {    /* If SHIFT-STATE is SHIFTED */
     712:         if (ebqflg) {       /* If single shifts enabled, */
     713:             *dp++ = ebq;    /* insert a single shift. */
     714:         } else {        /* Otherwise must shift in. */
     715:             *dp++ = myctlq; /* Insert shift-out code */
     716:             *dp++ = 'O';
     717:             lsstate = 0;    /* Change shift state */
     718:         }
     719:         }
     720:         *dp++ = myctlq;     /* Insert carriage return directly */
     721:         *dp++ = 'M';
     722:         rt = LF;            /* Now make next char be linefeed. */
     723:     }
     724: #endif /* NLCHAR */
     725:
     726: /*
     727:   Now handle the 8th bit of the file character.  If we have an 8-bit
     728:   connection, we preserve the 8th bit.  If we have a 7-bit connection,
     729:   we employ either single or locking shifts (if they are enabled).
     730: */
     731:     a7 = rt & 0177;         /* Get low 7 bits of character */
     732:     if (rt & 0200) {        /* 8-bit character? */
     733:         if (lscapu) {       /* Locking shifts enabled? */
     734:         if (!lsstate) {     /* Not currently shifted? */
     735:             x = lslook(0200);   /* Look ahead */
     736:             if (x != 0 || ebqflg == 0) { /* Locking shift decision */
     737:             xxls = 'N';    /* Need locking shift-out */
     738:             lsstate = 1;       /* and change to shifted state */
     739:             } else if (ebqflg) {   /* Not worth it */
     740:             xxss = ebq;    /* Use single shift */
     741:             }
     742:         }
     743:         rt = a7;        /* Replace character by 7-bit value */
     744:         } else if (ebqflg) {    /* 8th bit prefixing is on? */
     745:         xxss = ebq;     /* Insert single shift */
     746:         rt = a7;        /* Replace character by 7-bit value */
     747:         }
     748:
     749:     } else if (lscapu) {        /* 7-bit character */
     750:
     751:         if (lsstate) {      /* Comes while shifted out? */
     752:         x = lslook(0);      /* Yes, look ahead */
     753:         if (x || ebqflg == 0) { /* Time to shift in. */
     754:             xxls = 'O';     /* Set shift-in code */
     755:             lsstate = 0;    /* Exit shifted state */
     756:         } else if (ebqflg) {    /* Not worth it, stay shifted out */
     757:             xxss = ebq;     /* Insert single shift */
     758:         }
     759:         }
     760:     }
     761:     /* If data character is significant to locking shift protocol... */
     762:     if (lscapu && (a7 == SO || a7 == SI || a7 == DLE))
     763:       xxdl = 'P';           /* Insert datalink escape */
     764:
     765:     if ((a7 < SP) || (a7 == DEL)) { /* Do control prefixing if necessary */
     766:         xxcq = myctlq;      /* The prefix */
     767:         rt = ctl(rt);       /* Uncontrollify the character */
     768:     }
     769:     if (a7 == myctlq)       /* Always prefix the control prefix */
     770:       xxcq = myctlq;
     771:
     772:     if ((rptflg) && (a7 == rptq))   /* If it's the repeat prefix, */
     773:       xxcq = myctlq;        /* prefix it if doing repeat counts */
     774:
     775:     if ((ebqflg) && (a7 == ebq))    /* Prefix the 8th-bit prefix */
     776:       xxcq = myctlq;        /* if doing 8th-bit prefixes */
     777:
     778: /* Now construct the entire sequence */
     779:
     780:     if (xxls) { *dp++ = myctlq; *dp++ = xxls; } /* Locking shift */
     781:     odp2 = dp;                  /* (Save this place) */
     782:     if (xxdl) { *dp++ = myctlq; *dp++ = xxdl; } /* Datalink escape */
     783:     if (xxrc) { *dp++ = rptq;   *dp++ = xxrc; } /* Repeat count */
     784:     if (xxss) { *dp++ = ebq; }          /* Single shift */
     785:     if (xxcq) { *dp++ = myctlq; }               /* Control prefix */
     786:     *dp++ = rt;         /* Finally, the character itself */
     787:
     788:     if (rpt == 1) {         /* Exactly two copies? */
     789:         rpt = 0;
     790:         p2 = dp;            /* Save place temporarily */
     791:         for (p1 = odp2; p1 < p2; p1++) /* Copy the old chars over again */
     792:           *dp++ = *p1;
     793:         if ((p2-data) <= bufmax) odp = p2; /* Check packet bounds */
     794:     }
     795:     rt = rnext;         /* Next character is now current. */
     796:
     797: /* Done encoding the character.  Now take care of packet buffer overflow. */
     798:
     799:     if ((dp-data) >= bufmax) {  /* If too big, save some for next. */
     800:         size = (dp-data);       /* Calculate the size. */
     801:         *dp = '\0';         /* Mark the end. */
     802:         if ((dp-data) > bufmax) {   /* if packet is overfull */
     803:         /* copy the part that doesn't fit into the leftover buffer, */
     804:         /* taking care not to split a prefixed sequence. */
     805:         for (p1 = leftover, p2=odp; (*p1 = *p2) != '\0'; p1++,p2++)
     806:             ;
     807:         debug(F111,"getpkt leftover",leftover,size);
     808:         debug(F101," osize","",(odp-data));
     809:         size = (odp-data);  /* Return truncated packet. */
     810:         *odp = '\0';        /* Mark the new end */
     811:         }
     812:         t = rt; next = rnext;   /* save for next time */
     813:         return(size);
     814:     }
     815:     }                   /* Otherwise, keep filling. */
     816:
     817:     size = (dp-data);           /* End of file */
     818:     *dp = '\0';             /* Mark the end of the data. */
     819:     debug(F111,"getpkt eof/eot",data,size); /* Fell thru before packet full, */
     820:     return(size);            /* return partially filled last packet. */
     821: }
     822:
     823: /*  T I N I T  --  Initialize a transaction  */
     824:
     825: int
     826: tinit() {
     827:     int x;
     828:
     829: #ifndef NOCSETS
     830:     if (tcharset == TC_TRANSP) {    /* Character set translation */
     831:     rx = sx = NULL;         /* Transparent, no translation */
     832: #ifdef KANJI
     833:     } else if (tcharset == TC_JEUC) {
     834:     rx = sx = NULL;         /* Transparent, no translation */
     835: #endif /* KANJI */
     836:     } else {                /* otherwise */
     837:     rx = xlr[tcharset][fcharset];   /* Input translation function */
     838:     sx = xls[tcharset][fcharset];   /* Output translation function */
     839:     }
     840:     debug(F101,"tinit tcharset","",tcharset);
     841:     debug(F101,"tinit fcharset","",fcharset);
     842: #ifdef COMMENT
     843:     debug(F101,"tinit sx   ","",sx);
     844:     debug(F101,"tinit rx   ","",rx);
     845: #endif /* COMMENT */
     846: #endif /* NOCSETS */
     847:     myinit[0] = '\0';           /* Haven't sent init string yet */
     848:     autopar = 0;            /* Automatic parity detection flag */
     849:     retrans = 0;            /* Packet retransmission count */
     850:     sndtyp = 0;             /* No previous packet */
     851:     xflg = 0;               /* Reset x-packet flag */
     852:     rqf = -1;               /* Reset 8th-bit-quote request flag */
     853:     memstr = 0;             /* Reset memory-string flag */
     854:     memptr = NULL;          /*  and pointer */
     855:     bctu = bctl = 1;            /* Reset block check type to 1 */
     856:     ebq = MYEBQ;            /* Reset 8th-bit quoting stuff */
     857:     ebqflg = 0;
     858:     if (savmod) {           /* If global file mode was saved, */
     859:         binary = savmod;        /*  restore it, */
     860:     savmod = 0;         /*  unsave it. */
     861:     }
     862:     pktnum = 0;             /* Initial packet number */
     863:     cxseen = czseen = discard = 0;  /* Reset interrupt flags */
     864:     *filnam = '\0';         /* Clear file name */
     865:     spktl = 0;              /* And its length */
     866:     nakstate = 0;           /* Assume not in a NAK'ing state */
     867:     numerrs = 0;            /* Transmission error counter */
     868:     if (server)             /* If acting as server, */
     869:       timint = srvtim;          /* Use server timeout interval. */
     870:     else                /* Otherwise */
     871:       timint = chktimo(rtimo,timef);    /* Begin by using local value */
     872:     spsiz = spsizr;         /* Initial send-packet size */
     873:     wslots = 1;             /* One window slot */
     874:     wslotn = 1;             /* No window negotiated yet */
     875:     winlo = 0;              /* Packet 0 is at window-low */
     876:     x = mksbuf(1);          /* Make a 1-slot send-packet buffer */
     877:     if (x < 0) return(x);
     878:     x = getsbuf(0);         /* Allocate first send-buffer. */
     879:     debug(F101,"tinit getsbuf","",x);
     880:     if (x < 0) return(x);
     881:     dumpsbuf();
     882:     x = mkrbuf(wslots);         /* & a 1-slot receive-packet buffer. */
     883:     if (x < 0) return(x);
     884:     what = W_NOTHING;           /* Doing nothing so far... */
     885:     lsstate = 0;            /* Initialize locking shift state */
     886:     return(0);
     887: }
     888:
     889: VOID
     890: pktinit() {             /* Initialize packet sequence */
     891:     pktnum = 0;             /* number & window low. */
     892:     winlo = 0;
     893: }
     894:
     895: /*  R I N I T  --  Respond to S or I packet  */
     896:
     897: VOID
     898: rinit(d) CHAR *d; {
     899:     char *tp;
     900:     ztime(&tp);
     901:     tlog(F110,"Transaction begins",tp,0L); /* Make transaction log entry */
     902:     if (binary)
     903:       tlog(F100,"Global file mode = binary","",0L);
     904:     else
     905:       tlog(F100,"Global file mode = text","",0L);
     906:     filcnt = 0;             /* Init file counter */
     907:     spar(d);
     908:     ack1(rpar());
     909: #ifdef datageneral
     910:     if ((local) && (!quiet))            /* Only do this if local & not quiet */
     911:         consta_mt();                    /* Start the asynch read task */
     912: #endif /* datageneral */
     913: }
     914:
     915:
     916: /*  R E S E T C  --  Reset per-transaction character counters */
     917:
     918: VOID
     919: resetc() {
     920:     rptn = 0;               /* Repeat counts */
     921:     fsecs = flci = flco = 0L;       /* File chars in and out */
     922:     tfc = tlci = tlco = 0L;     /* Total file, line chars in & out */
     923: #ifdef COMMENT
     924:     fsize = -1L;            /* File size */
     925: #else
     926:     if (what != W_SEND)
     927:       fsize = -1L;
     928:     debug(F101,"resetc fsize","",fsize);
     929: #endif /* COMMENT */
     930:     timeouts = retrans = 0;     /* Timeouts, retransmissions */
     931:     spackets = rpackets = 0;        /* Packet counts out & in */
     932:     crunched = 0;           /* Crunched packets */
     933:     wmax = 1;               /* Maximum window size used */
     934: }
     935:
     936: /*  S I N I T  --  Get & verify first file name, then send Send-Init packet */
     937: /*
     938:  Returns:
     939:    1 if send operation begins successfully
     940:    0 if send operation fails
     941: */
     942: #ifdef DYNAMIC
     943: char *cmargbuf = NULL;
     944: #else
     945: char cmargbuf[256];
     946: #endif /* DYNAMIC */
     947: char *cmargp[2];
     948:
     949: int
     950: sinit() {
     951:     int x;              /* Worker int */
     952:     char *tp, *xp, *m;          /* Worker string pointers */
     953:
     954:     filcnt = 0;             /* Initialize file counter */
     955:     sndsrc = nfils;         /* Source for filenames */
     956: #ifdef DYNAMIC
     957:     if (!cmargbuf && !(cmargbuf = malloc(256)))
     958:     fatal("sinit: no memory for cmargbuf");
     959: #endif /* DYNAMIC */
     960:     cmargbuf[0] = NUL;          /* Initialize name buffer */
     961:
     962:     debug(F101,"sinit nfils","",nfils);
     963:     debug(F110,"sinit cmarg",cmarg,0);
     964:     debug(F110,"sinit cmarg2",cmarg2,0);
     965:     if (nfils == 0) {           /* Sending from stdin or memory. */
     966:     if ((cmarg2 != NULL) && (*cmarg2)) {
     967:         cmarg = cmarg2;     /* If F packet, "as-name" is used */
     968:         cmarg2 = "";        /* if provided */
     969:     } else cmarg = "stdin";     /* otherwise just use "stdin" */
     970:     strcpy(cmargbuf,cmarg);
     971:     cmargp[0] = cmargbuf;
     972:     cmargp[1] = "";
     973:     cmlist = cmargp;
     974:     nfils = 1;
     975:     }
     976: #ifdef COMMENT
     977:     if (nfils < 1) {            /* Filespec pointed to by cmarg */
     978:     if (nfils < 0) sndsrc = 1;
     979:     nfils = 1;          /* Change it to cmlist */
     980:     strcpy(cmargbuf,cmarg);     /* so we have a consistent way */
     981:     cmargp[0] = cmargbuf;       /* of going thru the file list. */
     982:     cmargp[1] = "";
     983:     cmlist = cmargp;
     984:     }
     985:
     986: /* At this point, cmlist contains the list of filespecs to send */
     987:
     988:     debug(F111,"sinit *cmlist",*cmlist,nfils);
     989:
     990:     xp = *cmlist;           /* Save this for messages */
     991: #else
     992:     xp = (nfils < 0) ? cmarg : *cmlist;
     993: #endif
     994:
     995:     x = gnfile();           /* Get first filename. */
     996:     m = NULL;               /* Error message pointer */
     997:     debug(F101,"sinit gnfil","",x);
     998:     switch (x) {
     999:       case -5: m = "Too many files match wildcard"; break;
    1000:       case -4: m = "Cancelled"; break;
    1001:       case -3: m = "Read access denied"; break;
    1002:       case -2: m = "File is not readable"; break;
    1003:       case -1: m = iswild(filnam) ? "No files match" : "File not found";
    1004:     break;
    1005:       case  0: m = "No filespec given!" ; break;
    1006:       default:
    1007:     break;
    1008:     }
    1009:     debug(F101,"sinit nfils","",nfils);
    1010:     debug(F110,"sinit filnam",filnam,0);
    1011:     debug(F110,"sinit cmdstr",cmdstr,0);
    1012:     if (x < 1) {            /* Didn't get a file. */
    1013:     if (server)         /* Doing GET command */
    1014:       errpkt((CHAR *)m);        /* so send Error packet. */
    1015:     else                /* Doing SEND command */
    1016:       screen(SCR_EM,0,0l,m);    /* so print message. */
    1017:     tlog(F110,xp,m,0L);     /* Make transaction log entry. */
    1018:     freerbuf(rseqtbl[0]);       /* Free the buffer the GET came in. */
    1019:     return(0);          /* Return failure code */
    1020:     }
    1021:     if (!local && !server) sleep(delay); /* Delay if requested */
    1022: #ifdef datageneral
    1023:     if ((local) && (!quiet))            /* Only do this if local & not quiet */
    1024:         consta_mt();                    /* Start the asynch read task */
    1025: #endif /* datageneral */
    1026:     freerbuf(rseqtbl[0]);       /* Free the buffer the GET came in. */
    1027:     sipkt('S');             /* Send the Send-Init packet. */
    1028:     ztime(&tp);             /* Get current date/time */
    1029:     tlog(F110,"Transaction begins",tp,0L); /* Make transaction log entry */
    1030:     debug(F111,"sinit ok",filnam,0);
    1031:     return(1);
    1032: }
    1033:
    1034: int
    1035: #ifdef CK_ANSIC
    1036: sipkt(char c)               /* Send S or I packet. */
    1037: #else
    1038: sipkt(c) char c;
    1039: #endif
    1040: /* sipkt */ {
    1041:     CHAR *rp; int k;
    1042:     debug(F101,"sipkt pktnum","",pktnum);
    1043:     k = sseqtbl[pktnum];        /* Find slot for this packet */
    1044:     debug(F101,"sipkt k","",k);
    1045:     if (k < 0) {            /* No slot? */
    1046:     k = getsbuf(winlo = pktnum);    /* Make one. */
    1047:     debug(F101,"sipkt getsbuf","",k);
    1048:     }
    1049:     ttflui();               /* Flush pending input. */
    1050:     rp = rpar();            /* Get protocol parameters. */
    1051:     return(spack(c,pktnum,(int)strlen((char *)rp),rp)); /* Send them. */
    1052: }
    1053:
    1054: /*  X S I N I T  --  Retransmit S-packet  */
    1055: /*
    1056:   For use in the GET-SEND sequence, when we start to send, but receive another
    1057:   copy of the GET command because the receiver didn't get our S packet.
    1058:   This retransmits the S packet and frees the receive buffer for the ACK.
    1059:   The only reason this special case is necessary is that packet number zero
    1060:   is being re-used.
    1061: */
    1062: VOID
    1063: xsinit() {
    1064:     int k;
    1065:     k = rseqtbl[0];
    1066:     debug(F101,"xsinit k","",k);
    1067:     if (k > -1)
    1068:       freerbuf(k);
    1069:     resend(0);
    1070: }
    1071:
    1072: /*  R C V F I L -- Receive a file  */
    1073:
    1074: /*
    1075:   Incoming filename is in data field of F packet.
    1076:   This function decodes it into the srvcmd buffer, substituting an
    1077:   alternate "as-name", if one was given.
    1078:   Then it does any requested transformations (like converting to
    1079:   lowercase), and finally if a file of the same name already exists,
    1080:   takes the desired collision action.
    1081: */
    1082: #ifdef pdp11
    1083: #define XNAMLEN 256
    1084: #else
    1085: #define XNAMLEN 65
    1086: #endif /* pdp11 */
    1087:
    1088: int
    1089: rcvfil(n) char *n; {
    1090:     char xname[XNAMLEN], *xp;       /* Buffer for constructing name */
    1091: #ifdef DTILDE
    1092:     char *dirp, *tilde_expand();
    1093: #endif /* DTILDE */
    1094:
    1095:     lsstate = 0;            /* Cancel locking-shift state */
    1096:     srvptr = srvcmd;            /* Decode file name from packet. */
    1097:     decode(rdatap,putsrv,0);        /* Don't xlate charsets. */
    1098:     if (*srvcmd == '\0')        /* Watch out for null F packet. */
    1099:       strcpy((char *)srvcmd,"NONAME");
    1100: #ifdef DTILDE
    1101:     dirp = tilde_expand((char *)srvcmd); /* Expand tilde, if any. */
    1102:     if (*dirp != '\0') strcpy((char *)srvcmd,dirp);
    1103: #endif /* DTILDE */
    1104:     screen(SCR_FN,0,0l,(char *)srvcmd); /* Put it on screen if local */
    1105:     debug(F110,"rcvfil",(char *)srvcmd,0); /* Debug log entry */
    1106:     debug(F101,"rcvfil cmarg2","",cmarg2);
    1107:     tlog(F110,"Receiving",(char *)srvcmd,0L); /* Transaction log entry */
    1108:     if (cmarg2 != NULL) {               /* Check for alternate name */
    1109:         if (*cmarg2 != '\0') {
    1110:             strcpy((char *)srvcmd,cmarg2); /* Got one, use it. */
    1111:         }
    1112:     } else cmarg2 = "";
    1113: /*
    1114:   NOTE: Much of this code should be moved to opena(), where the file is
    1115:   actually opened, AFTER we have received the Attribute packet(s).  That
    1116:   way, if the file is mail, or is being sent to the printer, we don't have
    1117:   to fuss with collision options, etc, but instead we just pipe the data
    1118:   straight into lpr or mail (in UNIX anyway), and then we can also have
    1119:   nice subject lines for mail messages by using whatever is in the file
    1120:   header packet data field, whether it's a legal filename or not.
    1121: */
    1122:     if ((int)strlen((char *)srvcmd) > XNAMLEN) /* Watch out for overflow */
    1123:       *(srvcmd + XNAMLEN - 1) = NUL;
    1124:
    1125:     xp = xname;             /* OK to proceed. */
    1126:     if (fncnv && !*cmarg2)
    1127:       zrtol((char *)srvcmd,xp);     /* convert name to local form */
    1128:     else                /* otherwise, */
    1129:       strcpy(xname,(char *)srvcmd); /* use it literally */
    1130:     cmarg2 = "";            /* Remove alternate name */
    1131:     debug(F110,"rcvfil as",xname,0);
    1132:
    1133: #ifdef COMMENT              /* Old code... */
    1134:     if (warn) {             /* File collision avoidance? */
    1135:     if (zchki(xname) != -1) {   /* Yes, file exists? */
    1136:         znewn(xname,&xp);       /* Yes, make new name. */
    1137:         strcpy(xname,xp);
    1138:         debug(F110," exists, new name ",xname,0);
    1139:         }
    1140:     }
    1141: #endif /* COMMENT */
    1142:
    1143: /* Filename collision action section. */
    1144:
    1145:     if (
    1146: #ifdef UNIX
    1147:     strcmp(xname,"/dev/null") &&    /* It's not the null device? */
    1148: #endif /* UNIX */
    1149:     (zchki(xname) != -1)        /* File of same name exists? */
    1150:     ) {
    1151:     debug(F111,"rcvfil exists",xname,fncact);
    1152:     switch (fncact) {       /* Yes, do what user said. */
    1153:       case XYFX_A:          /* Append */
    1154:         debug(F100,"rcvfil append","",0);
    1155:         break;
    1156:       case XYFX_Q:          /* Query (Ask) */
    1157:         break;          /* not yet implemented */
    1158:       case XYFX_B:          /* Backup (rename old file) */
    1159:         znewn(xname,&xp);       /* Get new unique name */
    1160:         debug(F110,"rcvfil backup",xname,0);
    1161:         debug(F110,"rcvfil backup",xp,0);
    1162:         if (zrename(xname,xp) < 0) {
    1163:         debug(F110,"rcvfil rename fails",xname,0);
    1164:         return(0);
    1165:         }
    1166:         break;
    1167:       case XYFX_D:          /* Discard (refuse new file) */
    1168:         discard = 1;
    1169:         debug(F101,"rcvfil discard","",discard);
    1170:         break;          /* not yet implemented */
    1171:       case XYFX_R:          /* Rename new file */
    1172:         znewn(xname,&xp);       /* Make new name. */
    1173:         strcpy(xname,xp);
    1174:         debug(F110,"rcvfil rename",xname,0);
    1175:       case XYFX_X:          /* Replace old file */
    1176:         debug(F100,"rcvfil overwrite","",0);
    1177:         break;
    1178:       case XYFX_U:          /* Refuse if older */
    1179:         debug(F100,"rcvfil update","",0);
    1180:         break;          /* Not here, we don't have */
    1181:                     /* the attribute packet yet. */
    1182:       default:
    1183:         debug(F101,"rcvfil bad collision action","",fncact);
    1184:         break;
    1185:     }
    1186:     }
    1187:     debug(F110,"rcvfil: xname",xname,0);
    1188:     screen(SCR_AN,0,0l,xname);      /* Display it */
    1189:     strcpy(n,xname);            /* Return pointer to actual name. */
    1190:
    1191: #ifndef NOICP
    1192: #ifndef MAC
    1193: /* Why not Mac? */
    1194:     strcpy(fspec,xname);        /* Here too for \v(filespec) */
    1195: #endif /* MAC */
    1196: #endif /* NOICP */
    1197:     debug(F110,"rcvfil: n",n,0);
    1198:     ffc = 0L;               /* Init per-file counters */
    1199:     fsecs = gtimer();           /* Time this file started */
    1200:     filcnt++;
    1201:     intmsg(filcnt);
    1202:     return(1);              /* Always succeeds */
    1203: }
    1204:
    1205:
    1206: /*  R E O F  --  Receive End Of File packet for incoming file */
    1207:
    1208: /*
    1209:   Closes the received file.
    1210:   Returns:
    1211:     0 on success.
    1212:    -1 if file could not be closed.
    1213:     2 if disposition was mail, mail was sent, but temp file not deleted.
    1214:     3 if disposition was print, file was printed, but not deleted.
    1215:    -2 if disposition was mail and mail could not be sent
    1216:    -3 if disposition was print and file could not be printed
    1217: */
    1218: int
    1219: reof(f,yy) char *f; struct zattr *yy; {
    1220:     int x;
    1221:     char *p;
    1222:     char c;
    1223:
    1224:     debug(F111,"reof fncact",f,fncact);
    1225:     debug(F101,"reof discard","",discard);
    1226:     success = 1;            /* Assume status is OK */
    1227:     lsstate = 0;            /* Cancel locking-shift state */
    1228:     if (
    1229: #ifdef COMMENT
    1230: /*
    1231:   If the discard flag is set, for whatever reason, we discard it, right?
    1232: */
    1233:     (fncact == XYFX_D || fncact == XYFX_U) &&
    1234: #endif /* COMMENT */
    1235:     discard != 0) {    /* SET FILE COLLISION DISCARD or UPDATE */
    1236:
    1237:     debug(F101,"reof discarding","",0);
    1238:     discard = 0;            /* We never opened it, */
    1239:     return(0);          /* so we won't close it. */
    1240:     }
    1241:     if (cxseen == 0) cxseen = (*rdatap == 'D'); /* Got cancel directive? */
    1242:     success = (cxseen || czseen) ? 0 : 1; /* Set SUCCESS flag appropriately */
    1243:     x = clsof(cxseen || czseen);    /* Close the file (resets cxseen) */
    1244:     if (x < 0) success = 0;     /* If failure to close, FAIL */
    1245:     if (atcapu) zstime(f,yy,0);     /* Set file creation date */
    1246:
    1247: /* Handle dispositions from attribute packet... */
    1248:
    1249: #ifndef NOFRILLS
    1250:     if (yy->disp.len != 0) {
    1251:     p = yy->disp.val;
    1252:     c = *p++;
    1253:     if (c == 'M') {         /* Mail to user. */
    1254:         x = zmail(p,filnam);    /* Do the system's mail command */
    1255:         if (x < 0) success = 0; /* Remember status */
    1256:         tlog(F110,"mailed",filnam,0L);
    1257:         tlog(F110," to",p,0L);
    1258:         zdelet(filnam);     /* Delete the file */
    1259:     } else if (c == 'P') {      /* Print the file. */
    1260:         x = zprint(p,filnam);   /* Do the system's print command */
    1261:         if (x < 0) success = 0; /* Remember status */
    1262:         tlog(F110,"printed",filnam,0L);
    1263:         tlog(F110," with options",p,0L);
    1264: #ifndef VMS
    1265:         if (zdelet(filnam) && x == 0) x = 3; /* Delete the file */
    1266: #endif /* VMS */
    1267:     }
    1268:     }
    1269: #endif /* NOFRILLS */
    1270:     debug(F101,"reof returns","",x);
    1271:     *filnam = '\0';
    1272:     return(x);
    1273: }
    1274:
    1275: /*  R E O T  --  Receive End Of Transaction  */
    1276:
    1277: VOID
    1278: reot() {
    1279:     cxseen = czseen = discard = 0;  /* Reset interruption flags */
    1280:     tstats();
    1281: }
    1282:
    1283: /*  S F I L E -- Send File header or teXt header packet  */
    1284:
    1285: /*  Call with x nonzero for X packet, zero for F packet  */
    1286: /*  Returns 1 on success, 0 on failure                   */
    1287:
    1288: int
    1289: sfile(x) int x; {
    1290: #ifdef pdp11
    1291: #define PKTNL 64
    1292: #else
    1293: #define PKTNL 256
    1294: #endif /* pdp11 */
    1295:     char pktnam[PKTNL+1];       /* Local copy of name */
    1296:     char *s;
    1297:
    1298:     lsstate = 0;            /* Cancel locking-shift state */
    1299:     if (nxtpkt() < 0) return(0);    /* Bump packet number, get buffer */
    1300:     if (x == 0) {           /* F-Packet setup */
    1301:
    1302:         if (*cmarg2 != '\0') {      /* If we have a send-as name, */
    1303:         strncpy(pktnam,cmarg2,PKTNL); /* copy it literally, */
    1304:         cmarg2 = "";        /* and blank it out for next time. */
    1305:         } else {            /* Otherwise use actual file name: */
    1306:         if (fncnv) {        /* If converting names, */
    1307:             zltor(filnam,pktnam);   /* convert it to common form, */
    1308:         } else {            /* otherwise, */
    1309:             strncpy(pktnam,filnam,PKTNL); /* copy it literally. */
    1310:             }
    1311:         }
    1312:         debug(F110,"sfile",filnam,0);   /* Log debugging info */
    1313:         debug(F110," pktnam",pktnam,0);
    1314:         if (openi(filnam) == 0)     /* Try to open the file */
    1315:       return(0);
    1316:         s = pktnam;         /* Name for packet data field */
    1317:
    1318:     } else {                /* X-packet setup */
    1319:
    1320:         debug(F110,"sxpack",cmdstr,0);  /* Log debugging info */
    1321:         s = cmdstr;         /* Name for data field */
    1322:     }
    1323:
    1324:     encstr((CHAR *)s);          /* Encode the name into encbuf[]. */
    1325:                     /* Send the F or X packet */
    1326:     spack((char) (x ? 'X' : 'F'), pktnum, size, encbuf+7);
    1327:
    1328:     if (x == 0) {           /* Display for F packet */
    1329:         if (displa) {           /* Screen */
    1330:         screen(SCR_FN,'F',(long)pktnum,filnam);
    1331:         screen(SCR_AN,0,0l,pktnam);
    1332:         screen(SCR_FS,0,fsize,"");
    1333:         }
    1334:         tlog(F110,"Sending",filnam,0L); /* Transaction log entry */
    1335:         tlog(F110," as",pktnam,0L);
    1336:     if (binary) {           /* Log file mode in transaction log */
    1337:         tlog(F101," mode: binary","",(long) binary);
    1338:     } else {            /* If text mode, check character set */
    1339:         tlog(F100," mode: text","",0L);
    1340: #ifndef NOCSETS
    1341:         tlog(F110," file character set",fcsinfo[fcharset].name,0L);
    1342:         if (tcharset == TC_TRANSP)
    1343:           tlog(F110," xfer character set","transparent",0L);
    1344:         else
    1345:           tlog(F110," xfer character set",tcsinfo[tcharset].name,0L);
    1346: #endif /* NOCSETS */
    1347:     }
    1348:     } else {                /* Display for X-packet */
    1349:
    1350:         screen(SCR_XD,'X',(long)pktnum,cmdstr); /* Screen */
    1351:         tlog(F110,"Sending from:",cmdstr,0L);   /* Transaction log */
    1352:     }
    1353:     intmsg(++filcnt);           /* Count file, give interrupt msg */
    1354:     first = 1;              /* Init file character lookahead. */
    1355:     ffc = 0L;               /* Init file character counter. */
    1356:     fsecs = gtimer();           /* Time this file started */
    1357:     debug(F101,"SFILE fsecs","",fsecs);
    1358:     return(1);
    1359: }
    1360:
    1361: /*  S D A T A -- Send a data packet */
    1362:
    1363: /*
    1364:   Returns -1 if no data to send (end of file).  If there is data, a data
    1365:   packet is sent, and sdata() returns 1.
    1366:
    1367:   For window size greater than 1, keep sending data packets until window
    1368:   is full or characters start to appear from the other Kermit, whichever
    1369:   happens first.
    1370:
    1371:   In the windowing case, when there is no more data left to send (or when
    1372:   sending has been interrupted), sdata() does nothing and returns 0 each time
    1373:   it is called until the current packet number catches up to the last data
    1374:   packet that was sent.
    1375: */
    1376:
    1377: int
    1378: sdata() {
    1379:     int i, x, len;
    1380:
    1381:     debug(F101,"sdata entry, first","",first);
    1382:     debug(F101," drain","",drain);
    1383:
    1384: /* The "drain" flag is used with window size > 1.  It means we have sent  */
    1385: /* our last data packet.  If called and drain is not zero, then we return */
    1386: /* 0 as if we had sent an empty data packet, until all data packets have  */
    1387: /* been ACK'd, then then we can finally return -1 indicating EOF, so that */
    1388: /* the protocol can switch to seof state.  This is a kludge, but at least */
    1389: /* it's localized...  */
    1390:
    1391:     if (first == 1) drain = 0;      /* Start of file, init drain flag. */
    1392:
    1393:     if (drain) {            /* If draining... */
    1394:     debug(F101,"sdata draining, winlo","",winlo);
    1395:     if (winlo == pktnum)        /* If all data packets are ACK'd */
    1396:       return(-1);           /* return EOF indication */
    1397:     else                /* otherwise */
    1398:       return(0);            /* pretend we sent a data packet. */
    1399:     }
    1400:     debug(F101,"sdata sbufnum","",sbufnum);
    1401:     for (i = sbufnum; i > 0; i--) {
    1402:         debug(F101,"sdata countdown","",i);
    1403:     x = nxtpkt();           /* Get next pkt number and buffer */
    1404:     debug(F101,"sdata packet","",pktnum);
    1405:     if (x < 0) return(0);
    1406: /***	dumpsbuf(); */
    1407:     if (cxseen || czseen) {     /* If interrupted, done. */
    1408:         if (wslots > 1) {
    1409:         drain = 1;
    1410:         debug(F101,"sdata cx/zseen, drain","",cxseen);
    1411:         return(0);
    1412:         } else {
    1413:         return(-1);
    1414:         }
    1415:     }
    1416: #ifdef COMMENT
    1417:     if (spsiz > 94)         /* Fill the packet's data buffer */
    1418:       len = getpkt(spsiz-bctl-6,1); /* long packet */
    1419:     else                /*  or */
    1420:       len = getpkt(spsiz-bctl-3,1); /* short packet */
    1421: #else
    1422:     len = getpkt(spsiz,1);
    1423: #endif /* COMMENT */
    1424:     if (len == 0) {         /* Done if no data. */
    1425:         if (pktnum == winlo) return(-1);
    1426:         drain = 1;          /* But can't return -1 until all */
    1427:         debug(F101,"sdata eof, drain","",drain);
    1428:         return(0);          /* ACKs are drained. */
    1429:     }
    1430:     spack('D',pktnum,len,data); /* Send the data packet. */
    1431:     x = ttchk();            /* Peek at input buffer. */
    1432:     debug(F101,"sdata ttchk","",x); /* ACKs waiting, maybe?  */
    1433:     if (x) return(1);       /* Yes, stop sending data packets */
    1434:     }                   /* and go try to read the ACKs. */
    1435:     return(1);
    1436: }
    1437:
    1438:
    1439: /*  S E O F -- Send an End-Of-File packet */
    1440:
    1441: /*  Call with a string pointer to character to put in the data field, */
    1442: /*  or else a null pointer or "" for no data.  */
    1443:
    1444: /*
    1445:   There are two "send-eof" functions.  seof() is used to send the normal eof
    1446:   packet at the end of a file's data (even if the file has no data), or when
    1447:   a file transfer is interrupted.  sxeof() is used to send an EOF packet that
    1448:   occurs because of attribute refusal.  The difference is purely a matter of
    1449:   buffer allocation and packet sequence number management.  Both functions
    1450:   act as "front ends" to the common send-eof function, szeof().
    1451: */
    1452:
    1453: /* Code common to both seof() and sxeof() */
    1454:
    1455: int
    1456: szeof(s) CHAR *s; {
    1457:     lsstate = 0;            /* Cancel locking-shift state */
    1458:     if ((s != NULL) && (*s != '\0')) {
    1459:     spack('Z',pktnum,1,s);
    1460:     tlog(F100," *** interrupted, sending discard request","",0L);
    1461:     } else {
    1462:     spack('Z',pktnum,0,(CHAR *)"");
    1463:     }
    1464:     discard = 0;            /* Turn off per-file discard flag */
    1465:     return(0);
    1466: }
    1467:
    1468: int
    1469: seof(s) CHAR *s; {
    1470:
    1471: /*
    1472:   ckcpro.w, before calling seof(), sets window size back to 1 and then calls
    1473:   window(), which clears out the old buffers.  This is OK because the final
    1474:   data packet for the file has been ACK'd.  However, sdata() has already
    1475:   called nxtpkt(), which set the new value of pktnum which seof() will use.
    1476:   So all we need to do here is is allocate a new send-buffer.
    1477: */
    1478:     if (getsbuf(pktnum) < 0) {  /* Get a buffer for packet n */
    1479:     debug(F101,"seof can't get s-buffer","",pktnum);
    1480:     return(-1);
    1481:     }
    1482:     return(szeof(s));
    1483: }
    1484:
    1485: /*
    1486:   Version of seof() to be called when sdata() has not been called before.  The
    1487:   difference is that this version calls nxtpkt() to allocate a send-buffer and
    1488:   get the next packet number.
    1489: */
    1490: int
    1491: sxeof(s) CHAR *s; {
    1492:     int x;
    1493:     x = nxtpkt();           /* Get next pkt number and buffer */
    1494:     if (x < 0)
    1495:       debug(F101,"sxeof nxtpkt fails","",pktnum);
    1496:     else
    1497:       debug(F101,"sxeof packet","",pktnum);
    1498:     return(szeof(s));
    1499: }
    1500:
    1501: /*  S E O T -- Send an End-Of-Transaction packet */
    1502:
    1503: int
    1504: seot() {
    1505:     if (nxtpkt() < 0) return(-1);   /* Bump packet number, get buffer */
    1506:     spack('B',pktnum,0,(CHAR *)""); /* Send the EOT packet */
    1507:     cxseen = czseen = discard = 0;  /* Reset interruption flags */
    1508:     tstats();               /* Log timing info */
    1509:     return(0);
    1510: }
    1511:
    1512: /*   R P A R -- Fill the data array with my send-init parameters  */
    1513:
    1514:
    1515: CHAR dada[20];              /* Use this instead of data[]. */
    1516:                     /* To avoid some kind of wierd */
    1517:                     /* addressing foulup in spack()... */
    1518:                     /* (which might be fixed now...) */
    1519:
    1520: CHAR *
    1521: rpar() {
    1522:     if (rpsiz > MAXPACK)        /* Biggest normal packet I want. */
    1523:       dada[0] = tochar(MAXPACK);    /* If > 94, use 94, but specify */
    1524:     else                /* extended packet length below... */
    1525:       dada[0] = tochar(rpsiz);      /* else use what the user said. */
    1526:     dada[1] = tochar(chktimo(pkttim,0)); /* When I want to be timed out */
    1527:     dada[2] = tochar(mypadn);       /* How much padding I need (none) */
    1528:     dada[3] = ctl(mypadc);      /* Padding character I want */
    1529:     dada[4] = tochar(eol);      /* End-Of-Line character I want */
    1530:     dada[5] = '#';          /* Control-Quote character I send */
    1531:     switch (rqf) {          /* 8th-bit prefix */
    1532:     case -1:
    1533:     case  1: if (parity) ebq = sq = '&'; break;
    1534:     case  0:
    1535:     case  2: break;
    1536:     }
    1537:     debug(F000,"rpar 8bq sq","",sq);
    1538:     debug(F000,"rpar 8bq ebq","",ebq);
    1539:     if (lscapu == 2)            /* LOCKING-SHIFT FORCED */
    1540:       dada[6] = 'N';            /* means no single-shift */
    1541:     else
    1542:       dada[6] = sq;
    1543:     dada[7] = (bctr == 4) ? 'B' : bctr + '0'; /* Block check type */
    1544:     if (rptflg)             /* Run length encoding */
    1545:         dada[8] = rptq;         /* If receiving, agree. */
    1546:     else
    1547:         dada[8] = '~';
    1548:     /* CAPAS mask */
    1549:     dada[9] = tochar((lscapr ? lscapb : 0) | /* Locking shifts */
    1550:              (atcapr ? atcapb : 0) | /* Attribute packets */
    1551:              (lpcapr ? lpcapb : 0) | /* Long packets */
    1552:              (swcapr ? swcapb : 0)); /* Sliding windows */
    1553:     dada[10] = tochar(swcapr ? wslotr : 1);  /* Window size */
    1554:     rpsiz = urpsiz - 1;         /* Long packets ... */
    1555:     dada[11] = tochar(rpsiz / 95);  /* Long packet size, big part */
    1556:     dada[12] = tochar(rpsiz % 95);  /* Long packet size, little part */
    1557:     dada[13] = '\0';            /* Terminate the init string */
    1558: #ifdef DEBUG
    1559:     if (deblog) {
    1560:     debug(F110,"rpar",dada,0);
    1561:     rdebu(dada,(int)strlen((char *)dada));
    1562:     }
    1563: #endif /* DEBUG */
    1564:     strcpy((char *)myinit,(char *)dada);
    1565:     return(dada);           /* Return pointer to string. */
    1566: }
    1567:
    1568: int
    1569: spar(s) CHAR *s; {          /* Set parameters */
    1570:     int x, y, lpsiz;
    1571:
    1572:     debug(F110,"entering spar",s,0);
    1573:
    1574:     s--;                /* Line up with field numbers. */
    1575:
    1576: /* Limit on size of outbound packets */
    1577:     x = (rln >= 1) ? xunchar(s[1]) : 80;
    1578:     lpsiz = spsizr;         /* Remember what they SET. */
    1579:     if (spsizf) {           /* SET-command override? */
    1580:     if (x < spsizr) spsiz = x;  /* Ignore LEN unless smaller */
    1581:     } else {                /* otherwise */
    1582:     spsiz = (x < 10) ? 80 : x;  /* believe them if reasonable */
    1583:     }
    1584:     spmax = spsiz;          /* Remember maximum size */
    1585:
    1586: /* Timeout on inbound packets */
    1587:     if (timef) {
    1588:     timint = rtimo;         /* SET SEND TIMEOUT value overrides */
    1589:     } else {                /* Otherwise use requested value, */
    1590:     x = (rln >= 2) ? xunchar(s[2]) : rtimo; /* if it is legal. */
    1591:     timint = (x < 0) ? rtimo : x;
    1592:     }
    1593:     timint = chktimo(timint,timef); /* Adjust if necessary */
    1594:
    1595: /* Outbound Padding */
    1596:     npad = 0; padch = '\0';
    1597:     if (rln >= 3) {
    1598:     npad = xunchar(s[3]);
    1599:     if (rln >= 4) padch = ctl(s[4]); else padch = 0;
    1600:     }
    1601:     if (npad) {
    1602:     int i;
    1603:     for (i = 0; i < npad; i++) padbuf[i] = dopar(padch);
    1604:     }
    1605:
    1606: /* Outbound Packet Terminator */
    1607:     seol = (rln >= 5) ? xunchar(s[5]) : CR;
    1608:     if ((seol < 2) || (seol > 31)) seol = CR;
    1609:
    1610: /* Control prefix */
    1611:     x = (rln >= 6) ? s[6] : '#';
    1612:     myctlq = ((x > 32 && x < 63) || (x > 95 && x < 127)) ? x : '#';
    1613:
    1614: /* 8th-bit prefix */
    1615:     rq = (rln >= 7) ? s[7] : 0;
    1616:     if (rq == 'Y') rqf = 1;
    1617:       else if ((rq > 32 && rq < 63) || (rq > 95 && rq < 127)) rqf = 2;
    1618:         else rqf = 0;
    1619:     debug(F000,"spar 8bq rq","",rq);
    1620:     debug(F000,"spar 8bq sq","",sq);
    1621:     debug(F000,"spar 8bq ebq","",ebq);
    1622:     debug(F101,"spar 8bq rqf","",rqf);
    1623:     switch (rqf) {
    1624:     case 0: ebqflg = 0; break;
    1625:     case 1: if (parity) { ebqflg = 1; ebq = '&'; } break;
    1626:     case 2: if (ebqflg = (ebq == sq || sq == 'Y')) ebq = rq;
    1627:     }
    1628:     if (lscapu == 2) {     /* No single-shifts if LOCKING-SHIFT FORCED */
    1629:     ebqflg = 0;
    1630:     ebq = 'N';
    1631:     }
    1632:
    1633: /* Block check */
    1634:     x = 1;
    1635:     if (rln >= 8) {
    1636:     if (s[8] == 'B') x = 4;
    1637:     else x = s[8] - '0';
    1638:     if ((x < 1) || (x > 4)) x = 1;
    1639:     }
    1640:     bctr = x;
    1641:
    1642: /* Repeat prefix */
    1643:     if (rln >= 9) {
    1644:     rptq = s[9];
    1645:     rptflg = ((rptq > 32 && rptq < 63) || (rptq > 95 && rptq < 127));
    1646:     } else rptflg = 0;
    1647:
    1648: /* Capabilities */
    1649:     atcapu = lpcapu = swcapu = 0;   /* Assume none of these */
    1650:     if (lscapu != 2) lscapu = 0;    /* Assume no LS unless forced. */
    1651:     y = 11;             /* Position of next field, if any */
    1652:     if (rln >= 10) {
    1653:         x = xunchar(s[10]);
    1654:     debug(F101,"spar capas","",x);
    1655:         atcapu = (x & atcapb) && atcapr;
    1656:     lpcapu = (x & lpcapb) && lpcapr;
    1657:     swcapu = (x & swcapb) && swcapr;
    1658:     debug(F101,"spar lscapu","",lscapu);
    1659:     debug(F101,"spar lscapr","",lscapr);
    1660:     debug(F101,"spar ebqflg","",ebqflg);
    1661:     if (lscapu != 2) lscapu = ((x & lscapb) && lscapr && ebqflg) ? 1 : 0;
    1662:     debug(F101,"spar swcapr","",swcapr);
    1663:     debug(F101,"spar swcapu","",swcapu);
    1664:     debug(F101,"spar lscapu","",lscapu);
    1665:     for (y = 10; (xunchar(s[y]) & 1) && (rln >= y); y++) ;
    1666:     debug(F101,"spar y","",y);
    1667:     }
    1668:
    1669: /* Long Packets */
    1670:     debug(F101,"spar lpcapu","",lpcapu);
    1671:     if (lpcapu) {
    1672:         if (rln > y+1) {
    1673:         x = xunchar(s[y+2]) * 95 + xunchar(s[y+3]);
    1674:         debug(F101,"spar lp len","",x);
    1675:         if (spsizf) {       /* If overriding negotiations */
    1676:         spsiz = (x < lpsiz) ? x : lpsiz; /* do this, */
    1677:         } else {                     /* otherwise */
    1678:         spsiz = (x > MAXSP) ? MAXSP : x; /* do this. */
    1679:         }
    1680:         if (spsiz < 10) spsiz = 80; /* Be defensive... */
    1681:     }
    1682:     }
    1683:     /* (PWP) save current send packet size for optimal packet size calcs */
    1684:     spmax = spsiz;
    1685:     debug(F101,"spar lp spmax","",spmax);
    1686:     timint = chktimo(timint,timef); /* Recalculate the packet timeout! */
    1687:
    1688: /* Sliding Windows... */
    1689:
    1690:     if (swcapr) {           /* Only if requested... */
    1691:         if (rln > y) {          /* See what other Kermit says */
    1692:         x = xunchar(s[y+1]);
    1693:         debug(F101,"spar window","",x);
    1694:         wslotn = (x > MAXWS) ? MAXWS : x;
    1695: /*
    1696:   wslotn = negotiated size (from other Kermit's S or I packet).
    1697:   wslotr = requested window size (from this Kermit's SET WINDOW command).
    1698: */
    1699:         if (wslotn > wslotr)    /* Use the smaller of the two */
    1700:           wslotn = wslotr;
    1701:         if (wslotn < 1)     /* Watch out for bad negotiation */
    1702:           wslotn = 1;
    1703:         if (wslotn > 1)
    1704:           swcapu = 1; /* We do windows... */
    1705:         debug(F101,"spar window after adjustment","",x);
    1706:     } else {            /* No window size specified. */
    1707:         wslotn = 1;         /* We don't do windows... */
    1708:         debug(F101,"spar window","",x);
    1709:         swcapu = 0;
    1710:         debug(F101,"spar no windows","",wslotn);
    1711:     }
    1712:     }
    1713:
    1714: /* Now recalculate packet length based on number of windows.   */
    1715: /* The nogotiated number of window slots will be allocated,    */
    1716: /* and the maximum packet length will be reduced if necessary, */
    1717: /* so that a windowful of packets can fit in the big buffer.   */
    1718:
    1719:     if (wslotn > 1) {           /* Shrink to fit... */
    1720:     x = adjpkl(spsiz,wslotn,bigsbsiz);
    1721:     if (x < spsiz) {
    1722:         spsiz = spmax = x;
    1723:         debug(F101,"spar sending, redefine spsiz","",spsiz);
    1724:     }
    1725:     }
    1726:
    1727: /* Record parameters in debug log */
    1728: #ifdef DEBUG
    1729:     if (deblog) sdebu(rln);
    1730: #endif /* DEBUG */
    1731:     numerrs = 0;            /* Start counting errors here. */
    1732:     return(0);
    1733: }
    1734:
    1735: /*  G N F I L E  --  Get name of next file to send  */
    1736: /*
    1737:   Expects global sndsrc to be:
    1738:    -1: next filename to be obtained by calling znext().
    1739:     0: no next file name
    1740:     1: (or greater) next filename to be obtained from **cmlist.
    1741:   Returns:
    1742:     1, with name of next file in filnam.
    1743:     0, no more files, with filnam set to empty string.
    1744:    -1, file not found
    1745:    -2, file is not readable
    1746:    -3, read access denied
    1747:    -4, cancelled
    1748:    -5, too many files match wildcard
    1749: */
    1750:
    1751: int
    1752: gnfile() {
    1753:     int x; long y;
    1754:     int retcode = 0;
    1755:
    1756:     debug(F101,"gnfile sndsrc","",sndsrc);
    1757:     fsize = -1L;            /* Initialize file size */
    1758:     if (sndsrc == 0) {          /* It's not really a file */
    1759:     if (nfils > 0) {        /* It's a pipe, or stdin */
    1760:         strcpy(filnam, *cmlist);    /* Copy its "name" */
    1761:         nfils = 0;          /* There is no next file */
    1762:         return(1);          /* OK this time */
    1763:     } else return(0);       /* but not next time */
    1764:     }
    1765:
    1766: /* If file group interruption (C-Z) occurred, fail.  */
    1767:
    1768:     if (czseen) {
    1769:     tlog(F100,"Transaction cancelled","",0L);
    1770:         debug(F100,"gnfile czseen","",0);
    1771:     return(-4);
    1772:     }
    1773:
    1774: /* Loop through file list till we find a readable, sendable file */
    1775:
    1776:     y = -1L;                /* Loop exit (file size) variable */
    1777:     while (y < 0L) {            /* Keep trying till we get one... */
    1778:     if (sndsrc > 0) {       /* File list in cmlist */
    1779:         debug(F101,"gnfile nfils","",nfils);
    1780:         if (nfils-- > 0) {      /* Still some left? */
    1781:         strcpy(filnam,*cmlist++);
    1782:         debug(F111,"gnfile cmlist filnam",filnam,nfils);
    1783:         if (!clfils) {      /* Expand only if not from cmdline */
    1784:             x = zxpand(filnam);
    1785:             debug(F101,"gnfile zxpand","",x);
    1786:             if (x == 1) {
    1787:             znext(filnam);
    1788:             goto gotnam;
    1789:             }
    1790:             if (x == 0) {
    1791:             retcode = -1; /* None match */
    1792:             continue;
    1793:             }
    1794:             if (x < 0) return(-5); /* Too many to expand */
    1795:             sndsrc = -1;    /* Change send-source to znext() */
    1796:         }
    1797:         } else {            /* We're out of files. */
    1798:         debug(F101,"gnfile done","",nfils);
    1799:         *filnam = '\0';
    1800:         return(retcode);
    1801:         }
    1802:     }
    1803:
    1804: /* Otherwise, step to next element of internal wildcard expansion list. */
    1805:
    1806:     if (sndsrc < 0) {
    1807:         x = znext(filnam);
    1808:         debug(F111,"gnfile znext",filnam,x);
    1809:         if (x == 0) {       /* If no more, */
    1810:         sndsrc = 1;     /* go back to list */
    1811:         continue;
    1812:         }
    1813:     }
    1814:
    1815: /* Get here with a filename. */
    1816:
    1817: gotnam:
    1818:     if (sndsrc) {
    1819:         y = zchki(filnam);      /* Check if file readable */
    1820:         retcode = (int) y;      /* Possible return code */
    1821:         if (y == -1L) {     /* If not found */
    1822:         debug(F110,"gnfile skipping:",filnam,0);
    1823:         tlog(F111,filnam,"not sent, reason",(long)y);
    1824:         screen(SCR_ST,ST_SKIP,0l,filnam);
    1825:         continue;
    1826:         } else if (y < 0) {
    1827:         continue;
    1828:         } else {
    1829:         fsize = y;
    1830:         return(1);
    1831:         }
    1832:     } else return(1);       /* sndsrc is 0... */
    1833:     }
    1834:     *filnam = '\0';         /* Should never get here */
    1835:     return(0);
    1836: }
    1837:
    1838:
    1839: /*  S N D H L P  --  Routine to send builtin help  */
    1840:
    1841: int
    1842: sndhlp() {
    1843: #ifndef NOSERVER
    1844:     nfils = 0;              /* No files, no lists. */
    1845:     xflg = 1;               /* Flag we must send X packet. */
    1846:     strcpy(cmdstr,"help text");     /* Data for X packet. */
    1847:     first = 1;              /* Init getchx lookahead */
    1848:     memstr = 1;             /* Just set the flag. */
    1849:     memptr = hlptxt;            /* And the pointer. */
    1850:     if (binary) {           /* If file mode is binary, */
    1851:     savmod = binary;        /*  remember to restore it later. */
    1852:     binary = 0;         /*  turn it back to text for this, */
    1853:     }
    1854:     return(sinit());
    1855: #else
    1856:     return(0);
    1857: #endif /* NOSERVER */
    1858: }
    1859:
    1860: #ifdef OS2
    1861: /*  S N D S P A C E -- send disk space message  */
    1862: int
    1863: sndspace(int drive) {
    1864: #ifndef NOSERVER
    1865:     static char spctext[64];
    1866:     if (drive)
    1867:       sprintf(spctext, " Drive %c: %ldK free\n", drive,
    1868:           zdskspace(drive - 'A' + 1) / 1024L);
    1869:     else
    1870:       sprintf(spctext, " Free space: %ldK\n", zdskspace(0)/1024L);
    1871:     nfils = 0;          /* No files, no lists. */
    1872:     xflg = 1;           /* Flag we must send X packet. */
    1873:     strcpy(cmdstr,"free space");/* Data for X packet. */
    1874:     first = 1;          /* Init getchx lookahead */
    1875:     memstr = 1;         /* Just set the flag. */
    1876:     memptr = spctext;       /* And the pointer. */
    1877:     if (binary) {       /* If file mode is binary, */
    1878:         savmod = binary;    /*  remember to restore it later. */
    1879:         binary = 0;     /*  turn it back to text for this, */
    1880:     }
    1881:     return(sinit());
    1882: #else
    1883:     return(0);
    1884: #endif /* NOSERVER */
    1885: }
    1886: #endif /* OS2 */
    1887:
    1888: /*  C W D  --  Change current working directory  */
    1889:
    1890: /*
    1891:  String passed has first byte as length of directory name, rest of string
    1892:  is name.  Fails if can't connect, else ACKs (with name) and succeeds.
    1893: */
    1894:
    1895: int
    1896: cwd(vdir) char *vdir; {
    1897:     char *cdd, *zgtdir(), *dirp;
    1898:
    1899:     vdir[xunchar(*vdir) + 1] = '\0';    /* Terminate string with a null */
    1900:     dirp = vdir+1;
    1901:     tlog(F110,"Directory requested: ",dirp,0L);
    1902:     if (zchdir(dirp)) {     /* Try to change */
    1903:     cdd = zgtdir();     /* Get new working directory. */
    1904:     debug(F110,"cwd",cdd,0);
    1905:     encstr((CHAR *)cdd);
    1906:     ack1((CHAR *)(encbuf+7));
    1907:     tlog(F110,"Changed directory to",cdd,0L);
    1908:     return(1);
    1909:     } else {
    1910:     debug(F110,"cwd failed",dirp,0);
    1911:     tlog(F110,"Failed to change directory to",dirp,0L);
    1912:     return(0);
    1913:     }
    1914: }
    1915:
    1916:
    1917: /*  S Y S C M D  --  Do a system command  */
    1918:
    1919: /*  Command string is formed by concatenating the two arguments.  */
    1920:
    1921: int
    1922: syscmd(prefix,suffix) char *prefix, *suffix; {
    1923:     char *cp;
    1924:
    1925:     if (prefix == NULL || *prefix == '\0') return(0);
    1926:
    1927:     for (cp = cmdstr; *prefix != '\0'; *cp++ = *prefix++) ;
    1928:     while (*cp++ = *suffix++) ;     /* copy suffix */
    1929:
    1930:     debug(F110,"syscmd",cmdstr,0);
    1931:     if (zxcmd(ZIFILE,cmdstr) > 0) {
    1932:     debug(F110,"syscmd zxcmd ok",cmdstr,0);
    1933:     nfils = sndsrc = 0;     /* Flag that input is from stdin */
    1934:     xflg = hcflg = 1;       /* And special flags for pipe */
    1935:     if (binary) {           /* If file mode is binary, */
    1936:         savmod = binary;        /*  remember to restore it later. */
    1937:         binary = 0;         /*  turn it back to text for this, */
    1938:     }
    1939:     return (sinit());       /* Send S packet */
    1940:     } else {
    1941:     debug(F100,"syscmd zxcmd failed",cmdstr,0);
    1942:     return(0);
    1943:     }
    1944: }
    1945:
    1946: /*  R E M S E T  --  Remote Set  */
    1947: /*  Called by server to set variables as commanded in REMOTE SET packets.  */
    1948: /*  Returns 1 on success, 0 on failure.  */
    1949:
    1950: int
    1951: remset(s) char *s; {
    1952:     int len, i, x, y;
    1953:     char *p;
    1954:
    1955:     len = xunchar(*s++);        /* Length of first field */
    1956:     p = s + len;            /* Pointer to second length field */
    1957:     *p++ = '\0';            /* Zero out second length field */
    1958:     x = atoi(s);            /* Value of first field */
    1959:     debug(F111,"remset",s,x);
    1960:     debug(F110,"remset",p,0);
    1961:     switch (x) {            /* Do the right thing */
    1962:       case 132:             /* Attributes (all, in) */
    1963:     atcapr = atoi(p);
    1964:     return(1);
    1965:       case 133:             /* File length attributes */
    1966:       case 233:             /* IN/OUT combined */
    1967:       case 148:             /* Both kinds of lengths */
    1968:       case 248:
    1969:     atleni = atleno = atoi(p);
    1970:     return(1);
    1971:       case 134:             /* File Type (text/binary) */
    1972:       case 234:
    1973:     attypi = attypo = atoi(p);
    1974:     return(1);
    1975:       case 135:             /* File creation date */
    1976:       case 235:
    1977:     atdati = atdato = atoi(p);
    1978:     return(1);
    1979:       case 139:             /* File Blocksize */
    1980:       case 239:
    1981:     atblki = atblko = atoi(p);
    1982:     return(1);
    1983:       case 141:             /* Encoding / Character Set */
    1984:       case 241:
    1985:     atenci = atenco = atoi(p);
    1986:     return(1);
    1987:       case 142:             /* Disposition */
    1988:       case 242:
    1989:     atdisi = atdiso = atoi(p);
    1990:     return(1);
    1991:       case 145:             /* System ID */
    1992:       case 245:
    1993:     atsidi = atsido = atoi(p);
    1994:     return(1);
    1995:       case 147:             /* System-Dependent Info */
    1996:       case 247:
    1997:     atsysi = atsyso = atoi(p);
    1998:     return(1);
    1999:       case 232:             /* Attributes (all, out) */
    2000:     atcapr = atoi(p);
    2001:     return(1);
    2002:       case 300:             /* File type (text, binary) */
    2003:     binary = atoi(p);
    2004:     return(1);
    2005:       case 301:             /* File name conversion */
    2006:     fncnv = 1 - atoi(p);        /* (oops) */
    2007:     return(1);
    2008:       case 302:             /* File name collision */
    2009:     x = atoi(p);
    2010:     if (x == XYFX_R) warn = 1;  /* Rename */
    2011:     if (x == XYFX_X) warn = 0;  /* Replace */
    2012:     fncact = x;
    2013:     return(1);
    2014:       case 310:             /* Incomplete File Disposition */
    2015:     keep = atoi(p);         /* Keep, Discard */
    2016:     return(1);
    2017:       case 311:             /* Blocksize */
    2018:     fblksiz = atoi(p);
    2019:     return(1);
    2020:       case 312:             /* Record Length */
    2021:     frecl = atoi(p);
    2022:     return(1);
    2023:       case 313:             /* Record format */
    2024:     frecfm = atoi(p);
    2025:     return(1);
    2026:       case 314:             /* File organization */
    2027:     forg = atoi(p);
    2028:     return(1);
    2029:       case 315:             /* File carriage control */
    2030:     fcctrl = atoi(p);
    2031:     return(1);
    2032:       case 400:             /* Block check */
    2033:     y = atoi(p);
    2034:     if (y < 5 && y > 0) {
    2035:         bctr = y;
    2036:         return(1);
    2037:     } else if (*p == 'B') {
    2038:         bctr = 4;
    2039:         return(1);
    2040:     }
    2041:     return(0);
    2042:       case 401:             /* Receive packet-length */
    2043:     urpsiz = atoi(p);
    2044:     if (urpsiz > MAXRP) urpsiz = MAXRP;
    2045:     urpsiz = adjpkl(urpsiz,wslots,bigrbsiz);
    2046:     return(1);
    2047:       case 402:             /* Receive timeout */
    2048:     y = atoi(p);            /* Client is telling us */
    2049:     if (y > -1 && y < 999) {    /* the timeout that it wants */
    2050:         pkttim = chktimo(y,timef);  /* us to tell it to use. */
    2051:         return(1);
    2052:     } else return(0);
    2053:       case 403:             /* Retry limit */
    2054:     y = atoi(p);
    2055:     if (y > -1 && y < 95) {
    2056:         maxtry = y;
    2057:         return(1);
    2058:     } else return(0);
    2059:       case 404:             /* Server timeout */
    2060:     y = atoi(p);
    2061:     if (y < 0) return(0);
    2062:     srvtim = y;
    2063:     return(1);
    2064:
    2065: #ifndef NOCSETS
    2066:       case 405:             /* Transfer character set */
    2067:     for (i = 0; i < ntcsets; i++) {
    2068:         if (!strcmp(tcsinfo[i].designator,p)) break;
    2069:     }
    2070:     debug(F101,"remset xfer charset lookup","",i);
    2071:     if (i == ntcsets) return(0);
    2072:     tcharset = tcsinfo[i].code; /* if known, use it */
    2073:     if (tcharset == TC_TRANSP)
    2074:       rx = NULL;
    2075:     else
    2076:       rx = xlr[tcharset][fcharset]; /* translation function */
    2077:     return(1);
    2078: #endif /* NOCSETS */
    2079:
    2080:       case 406:             /* Window slots */
    2081:     y = atoi(p);
    2082:     if (y == 0) y = 1;
    2083:     if (y < 1 && y > 31) return(0);
    2084:     wslotr = y;
    2085:     swcapr = 1;
    2086:     urpsiz = adjpkl(urpsiz,wslots,bigrbsiz);
    2087:     return(1);
    2088:       default:              /* Anything else... */
    2089:     return(0);
    2090:     }
    2091: }
    2092:
    2093: /* Adjust packet length based on number of window slots and buffer size */
    2094:
    2095: int
    2096: adjpkl(pktlen,slots,bufsiz) int pktlen, slots, bufsiz; {
    2097:     debug(F101,"adjpkl len","",pktlen);
    2098:     debug(F101,"adjpkl slots","",slots);
    2099:     debug(F101,"adjpkl bufsiz","",bufsiz);
    2100:     if (((pktlen + 6) * slots) > bufsiz)
    2101:       pktlen = (bufsiz / slots) - 6;
    2102:     debug(F101,"adjpkl new len","",pktlen);
    2103:     return(pktlen);
    2104: }

#### Defined functions

adjpkl defined in line 2095; used 8 times

- in line 1720, 2045, 2086
- in /usr/src/new/kermit5.188/ckuus3.c line 740-742(2), 1264
- in /usr/src/new/kermit5.188/ckuus7.c line 1077, 1103

cwd defined in line 1895; never used
decode defined in line 331; used 1 times

- in line 1097

encode defined in line 203; used 2 times

- in line 224-227(2)

encstr defined in line 162; used 5 times

- in line 1324, 1905
- in /usr/src/new/kermit5.188/ckcfn2.c line 1201, 1224, 1231

getpkt defined in line 509; used 5 times

- in line 183-185(2), 1418-1422(3)

gnfile defined in line 1751; used 1 times

- in line 995

kgetf defined in line 484; used 2 times

- in line 543, 628

kgetm defined in line 489; used 2 times

- in line 543, 628

lslook defined in line 497; used 3 times

- in line 76, 735, 752

pktinit defined in line 889; never used
putfil defined in line 286; used 2 times

- in line 347, 406

putsrv defined in line 263; used 1 times

- in line 1097

puttrm defined in line 275; never used
rcvfil defined in line 1088; never used
remset defined in line 1950; never used
reof defined in line 1218; never used
reot defined in line 1277; never used
resetc defined in line 918; never used
rinit defined in line 897; never used
rpar defined in line 1520; used 3 times

- in line 75, 908, 1050

sdata defined in line 1377; never used
seof defined in line 1468; never used
seot defined in line 1503; never used
sfile defined in line 1288; never used
sinit defined in line 949; used 3 times

- in line 1854, 1881, 1939

sipkt defined in line 1034; used 1 times

- in line 1027

sndhlp defined in line 1841; never used
sndspace defined in line 1862; never used
spar defined in line 1568; used 1 times

- in line 907

sxeof defined in line 1490; never used
syscmd defined in line 1921; never used
szeof defined in line 1455; used 3 times

- in line 77, 1482, 1498

tinit defined in line 825; never used
xsinit defined in line 1062; never used
zdstuff defined in line 320; used 16 times

- in /usr/src/new/kermit5.188/ckuxla.c line 2479, 2486-2504(7), 2514-2539(8)

#### Defined variables

VOID defined in line 897; never used
cmargbuf defined in line 945; used 7 times

- in line 957-960(3), 970-971(2), 980-981(2)

cmargp defined in line 947; used 6 times

- in line 971-973(3), 981-983(3)

cmdstr defined in line 132; used 12 times

- in line 1011, 1320-1321(2), 1350-1351(2), 1846, 1873, 1927-1932(4), 1941

dada defined in line 1515; used 22 times

- in line 1523-1530(7), 1540-1565(15)

drain defined in line 135; used 6 times

- in line 1382, 1391-1393(2), 1409, 1426-1427(2)

encbuf defined in line 160; used 6 times

- in line 181, 1326, 1906
- in /usr/src/new/kermit5.188/ckcfn2.c line 1202, 1225, 1232

first defined in line 137; used 20 times

- in line 179, 190, 213, 532-534(2), 544, 559, 568, 607, 617, 624-629(2), 639-643(2), 689, 1354, 1381, 1391, 1847, 1874

fnsv defined in line 1; used 1 times

- in /usr/src/new/kermit5.188/ckuus5.c line 1595

lsquote defined in line 142; used 3 times

- in line 377-379(2), 388

lsstate defined in line 141; used 16 times

- in line 359, 372-385(4), 711, 717, 734-738(2), 751-755(2), 885, 1095, 1227, 1298, 1457

memptr defined in line 127; used 9 times

- in line 175-177(2), 189, 492, 558, 638, 854, 1849, 1876

memstr defined in line 117; used 13 times

- in line 175-178(2), 188, 543, 557, 628, 637, 853, 1848, 1875
- in /usr/src/new/kermit5.188/ckcfn3.c line 1265, 1370-1371(2)

myinit defined in line 122; used 5 times

- in line 847, 1564
- in /usr/src/new/kermit5.188/ckcfn2.c line 1107, 1119(2)

next defined in line 139; used 3 times

- in line 213, 511, 812

sndsrc defined in line 112; used 13 times

- in line 955, 978, 1756-1758(2), 1778, 1795, 1806-1810(2), 1818, 1933
- in /usr/src/new/kermit5.188/ckcfn3.c line 1268-1270(2)
- in /usr/src/new/kermit5.188/ckuusr.c line 1656

t defined in line 138; used 5 times

- in line 339, 418-421(2), 511, 812

xdbuf defined in line 315; used 8 times

- in line 327-328(2), 350-357(4), 363-367(2)

#### Defined macros

ENCBUFL defined in line 158; used 4 times

- in line 160, 167-169(3)

PKTNL defined in line 1293; used 3 times

- in line 1295, 1303, 1309

XNAMLEN defined in line 1085; used 3 times

- in line 1090, 1122-1123(2)

Last modified: 1992-11-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 4742 |