Annotation of researchv10dc/lbin/kermit/ckcfns.c, revision 1.1

1.1     ! root        1: char *fnsv = "C-Kermit functions, 4E(053) 14 Sep 87";
        !             2: 
        !             3: /*  C K C F N S  --  System-independent Kermit protocol support functions.  */
        !             4: 
        !             5: /*  ...Part 1 (others moved to ckcfn2 to make this module small enough) */
        !             6: 
        !             7: /*
        !             8:  4E includes support for Data General systems from Phil Julian of SAS 
        !             9:  Institute, and Megamax native Macintosh C compiler support from
        !            10:  Jim Noble of Planning Research Corporation.
        !            11: */ 
        !            12: /*
        !            13:  Author: Frank da Cruz (SY.FDC@CU20B),
        !            14:  Columbia University Center for Computing Activities, January 1985.
        !            15:  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
        !            16:  Permission is granted to any individual or institution to use, copy, or
        !            17:  redistribute this software so long as it is not sold for profit, provided this
        !            18:  copyright notice is retained. 
        !            19: */
        !            20: /*
        !            21:  System-dependent primitives defined in:
        !            22: 
        !            23:    ck?tio.c -- terminal i/o
        !            24:    cx?fio.c -- file i/o, directory structure
        !            25: */
        !            26: #include "ckcsym.h"                    /* Need this for Mac */
        !            27: #include "ckcker.h"                    /* Symbol definitions for Kermit */
        !            28: #include "ckcdeb.h"                    /* Debug formats, typedefs, etc. */
        !            29: 
        !            30: #ifndef NULL
        !            31: #define NULL 0
        !            32: #endif
        !            33: 
        !            34: /* Externals from ckcmai.c */
        !            35: extern int spsiz, rpsiz, timint, rtimo, npad, ebq, ebqflg, rpt, rptq,
        !            36:  rptflg, capas, keep;
        !            37: extern int pktnum, prvpkt, sndtyp, bctr, bctu, fmask,
        !            38:  size, osize, maxsize, spktl, nfils, stdouf, warn, timef, spsizf;
        !            39: extern int parity, speed, turn, turnch, 
        !            40:  delay, displa, pktlog, tralog, seslog, xflg, mypadn;
        !            41: extern long filcnt, ffc, flci, flco, tlci, tlco, tfc, fsize;
        !            42: extern int tsecs;
        !            43: extern int deblog, hcflg, binary, savmod, fncnv, local, server, cxseen, czseen;
        !            44: extern int rq, rqf, sq, wsize, urpsiz, rln;
        !            45: extern int atcapr, atcapb, atcapu;
        !            46: extern int lpcapr, lpcapb, lpcapu;
        !            47: extern int swcapr, swcapb, swcapu;
        !            48: extern CHAR padch, mypadc, eol, seol, ctlq, myctlq, sstate;
        !            49: extern CHAR filnam[], sndpkt[], recpkt[], data[], srvcmd[], stchr, mystch;
        !            50: extern char *cmarg, *cmarg2, *hlptxt, **cmlist;
        !            51: extern CHAR *srvptr;
        !            52: extern char *rdatap;
        !            53: long zchki();
        !            54: char *strcpy();
        !            55: CHAR *rpar();
        !            56: 
        !            57: /* Variables local to this module */
        !            58: 
        !            59: static char *memptr;                   /* Pointer for memory strings */
        !            60: 
        !            61: static char cmdstr[100];               /* Unix system command string */
        !            62: 
        !            63: static int  sndsrc;                    /* Flag for where to send from: */
        !            64:                                        /* -1: name in cmdata */
        !            65:                                        /*  0: stdin          */
        !            66:                                        /* >0: list in cmlist */
        !            67: 
        !            68: static int  memstr,                    /* Flag for input from memory string */
        !            69:     first;                             /* Flag for first char from input */
        !            70: static CHAR t,                         /* Current character */
        !            71:     next;                              /* Next character */
        !            72: #ifdef datageneral
        !            73: extern int quiet;
        !            74: #endif
        !            75: 
        !            76: /*  E N C S T R  --  Encode a string from memory. */
        !            77: 
        !            78: /*  Call this instead of getpkt() if source is a string, rather than a file. */
        !            79: 
        !            80: encstr(s) char* s; {
        !            81:     int m; char *p;
        !            82: 
        !            83:     m = memstr; p = memptr;            /* Save these. */
        !            84: 
        !            85:     memptr = s;                                /* Point to the string. */
        !            86:     memstr = 1;                                /* Flag memory string as source. */
        !            87:     first = 1;                         /* Initialize character lookahead. */
        !            88:     getpkt(spsiz-bctu-3);              /* Fill a packet from the string. */
        !            89:     memstr = m;                                /* Restore memory string flag */
        !            90:     memptr = p;                                /* and pointer */
        !            91:     first = 1;                         /* Put this back as we found it. */
        !            92: }
        !            93: 
        !            94: /* E N C O D E - Kermit packet encoding procedure */
        !            95: 
        !            96: encode(a) CHAR a; {                    /* The current character */
        !            97:     int a7;                            /* Low order 7 bits of character */
        !            98:     int b8;                            /* 8th bit of character */
        !            99: 
        !           100:     if (rptflg)        {                       /* Repeat processing? */
        !           101:         if (a == next && (first == 0)) { /* Got a run... */
        !           102:            if (++rpt < 94)             /* Below max, just count */
        !           103:                 return;
        !           104:            else if (rpt == 94) {       /* Reached max, must dump */
        !           105:                 data[size++] = rptq;
        !           106:                 data[size++] = tochar(rpt);
        !           107:                 rpt = 0;
        !           108:            }
        !           109:         } else if (rpt == 1) {         /* Run broken, only 2? */
        !           110:             rpt = 0;                   /* Yes, reset repeat flag & count. */
        !           111:            encode(a);                  /* Do the character twice. */
        !           112:            if (size <= maxsize) osize = size;
        !           113:            rpt = 0;
        !           114:            encode(a);
        !           115:            return;
        !           116:        } else if (rpt > 1) {           /* More than two */
        !           117:             data[size++] = rptq;       /* Insert the repeat prefix */
        !           118:             data[size++] = tochar(++rpt); /* and count. */
        !           119:             rpt = 0;                   /* Reset repeat counter. */
        !           120:         }
        !           121:     }
        !           122:     a7 = a & 0177;                     /* Isolate ASCII part */
        !           123:     b8 = a & 0200;                     /* and 8th (parity) bit. */
        !           124: 
        !           125:     if (ebqflg && b8) {                        /* Do 8th bit prefix if necessary. */
        !           126:         data[size++] = ebq;
        !           127:         a = a7;
        !           128:     }
        !           129:     if ((a7 < SP) || (a7==DEL))        {       /* Do control prefix if necessary */
        !           130:         data[size++] = myctlq;
        !           131:        a = ctl(a);
        !           132:     }
        !           133:     if (a7 == myctlq)                  /* Prefix the control prefix */
        !           134:         data[size++] = myctlq;
        !           135: 
        !           136:     if ((rptflg) && (a7 == rptq))      /* If it's the repeat prefix, */
        !           137:         data[size++] = myctlq;         /* quote it if doing repeat counts. */
        !           138: 
        !           139:     if ((ebqflg) && (a7 == ebq))       /* Prefix the 8th bit prefix */
        !           140:         data[size++] = myctlq;         /* if doing 8th-bit prefixes */
        !           141: 
        !           142:     data[size++] = a;                  /* Finally, insert the character */
        !           143:     data[size] = '\0';                 /* itself, and mark the end. */
        !           144: }
        !           145: 
        !           146: /* D E C O D E  --  Kermit packet decoding procedure */
        !           147: 
        !           148: /* Call with string to be decoded and an output function. */
        !           149: /* Returns 0 on success, -1 on failure (e.g. disk full).  */
        !           150: 
        !           151: decode(buf,fn) CHAR *buf; int (*fn)(); {
        !           152:     unsigned int a, a7, b8;            /* Low order 7 bits, and the 8th bit */
        !           153: 
        !           154:     rpt = 0;                           /* Initialize repeat count. */
        !           155: 
        !           156:     while ((a = *buf++) != '\0') {
        !           157:        if (rptflg) {                   /* Repeat processing? */
        !           158:            if (a == rptq) {            /* Yes, got a repeat prefix? */
        !           159:                rpt = xunchar(*buf++);  /* Yes, get the repeat count, */
        !           160:                a = *buf++;             /* and get the prefixed character. */
        !           161:            }
        !           162:        }
        !           163:        b8 = 0;                         /* Check high order "8th" bit */
        !           164:        if (ebqflg) {                   /* 8th-bit prefixing? */
        !           165:            if (a == ebq) {             /* Yes, got an 8th-bit prefix? */
        !           166:                b8 = 0200;              /* Yes, remember this, */
        !           167:                a = *buf++;             /* and get the prefixed character. */
        !           168:            }
        !           169:        }
        !           170:        if (a == ctlq) {                /* If control prefix, */
        !           171:            a  = *buf++;                /* get its operand. */
        !           172:            a7 = a & 0177;              /* Only look at low 7 bits. */
        !           173:            if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') /* Uncontrollify */
        !           174:            a = ctl(a);                 /* if in control range. */
        !           175:        }
        !           176:        a |= b8;                        /* OR in the 8th bit */
        !           177:        if (rpt == 0) rpt = 1;          /* If no repeats, then one */
        !           178: #ifdef NLCHAR
        !           179:        if (!binary) {                  /* If in text mode, */
        !           180:            if (a == CR) continue;      /* discard carriage returns, */
        !           181:            if (a == LF) a = NLCHAR;    /* convert LF to system's newline. */
        !           182:        }
        !           183: #endif
        !           184:        for (; rpt > 0; rpt--) {        /* Output the char RPT times */
        !           185:            if ((*fn)(a) < 0) return(-1); /* Send it to the output function. */
        !           186:            ffc++, tfc++;               /* Count the character */
        !           187:        }
        !           188:     }
        !           189:     return(0);
        !           190: }
        !           191: 
        !           192: 
        !           193: /*  Output functions passed to 'decode':  */
        !           194: 
        !           195: putsrv(c) char c; {    /*  Put character in server command buffer  */
        !           196:     *srvptr++ = c;
        !           197:     *srvptr = '\0';    /* Make sure buffer is null-terminated */
        !           198:     return(0);
        !           199: }
        !           200: 
        !           201: puttrm(c) char c; {     /*  Output character to console.  */
        !           202:     conoc(c);
        !           203:     return(0);
        !           204: }
        !           205: 
        !           206: putfil(c) char c; {                    /*  Output char to file. */
        !           207:     if (zchout(ZOFILE, c & fmask) < 0) {
        !           208:        czseen = 1;                     /* If write error... */
        !           209:        debug(F101,"putfil zchout write error, setting czseen","",1);
        !           210:        return(-1);
        !           211:     }
        !           212:     return(0);
        !           213: }
        !           214: 
        !           215: /*  G E T P K T -- Fill a packet data field  */
        !           216: 
        !           217: /*
        !           218:  Gets characters from the current source -- file or memory string.
        !           219:  Encodes the data into the packet, filling the packet optimally.
        !           220:  Set first = 1 when calling for the first time on a given input stream
        !           221:  (string or file).
        !           222: 
        !           223:  Uses global variables:
        !           224:  t     -- current character.
        !           225:  first -- flag: 1 to start up, 0 for input in progress, -1 for EOF.
        !           226:  next  -- next character.
        !           227:  data  -- the packet data buffer.
        !           228:  size  -- number of characters in the data buffer.
        !           229: 
        !           230: Returns the size as value of the function, and also sets global size,
        !           231: and fills (and null-terminates) the global data array.  Returns 0 upon eof.
        !           232: */
        !           233: 
        !           234: getpkt(bufmax) int bufmax; {           /* Fill one packet buffer */
        !           235:     int i, x;                          /* Loop index. */
        !           236:        
        !           237:     static char leftover[6] = { '\0', '\0', '\0', '\0', '\0', '\0' };
        !           238: 
        !           239:     if (first == 1) {          /* If first time thru...  */
        !           240:        first = 0;              /* remember, */
        !           241:        *leftover = '\0';       /* discard any interrupted leftovers, */
        !           242:        x = getchx(&t);         /* get first character of file into t, */
        !           243:        if (x == 0) {           /* watching out for null file, */
        !           244:            first = -1;
        !           245:            return(size = 0);   
        !           246:        }
        !           247:     } else if ((first == -1) && (*leftover == '\0')) /* EOF from last time? */
        !           248:         return(size = 0);
        !           249: 
        !           250:     /* Do any leftovers */
        !           251: 
        !           252:     for (size = 0; (data[size] = leftover[size]) != '\0'; size++)
        !           253:        ;
        !           254:     *leftover = '\0';
        !           255:     if (first == -1) return(size);     /* Handle final leftovers leftovers */
        !           256: 
        !           257:     /* Now fill up the rest of the packet. */
        !           258: 
        !           259:     rpt = 0;                           /* Clear out any old repeat count. */
        !           260:     while (first > -1) {               /* Until EOF... */
        !           261:        x = getchx(&next);              /* Get next character for lookahead. */
        !           262:        if (x == 0) first = -1;         /* Flag eof for next time. */
        !           263:        osize = size;                   /* Remember current position. */
        !           264:         encode(t);                     /* Encode the current character. */
        !           265:        t = next;                       /* Next is now current. */
        !           266: 
        !           267:        if (size == bufmax) {           /* If the packet is exactly full, */
        !           268: /**        debug(F101,"getpkt exact fit","",size); **/
        !           269:             return(size);              /* ... return. */
        !           270:        }
        !           271:        if (size > bufmax) {            /* If too big, save some for next. */
        !           272:            for (i = 0; (leftover[i] = data[osize+i]) != '\0'; i++)
        !           273:                ;
        !           274: /**        debug(F111,"getpkt leftover",leftover,size); **/
        !           275: /**        debug(F101," osize","",osize);               **/
        !           276:            size = osize;               /* Return truncated packet. */
        !           277:            data[size] = '\0';
        !           278:            return(size);
        !           279:        }
        !           280:     }                                  /* Otherwise, keep filling. */
        !           281:     debug(F111,"getpkt eof/eot",data,size); /* Fell thru before packet full, */
        !           282:     return(size);                 /* return partially filled last packet. */
        !           283: }
        !           284: 
        !           285: /*  G E T C H X  --  Get the next character from file (or pipe). */
        !           286:  
        !           287: /*
        !           288:  On systems like Unix, the Macintosh, etc, that use a single character
        !           289:  (NLCHAR, defined in ckcdeb.h) to separate lines in text files, and
        !           290:  when in text/ascii mode (binary == 0), this function maps the newline
        !           291:  character to CRLF.  If NLCHAR is not defined, then this mapping is
        !           292:  not done, even in text mode.
        !           293: 
        !           294:  Returns 1 on success with ch set to the character, or 0 on failure (EOF)
        !           295: */
        !           296: getchx(ch) char *ch; {                 /* Get next character */
        !           297:     int x; CHAR a;                     /* The character to return. */
        !           298:     static int b = 0;                  /* A character to remember. */
        !           299:     
        !           300:     if (b > 0) {                       /* Do we have a LF saved? */
        !           301:        b = 0;                          /* Yes, return that. */
        !           302:        *ch = LF;
        !           303:        return(1);
        !           304:     }
        !           305: 
        !           306:     if (memstr)                                /* Try to get the next character */
        !           307:        x = ((a = *memptr++) == '\0');  /* from the appropriate source, */
        !           308:     else                               /* memory or the current file. */
        !           309:        x = (zchin(ZIFILE,&a) == -1);
        !           310: 
        !           311:     if (x)
        !           312:        return(0);                      /* No more, return 0 for EOF. */
        !           313:     else {                             /* Otherwise, read the next char. */
        !           314:        ffc++, tfc++;                   /* Count it. */
        !           315:        a &= fmask;                     /* Bytesize mask. */
        !           316: #ifdef NLCHAR
        !           317:        if (!binary && (a == NLCHAR)) { /* If nl and we must do nl-CRLF */
        !           318:            b = 1;                      /* mapping, remember a linefeed, */
        !           319:            *ch = CR;                   /* and return a carriage return. */
        !           320:            return(1);
        !           321:        } else {
        !           322:            *ch = a;                    /*  General case, return the char. */
        !           323:            return(1);  
        !           324:         }
        !           325: #else
        !           326:         *ch = a;
        !           327:         return(1);     
        !           328: #endif
        !           329:     }
        !           330: }
        !           331: 
        !           332: 
        !           333: /*  C A N N E D  --  Check if current file transfer cancelled */
        !           334: 
        !           335: canned(buf) char *buf; {
        !           336:     if (*buf == 'X') cxseen = 1;
        !           337:     if (*buf == 'Z') czseen = 1;
        !           338:     debug(F101,"canned: cxseen","",cxseen);
        !           339:     debug(F101," czseen","",czseen);
        !           340:     return((czseen || cxseen) ? 1 : 0);
        !           341: }
        !           342: 
        !           343: /*  R E S E T C  --  Reset per-transaction character counters */
        !           344: resetc() {
        !           345:     tfc = tlci = tlco = 0;     /* Total file chars, line chars in & out */
        !           346: }
        !           347: 
        !           348: 
        !           349: /*  T I N I T  --  Initialize a transaction  */
        !           350: 
        !           351: tinit() {
        !           352:     xflg = 0;                          /* Reset x-packet flag */
        !           353:     memstr = 0;                                /* Reset memory-string flag */
        !           354:     memptr = NULL;                     /*  and pointer */
        !           355:     bctu = 1;                          /* Reset block check type to 1 */
        !           356:     ebq = ebqflg = 0;                  /* Reset 8th-bit quoting stuff */
        !           357:     if (savmod) {                      /* If binary file mode was saved, */
        !           358:        binary = 1;                     /*  restore it, */
        !           359:        savmod = 0;                     /*  unsave it. */
        !           360:     }
        !           361:     prvpkt = -1;                       /* Reset packet number */
        !           362:     pktnum = 0;
        !           363:     cxseen = czseen = 0;               /* Reset interrupt flags */
        !           364:     *filnam = '\0';                    /* Clear file name */
        !           365:     *sndpkt = '\0';                    /* Clear retransmission buffer */
        !           366:     if (server)                        /* If acting as server, */
        !           367:        timint = 30;                    /* Use 30 second timeout, */
        !           368: }
        !           369: 
        !           370: 
        !           371: /*  R I N I T  --  Respond to S packet  */
        !           372: 
        !           373: rinit(d) char *d; {
        !           374:     char *tp;
        !           375:     ztime(&tp);
        !           376:     tlog(F110,"Transaction begins",tp,0l); /* Make transaction log entry */
        !           377:     filcnt = 0;                                /* Init file counter */
        !           378:     spar(d);
        !           379:     ack1(rpar());
        !           380: #ifdef datageneral
        !           381:     if ((local) && (!quiet))            /* Only do this if local & not quiet */
        !           382:         consta_mt();                    /* Start the asynch read task */
        !           383: #endif
        !           384: }
        !           385: 
        !           386: /*  S I N I T  --  Make sure file exists, then send Send-Init packet */
        !           387: 
        !           388: sinit() {
        !           389:     int x; char *tp;
        !           390: 
        !           391:     filcnt = 0;
        !           392:     sndsrc = nfils;                    /* Where to look for files to send */
        !           393:     ztime(&tp);
        !           394:     tlog(F110,"Transaction begins",tp,0l); /* Make transaction log entry */
        !           395:     debug(F101,"sinit: sndsrc","",sndsrc);
        !           396:     if (sndsrc < 0) {                  /* Must expand from 'send' command */
        !           397:        nfils = zxpand(cmarg);          /* Look up literal name. */
        !           398:        if (nfils < 0) {
        !           399:            screen(SCR_EM,0,0l,"Too many files");
        !           400:            return(0);
        !           401:         } else if (nfils == 0) {       /* If none found, */
        !           402:            char xname[100];            /* convert the name. */
        !           403:            zrtol(cmarg,xname);
        !           404:            nfils = zxpand(xname);      /* Look it up again. */
        !           405:        }
        !           406:        if (nfils < 1) {                /* If no match, report error. */
        !           407:            if (server) 
        !           408:                errpkt("File not found");
        !           409:            else
        !           410:                screen(SCR_EM,0,0l,"File not found");
        !           411:            return(0);
        !           412:        }
        !           413:        x = gnfile();                   /* Position to first file. */
        !           414:        if (x < 1) {
        !           415:            if (!server) 
        !           416:                screen(SCR_EM,0,0l,"No readable file to send");
        !           417:             else
        !           418:                errpkt("No readable file to send");
        !           419:            return(0);
        !           420:        } 
        !           421:     } else if (sndsrc > 0) {           /* Command line arglist -- */
        !           422:        x = gnfile();                   /* Get the first file from it. */
        !           423:        if (x < 1) return(0);           /* (if any) */
        !           424:     } else if (sndsrc == 0) {          /* stdin or memory always exist... */
        !           425:        if ((cmarg2 != NULL) && (*cmarg2)) {
        !           426:            strcpy(filnam,cmarg2);      /* If F packet, "as" name is used */
        !           427:            cmarg2 = "";                /* if provided, */
        !           428:         } else                         /* otherwise */
        !           429:            strcpy(filnam,"stdin");     /* just use this. */
        !           430:     }
        !           431:     debug(F101,"sinit: nfils","",nfils);
        !           432:     debug(F110," filnam",filnam,0);
        !           433:     debug(F110," cmdstr",cmdstr,0);
        !           434:     ttflui();                          /* Flush input buffer. */
        !           435:     if (!local && !server) sleep(delay);
        !           436: #ifdef datageneral
        !           437:     if ((local) && (!quiet))            /* Only do this if local & not quiet */
        !           438:         consta_mt();                    /* Start the asynch read task */
        !           439: #endif
        !           440:     sipkt('S');                                /* Send the Send-Init packet. */
        !           441:     return(1);
        !           442: }
        !           443: 
        !           444: sipkt(c) char c; {                     /* Send S or I packet. */
        !           445:     CHAR *rp;
        !           446:     ttflui();                          /* Flush pending input. */
        !           447:     rp = rpar();                       /* Get parameters. */
        !           448:     spack(c,pktnum,strlen(rp),rp);
        !           449: }
        !           450: 
        !           451: /*  R C V F I L -- Receive a file  */
        !           452: 
        !           453: rcvfil() {
        !           454:     int x;
        !           455:     ffc = flci = flco = 0;             /* Init per-file counters */
        !           456:     srvptr = srvcmd;                   /* Decode file name from packet. */
        !           457:     decode(rdatap,putsrv);
        !           458:     if (*srvcmd == '\0')               /* Watch out for null F packet. */
        !           459:        strcpy(srvcmd,"NONAME");
        !           460:     screen(SCR_FN,0,0l,srvcmd);                /* Put it on screen */
        !           461:     tlog(F110,"Receiving",srvcmd,0l);  /* Transaction log entry */
        !           462:     if (cmarg2 != NULL) {               /* Check for alternate name */
        !           463:         if (*cmarg2 != '\0') {
        !           464:             strcpy(srvcmd,cmarg2);     /* Got one, use it. */
        !           465:            *cmarg2 = '\0';
        !           466:         }
        !           467:     }
        !           468:     x = openo(srvcmd,filnam);          /* Try to open it */
        !           469:     if (x) {
        !           470:        tlog(F110," as",filnam,0l);
        !           471:        screen(SCR_AN,0,0l,filnam);
        !           472:        intmsg(++filcnt);
        !           473: #ifdef datageneral
        !           474: /* Need to turn on multi-tasking console interrupt task here, since multiple */
        !           475: /* files may be received. */
        !           476:         if ((local) && (!quiet))        /* Only do this if local & not quiet */
        !           477:             consta_mt();                /* Start the asynch read task */
        !           478: #endif
        !           479:     } else {
        !           480:         tlog(F110,"Failure to open",filnam,0l);
        !           481:        screen(SCR_EM,0,0l,"Can't open file");
        !           482:     }
        !           483:     return(x);                         /* Pass on return code from openo */
        !           484: }
        !           485: 
        !           486: /*  R E O F  --  Receive End Of File  */
        !           487: 
        !           488: reof() {
        !           489:     int x;
        !           490:     if (cxseen == 0) cxseen = (*rdatap == 'D');        /* Got discard directive? */
        !           491:     x = clsof(cxseen | czseen);
        !           492:     if (cxseen || czseen) {
        !           493:        tlog(F100," *** Discarding","",0l);
        !           494:        cxseen = 0;
        !           495:     } else
        !           496:        fstats();
        !           497:     return(x);
        !           498: }
        !           499: 
        !           500: 
        !           501: /*  R E O T  --  Receive End Of Transaction  */
        !           502: 
        !           503: reot() {
        !           504:     cxseen = czseen = 0;               /* Reset interruption flags */
        !           505:     tstats();
        !           506: }
        !           507: 
        !           508: /*  S F I L E -- Send File header or teXt header packet  */
        !           509: 
        !           510: /*  Call with x nonzero for X packet, zero for F packet  */
        !           511: /*  Returns 1 on success, 0 on failure                   */
        !           512: 
        !           513: sfile(x) int x; {
        !           514:     char pktnam[100];                  /* Local copy of name */
        !           515:     char *s;
        !           516: 
        !           517:     if (x == 0) {                      /* F-Packet setup */
        !           518: 
        !           519:        if (*cmarg2 != '\0') {          /* If we have a send-as name, */
        !           520:            strcpy(pktnam,cmarg2);      /* copy it literally, */
        !           521:            cmarg2 = "";                /* and blank it out for next time. */
        !           522:        } else {                        /* Otherwise use actual file name: */
        !           523:            if (fncnv) {                /* If converting names, */
        !           524:                zltor(filnam,pktnam);   /* convert it to common form, */
        !           525:            } else {                    /* otherwise, */
        !           526:                strcpy(pktnam,filnam);  /* copy it literally. */
        !           527:             }
        !           528:        }
        !           529:        debug(F110,"sfile",filnam,0);   /* Log debugging info */
        !           530:        debug(F110," pktnam",pktnam,0);
        !           531:        if (openi(filnam) == 0)         /* Try to open the file */
        !           532:            return(0);          
        !           533:        s = pktnam;                     /* Name for packet data field */
        !           534: 
        !           535:     } else {                           /* X-packet setup */
        !           536: 
        !           537:        debug(F110,"sxpack",cmdstr,0);  /* Log debugging info */
        !           538:        s = cmdstr;                     /* Name for data field */
        !           539:     }
        !           540: 
        !           541:     flci = flco = ffc = 0;             /* Init counters, etc. */
        !           542:     encstr(s);                         /* Encode the name into data[]. */
        !           543:     nxtpkt(&pktnum);                   /* Increment the packet number */
        !           544:     spack(x ? 'X' : 'F', pktnum, size, data); /* Send the F or X packet */
        !           545: 
        !           546:     if (x == 0) {                      /* Display for F packet */
        !           547:        if (displa) {                   /* Screen */
        !           548:            screen(SCR_FN,'F',(long)pktnum,filnam);
        !           549:            screen(SCR_AN,0,0l,pktnam);
        !           550:            screen(SCR_FS,0,(long)fsize,"");
        !           551:        }
        !           552:        tlog(F110,"Sending",filnam,0l); /* Transaction log entry */
        !           553:        tlog(F110," as",pktnam,0l);
        !           554: 
        !           555:     } else {                           /* Display for X-packet */
        !           556: 
        !           557:        screen(SCR_XD,'X',(long)pktnum,cmdstr); /* Screen */
        !           558:        tlog(F110,"Sending from:",cmdstr,0l);   /* Transaction log */
        !           559:     }
        !           560:     intmsg(++filcnt);                  /* Count file, give interrupt msg */
        !           561:     first = 1;                         /* Init file character lookahead. */
        !           562:     return(1);
        !           563: }
        !           564: 
        !           565: /*  S D A T A -- Send a data packet */
        !           566: 
        !           567: /*  Return -1 if no data to send, else send packet and return length  */
        !           568: 
        !           569: sdata() {
        !           570:     int len;
        !           571:     if (cxseen || czseen) return(-1);  /* If interrupted, done. */
        !           572:     if ((len = getpkt(spsiz-bctu-3)) == 0) /* Done if no data. */
        !           573:        return(-1);
        !           574:     nxtpkt(&pktnum);                   /* Increment the packet number */
        !           575:     spack('D',pktnum,len,data);                /* Send the packet */
        !           576:     return(len);
        !           577: }
        !           578: 
        !           579: 
        !           580: /*  S E O F -- Send an End-Of-File packet */
        !           581: 
        !           582: /*  Call with a string pointer to character to put in the data field, */
        !           583: /*  or else a null pointer or "" for no data.  */
        !           584: 
        !           585: seof(s) char *s; {
        !           586:     nxtpkt(&pktnum);                   /* Increment the packet number */
        !           587:     if ((s != NULL) && (*s != '\0')) {
        !           588:        spack('Z',pktnum,1,s);
        !           589:        tlog(F100," *** interrupted, sending discard request","",0l);
        !           590:     } else {
        !           591:        spack('Z',pktnum,0,"");
        !           592:        fstats();
        !           593:     }
        !           594: }
        !           595: 
        !           596: 
        !           597: /*  S E O T -- Send an End-Of-Transaction packet */
        !           598: 
        !           599: seot() {
        !           600:     nxtpkt(&pktnum);                   /* Increment the packet number */
        !           601:     spack('B',pktnum,0,"");            /* Send the EOT packet */
        !           602:     cxseen = czseen = 0;               /* Reset interruption flags */
        !           603:     tstats();                          /* Log timing info */
        !           604: }
        !           605: 
        !           606: /*   R P A R -- Fill the data array with my send-init parameters  */
        !           607: 
        !           608: CHAR *
        !           609: rpar() {
        !           610:     data[1] = tochar(rpsiz);           /* Biggest packet I can receive */
        !           611:     data[2] = tochar(rtimo);           /* When I want to be timed out */
        !           612:     data[3] = tochar(mypadn);          /* How much padding I need (none) */
        !           613:     data[4] = ctl(mypadc);             /* Padding character I want */
        !           614:     data[5] = tochar(eol);             /* End-Of-Line character I want */
        !           615:     data[6] = '#';                     /* Control-Quote character I send */
        !           616:     switch (rqf) {                     /* 8th-bit prefix */
        !           617:        case -1:
        !           618:        case  1: if (parity) ebq = sq = '&'; break;
        !           619:        case  0:
        !           620:        case  2: break;
        !           621:     }
        !           622:     data[7] = sq;
        !           623:     data[8] = bctr + '0';              /* Block check type */
        !           624:     if (rptflg)                                /* Run length encoding */
        !           625:        data[9] = rptq;                 /* If receiving, agree. */
        !           626:     else
        !           627:        data[9] = '~';          
        !           628: 
        !           629:     data[10] = tochar(atcapr?atcapb:0 | lpcapr?lpcapb:0 | swcapr?swcapb:0);
        !           630:     data[capas+1] = tochar(swcapr ? wsize : 0);        /* Window size */
        !           631: 
        !           632:     rpsiz = urpsiz;                    /* Long packets ... */
        !           633:     data[capas+2] = tochar(rpsiz / 95);        /* Long packet size, big part */
        !           634:     data[capas+3] = tochar(rpsiz % 95);        /* Long packet size, little part */
        !           635:     data[capas+4] = '\0';              /* Terminate the init string */
        !           636:     if (deblog) {
        !           637:        debug(F110,"rpar",data+1,0);
        !           638:        rdebu(capas+2);    
        !           639:     }
        !           640:     return(data+1);                    /* Return pointer to string. */
        !           641: }
        !           642: 
        !           643: spar(s) char *s; {                     /* Set parameters */
        !           644:     int x, lpsiz;
        !           645: 
        !           646:     s--;                               /* Line up with field numbers. */
        !           647: 
        !           648: debug(F101,"spar rln","",rln);
        !           649: 
        !           650: /* Limit on size of outbound packets */
        !           651:     x = (rln >= 1) ? xunchar(s[1]) : 80;
        !           652:     lpsiz = spsiz;                     /* Remember what they SET. */
        !           653:     if (spsizf) {                      /* SET-command override? */
        !           654:        if (x < spsiz) spsiz = x;       /* Ignore LEN unless smaller */
        !           655:     } else {                           /* otherwise */
        !           656:        spsiz = (x < 10) ? 80 : x;      /* believe them if reasonable */
        !           657:     }
        !           658: 
        !           659: /* Timeout on inbound packets */
        !           660:     if (!timef) {                      /* Only if not SET-cmd override */
        !           661:        x = (rln >= 2) ? xunchar(s[2]) : 5;
        !           662:        timint = (x < 0) ? 5 : x;
        !           663:     }
        !           664: 
        !           665: /* Outbound Padding */
        !           666:     npad = 0; padch = '\0';
        !           667:     if (rln >= 3) {
        !           668:        npad = xunchar(s[3]);
        !           669:        if (rln >= 4) padch = ctl(s[4]); else padch = 0;
        !           670:     }
        !           671: 
        !           672: /* Outbound Packet Terminator */
        !           673:     seol = (rln >= 5) ? xunchar(s[5]) : '\r';
        !           674:     if ((seol < 2) || (seol > 31)) seol = '\r';
        !           675: 
        !           676: /* Control prefix */
        !           677:     x = (rln >= 6) ? s[6] : '#';
        !           678:     myctlq = ((x > 32 && x < 63) || (x > 95 && x < 127)) ? x : '#';
        !           679: 
        !           680: /* 8th-bit prefix */
        !           681:     rq = (rln >= 7) ? s[7] : 0;
        !           682:     if (rq == 'Y') rqf = 1;
        !           683:       else if ((rq > 32 && rq < 63) || (rq > 95 && rq < 127)) rqf = 2;
        !           684:         else rqf = 0;
        !           685:     switch (rqf) {
        !           686:        case 0: ebqflg = 0; break;
        !           687:        case 1: if (parity) { ebqflg = 1; ebq = '&'; } break;
        !           688:        case 2: if (ebqflg = (ebq == sq || sq == 'Y')) ebq = rq;
        !           689:     }
        !           690: 
        !           691: /* Block check */
        !           692:     x = 1;
        !           693:     if (rln >= 8) {
        !           694:        x = s[8] - '0';
        !           695:        if ((x < 1) || (x > 3)) x = 1;
        !           696:     }
        !           697:     bctr = x;
        !           698: 
        !           699: /* Repeat prefix */
        !           700:     if (rln >= 9) {
        !           701:        rptq = s[9]; 
        !           702:        rptflg = ((rptq > 32 && rptq < 63) || (rptq > 95 && rptq < 127));
        !           703:     } else rptflg = 0;
        !           704: 
        !           705: /* Capabilities */
        !           706:     atcapu = lpcapu = swcapu = 0;
        !           707:     if (rln >= 10) {
        !           708:         x = xunchar(s[10]);
        !           709:         atcapu = (x & atcapb) && atcapr;
        !           710:        lpcapu = (x & lpcapb) && lpcapr;
        !           711:        swcapu = (x & swcapb) && swcapb;
        !           712:        for (capas = 10; (xunchar(s[capas]) & 1) && (rln >= capas); capas++) ;
        !           713:     }
        !           714: 
        !           715: /* Long Packets */
        !           716:     if (lpcapu) {
        !           717:         if (rln > capas+2) {
        !           718:            x = xunchar(s[capas+2]) * 95 + xunchar(s[capas+3]);
        !           719:            if (spsizf) {               /* If overriding negotiations */
        !           720:                spsiz = (x < lpsiz) ? x : lpsiz; /* do this, */
        !           721:            } else {                             /* otherwise */
        !           722:                spsiz = (x > MAXSP) ? MAXSP : x; /* do this. */
        !           723:            }
        !           724:            if (spsiz < 10) spsiz = 80; /* Be defensive... */
        !           725:        }
        !           726:     }
        !           727: 
        !           728: /* Sliding Windows */
        !           729:     if (swcapu) {
        !           730:         if (rln > capas+1) {
        !           731:            x = xunchar(s[capas+1]);
        !           732:            wsize = x > MAXWS ? MAXWS : x;
        !           733:        }
        !           734:        else wsize = 1;
        !           735:     }
        !           736:     if (deblog) sdebu(rln);            /* Record parameters in debug log */
        !           737: }
        !           738: 
        !           739: /*  G N F I L E  --  Get the next file name from a file group.  */
        !           740: 
        !           741: /*  Returns 1 if there's a next file, 0 otherwise  */
        !           742: 
        !           743: gnfile() {
        !           744:     int x; long y;
        !           745: #ifdef datageneral
        !           746:     int dgfiles = 0;                   /* Number of files expanded */
        !           747:     static int dgnfils = -1;           /* Saved nfils value */
        !           748: #endif
        !           749: 
        !           750: /* If file group interruption (C-Z) occured, fail.  */
        !           751: 
        !           752:     debug(F101,"gnfile: czseen","",czseen);
        !           753: 
        !           754:     if (czseen) {
        !           755:        tlog(F100,"Transaction cancelled","",0l);
        !           756:        return(0);
        !           757:     }
        !           758: 
        !           759: /* If input was stdin or memory string, there is no next file.  */
        !           760: 
        !           761:     if (sndsrc == 0) return(0);
        !           762: 
        !           763: /* If file list comes from command line args, get the next list element. */
        !           764: 
        !           765:     y = -1;
        !           766:     while (y < 0) {                    /* Keep trying till we get one... */
        !           767: 
        !           768:        if (sndsrc > 0) {
        !           769:            if (nfils-- > 0) {
        !           770: 
        !           771: #ifdef datageneral
        !           772: /* The DG does not internally expand the file names when a string of */
        !           773: /* filenames is given. So we must in this case. */
        !           774:                 if (dgnfils == -1) {   /* This is executed first time only! */
        !           775:                     strcpy(filnam,*cmlist++);
        !           776:                    dgfiles = zxpand(filnam); /* Expand the string */
        !           777:                     debug(F111,"gnfile:cmlist filnam (x-init)",filnam,dgfiles);
        !           778:                     dgnfils = nfils + 1;
        !           779:                     debug(F111,"gnfile:cmlist filnam (x-init)",filnam,dgnfils);
        !           780:                 } 
        !           781:                 x = znext(filnam);
        !           782:                 if (x > 0) {      /* Get the next file in the expanded list */
        !           783:                    debug(F111,"gnfile znext: filnam (exp-x=)",filnam,x);
        !           784:                     nfils = dgnfils;     /* The virtual number of files left */
        !           785:                  }
        !           786:                 if (x == 0) {     /* Expand the next command argument */
        !           787:                    if (dgnfils == 1) {
        !           788:                         dgnfils = -1;   /* The last argument resets things */
        !           789:                         *filnam = '\0';
        !           790:                         debug(F101,"gnfile cmlist: nfils","",nfils);
        !           791:                         return(0);
        !           792:                    }
        !           793:                  
        !           794:                     strcpy(filnam,*cmlist++);  /* Finish expanding last arg */
        !           795:                    dgfiles = zxpand(filnam); /* Expand the string */
        !           796:                     debug(F111,"gnfile: cmlist filnam (exp)",filnam,dgnfils);
        !           797:                    x = znext(filnam);
        !           798:                    debug(F111,"gnfile znext: filnam (exp)",filnam,x);
        !           799:                    nfils = dgnfils--;
        !           800:                } 
        !           801: #else
        !           802:                strcpy(filnam,*cmlist++);
        !           803:                debug(F111,"gnfile: cmlist filnam",filnam,nfils);
        !           804: #endif
        !           805:            } else {
        !           806:                *filnam = '\0';
        !           807:                debug(F101,"gnfile cmlist: nfils","",nfils);
        !           808:                return(0);
        !           809:            }
        !           810:        }
        !           811: 
        !           812: /* Otherwise, step to next element of internal wildcard expansion list. */
        !           813: 
        !           814:        if (sndsrc < 0) {
        !           815:            x = znext(filnam);
        !           816:            debug(F111,"gnfile znext: filnam",filnam,x);
        !           817:            if (x == 0) return(0);
        !           818:        }
        !           819: 
        !           820: /* Get here with a filename. */
        !           821: 
        !           822:        y = zchki(filnam);              /* Check if file readable */
        !           823:        if (y < 0) {
        !           824:            debug(F110,"gnfile skipping:",filnam,0);
        !           825:            tlog(F111,filnam,"not sent, reason",(long)y);
        !           826:            screen(SCR_ST,ST_SKIP,0l,filnam);
        !           827:        } else fsize = y;
        !           828:     }          
        !           829:     return(1);
        !           830: }
        !           831: 
        !           832: /*  O P E N I  --  Open an existing file for input  */
        !           833: 
        !           834: openi(name) char *name; {
        !           835:     int x, filno;
        !           836:     if (memstr) return(1);             /* Just return if file is memory. */
        !           837: 
        !           838:     debug(F110,"openi",name,0);
        !           839:     debug(F101," sndsrc","",sndsrc);
        !           840: 
        !           841:     filno = (sndsrc == 0) ? ZSTDIO : ZIFILE;    /* ... */
        !           842: 
        !           843:     debug(F101," file number","",filno);
        !           844: 
        !           845:     if (zopeni(filno,name)) {          /* Otherwise, try to open it. */
        !           846:        debug(F110," ok",name,0);
        !           847:        return(1);
        !           848:     } else {                           /* If not found, */
        !           849:        char xname[100];                /* convert the name */
        !           850:        zrtol(name,xname);              /* to local form and then */
        !           851:        x = zopeni(filno,xname);        /* try opening it again. */
        !           852:        debug(F101," zopeni","",x);
        !           853:        if (x) {
        !           854:            debug(F110," ok",xname,0);
        !           855:            return(1);                  /* It worked. */
        !           856:         } else {
        !           857:            screen(SCR_EM,0,0l,"Can't open file");  /* It didn't work. */
        !           858:            tlog(F110,xname,"could not be opened",0l);
        !           859:            debug(F110," openi failed",xname,0);
        !           860:            return(0);
        !           861:         }
        !           862:     }
        !           863: }
        !           864: 
        !           865: /*  O P E N O  --  Open a new file for output.  */
        !           866: 
        !           867: /*  Returns actual name under which the file was opened in string 'name2'. */
        !           868: 
        !           869: openo(name,name2) char *name, *name2; {
        !           870:     char xname[100], *xp;
        !           871: 
        !           872:     if (stdouf)                                /* Receiving to stdout? */
        !           873:        return(zopeno(ZSTDIO,""));
        !           874: 
        !           875:     debug(F110,"openo: name",name,0);
        !           876: 
        !           877:     if (cxseen || czseen) {            /* If interrupted, get out before */
        !           878:        debug(F100," open cancelled","",0); /* destroying existing file. */
        !           879:        return(1);                      /* Pretend to succeed. */
        !           880:     }
        !           881:     xp = xname;                                /* OK to proceed. */
        !           882:     if (fncnv)                         /* If desired, */
        !           883:        zrtol(name,xp);                 /* convert name to local form */
        !           884:     else                               /* otherwise, */
        !           885:        strcpy(xname,name);             /* use it literally */
        !           886: 
        !           887:     debug(F110,"openo: xname",xname,0);
        !           888: 
        !           889:     if (warn) {                                /* File collision avoidance? */
        !           890:        if (zchki(xname) != -1) {       /* Yes, file exists? */
        !           891:            znewn(xname,&xp);           /* Yes, make new name. */
        !           892:            strcpy(xname,xp);
        !           893:            debug(F110," exists, new name ",xname,0);
        !           894:         }
        !           895:     }
        !           896:     if (zopeno(ZOFILE,xname) == 0) {   /* Try to open the file */
        !           897:        debug(F110,"openo failed",xname,0);
        !           898:        tlog(F110,"Failure to open",xname,0l);
        !           899:        return(0);
        !           900:     } else {
        !           901:        strcpy(name2,xname);
        !           902:        debug(F110,"openo ok, name2",name2,0);
        !           903:        return(1);
        !           904:     }
        !           905: }
        !           906: 
        !           907: /*  O P E N T  --  Open the terminal for output, in place of a file  */
        !           908: 
        !           909: opent() {
        !           910:     ffc = tfc = 0;
        !           911:     return(zopeno(ZCTERM,""));
        !           912: }
        !           913: 
        !           914: /*  C L S I F  --  Close the current input file. */
        !           915: 
        !           916: clsif() {
        !           917: #ifdef datageneral
        !           918:     if ((local) && (!quiet))    /* Only do this if local & not quiet */
        !           919:         if (nfils < 1)          /* More files to send ... leave it on! */
        !           920:             connoi_mt();
        !           921: #endif
        !           922:     if (memstr) {                      /* If input was memory string, */
        !           923:        memstr = 0;                     /* indicate no more. */
        !           924:     } else zclose(ZIFILE);             /* else close input file. */
        !           925: 
        !           926:     if (czseen || cxseen) 
        !           927:        screen(SCR_ST,ST_DISC,0l,"");
        !           928:     else
        !           929:        screen(SCR_ST,ST_OK,0l,"");
        !           930:     cxseen = hcflg = 0;                        /* Reset flags, */
        !           931:     *filnam = '\0';                    /* and current file name */
        !           932: }
        !           933: 
        !           934: 
        !           935: /*  C L S O F  --  Close an output file.  */
        !           936: 
        !           937: /*  Call with disp != 0 if file is to be discarded.  */
        !           938: /*  Returns -1 upon failure to close, 0 or greater on success. */
        !           939: 
        !           940: clsof(disp) int disp; {
        !           941:     int x;
        !           942: #ifdef datageneral
        !           943:     if ((local) && (!quiet))    /* Only do this if local & not quiet */
        !           944:         connoi_mt();
        !           945: #endif
        !           946:     if ((x = zclose(ZOFILE)) < 0) {    /* Try to close the file */
        !           947:        tlog(F100,"Failure to close",filnam,0l);
        !           948:        screen(SCR_ST,ST_ERR,0l,"");
        !           949:     } else if (disp && (keep == 0)) {  /* Delete it if interrupted, */
        !           950:        if (*filnam) zdelet(filnam);    /* and not keeping incomplete files */
        !           951:        debug(F100,"Discarded","",0);
        !           952:        tlog(F100,"Discarded","",0l);
        !           953:        screen(SCR_ST,ST_DISC,0l,"");
        !           954:     } else {                           /* Nothing wrong, just keep it */
        !           955:        debug(F100,"Closed","",0);      /* and give comforting messages. */
        !           956:        screen(SCR_ST,ST_OK,0l,"");
        !           957:     }
        !           958:     *filnam = '\0';                    /* Zero the current file name. */
        !           959:     return(x);                         /* Send back zclose() return code. */
        !           960: }
        !           961: 
        !           962: /*  S N D H L P  --  Routine to send builtin help  */
        !           963: 
        !           964: sndhlp() {
        !           965:     nfils = 0;                         /* No files, no lists. */
        !           966:     xflg = 1;                          /* Flag we must send X packet. */
        !           967:     strcpy(cmdstr,"help text");                /* Data for X packet. */
        !           968:     first = 1;                         /* Init getchx lookahead */
        !           969:     memstr = 1;                                /* Just set the flag. */
        !           970:     memptr = hlptxt;                   /* And the pointer. */
        !           971:     if (binary) {                      /* If file mode is binary, */
        !           972:        binary = 0;                     /*  turn it back to text for this, */
        !           973:        savmod = 1;                     /*  remember to restore it later. */
        !           974:     }
        !           975:     return(sinit());
        !           976: }
        !           977: 
        !           978: 
        !           979: /*  C W D  --  Change current working directory  */
        !           980: 
        !           981: /*
        !           982:  String passed has first byte as length of directory name, rest of string
        !           983:  is name.  Fails if can't connect, else ACKs (with name) and succeeds. 
        !           984: */
        !           985: 
        !           986: cwd(vdir) char *vdir; {
        !           987:     char *cdd, *zgtdir();
        !           988:     vdir[xunchar(*vdir) + 1] = '\0';   /* End with a null */
        !           989:     if (zchdir(vdir+1)) {
        !           990:        cdd = zgtdir();                 /* Get new working directory. */
        !           991:        encstr(cdd);
        !           992:        ack1(data);
        !           993:        tlog(F110,"Changed directory to",cdd,0l);
        !           994:        return(1)        !           995:     } else {
        !           996:        tlog(F110,"Failed to change directory to",vdir+1,0l);
        !           997:        return(0);
        !           998:     }
        !           999: }
        !          1000: 
        !          1001: 
        !          1002: /*  S Y S C M D  --  Do a system command  */
        !          1003: 
        !          1004: /*  Command string is formed by concatenating the two arguments.  */
        !          1005: 
        !          1006: syscmd(prefix,suffix) char *prefix, *suffix; {
        !          1007:     char *cp;
        !          1008: 
        !          1009:     if (prefix == NULL || *prefix == '\0') return(0);
        !          1010: 
        !          1011: #ifdef datageneral
        !          1012: /* A kludge for now -- the real change needs to be done elsewhere... */
        !          1013:     {
        !          1014:        extern char *WHOCMD;
        !          1015:        if ((strcmp(prefix,WHOCMD) == 0) && (*suffix == 0))
        !          1016:          strcpy(suffix,"[!pids]");
        !          1017:     }
        !          1018: #endif
        !          1019:     for (cp = cmdstr; *prefix != '\0'; *cp++ = *prefix++) ;
        !          1020:     while (*cp++ = *suffix++) ;
        !          1021: 
        !          1022:     debug(F110,"syscmd",cmdstr,0);
        !          1023:     if (zopeni(ZSYSFN,cmdstr) > 0) {
        !          1024:        debug(F100,"syscmd zopeni ok",cmdstr,0);
        !          1025:        nfils = sndsrc = 0;             /* Flag that input from stdin */
        !          1026:        xflg = hcflg = 1;               /* And special flags for pipe */
        !          1027:        if (binary) {                   /* If file mode is binary, */
        !          1028:            binary = 0;                 /*  turn it back to text for this, */
        !          1029:            savmod = 1;                 /*  remember to restore it later. */
        !          1030:        }
        !          1031:        return (sinit());               /* Send S packet */
        !          1032:     } else {
        !          1033:        debug(F100,"syscmd zopeni failed",cmdstr,0);
        !          1034:        return(0);
        !          1035:     }
        !          1036: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.