Annotation of coherent/e/bin/ckermit/ckuusx.c, revision 1.1

1.1     ! root        1: /*  C K U U S X --  "User Interface" common functions. */
        !             2: 
        !             3: /*
        !             4:   Author: Frank da Cruz ([email protected], [email protected]),
        !             5:   Columbia University Center for Computing Activities.
        !             6:   First released January 1985.
        !             7:   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
        !             8:   York.  Permission is granted to any individual or institution to use this
        !             9:   software as long as it is not sold for profit.  This copyright notice must be
        !            10:   retained.  This software may not be included in commercial products without
        !            11:   written permission of Columbia University.
        !            12: */
        !            13: 
        !            14: /*
        !            15:   This module contains user interface functions needed by both the interactive
        !            16:   user interface and the command-line-only user interface.
        !            17: */
        !            18: 
        !            19: /* Includes */
        !            20: 
        !            21: #include "ckcdeb.h"
        !            22: #include "ckcasc.h"
        !            23: #include "ckcker.h"
        !            24: #include "ckuusr.h"
        !            25: #ifndef WINTCP
        !            26: #include <signal.h>
        !            27: #endif /* WINTCP */
        !            28: 
        !            29: #ifdef VMS
        !            30: #ifdef WINTCP
        !            31: #include <descrip.h>
        !            32: #include <ssdef.h>
        !            33: #include <stsdef.h>
        !            34: #include <signal.h>
        !            35: #else
        !            36: #include <descrip.h>
        !            37: #include <ssdef.h>
        !            38: #include <stsdef.h>
        !            39: #endif /* WINTCP */
        !            40: #endif /* VMS */
        !            41: 
        !            42: /* Used internally */
        !            43: _PROTOTYP( VOID screenc, (int, char, long, char *) );
        !            44: static int ft_win = 0;  /* Fullscreen file transfer display window is active */
        !            45: 
        !            46: /* Variables declared here */
        !            47: 
        !            48: int fdispla = XYFD_R;                  /* File transfer display type */
        !            49: int tt_crd = 0;                                /* Carriage return display */
        !            50: 
        !            51: #ifdef DEBUG
        !            52: char debfil[50];                       /* Debugging log file name */
        !            53: #endif /* DEBUG */
        !            54: 
        !            55: #ifdef TLOG
        !            56: char trafil[50];                       /* Transaction log file name */
        !            57: #endif /* TLOG */
        !            58: 
        !            59: char pktfil[50];                       /* Packet log file name */
        !            60: char sesfil[50];                       /* Session log file name */
        !            61: 
        !            62: #ifndef NOFRILLS
        !            63: char optbuf[100];                      /* Options for MAIL or REMOTE PRINT */
        !            64: #endif /* NOFRILLS */
        !            65: char cmdstr[256];                      /* Place to build generic command */
        !            66: 
        !            67: char fspec[FSPECL];                    /* Filename string for \v(filespec) */
        !            68: 
        !            69: /*  C C N T A B  --  Names of ASCII control characters 0-31 */
        !            70: 
        !            71: char *ccntab[] = { "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
        !            72:  "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
        !            73:  "DLE", "DC1/XON", "DC2", "DC3/XOFF", "DC4", "NAK", "SYN", "ETB", "CAN",
        !            74:  "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
        !            75: };
        !            76: 
        !            77: int success = 1,                       /* Command success/failure flag */
        !            78: 
        !            79: #ifndef NOSPL
        !            80:     cmdlvl = 0,                                /* Command level */
        !            81: #endif /* NOSPL */
        !            82:     action,                            /* Action selected on command line*/
        !            83:     sessft = 0,                                /* Session log file type, 0 = text */
        !            84:     pflag = 1,                         /* Print prompt */
        !            85:     msgflg = 1;                                /* Print informational messages */
        !            86: 
        !            87: #ifndef NOMSEND                                /* Multiple SEND */
        !            88: char *msfiles[MSENDMAX];
        !            89: #endif /* NOMSEND */
        !            90: 
        !            91: /* External variables */
        !            92: 
        !            93: #ifndef NODIAL
        !            94: extern FILE * dialfd;                  /* Dialing directory */
        !            95: #endif /* NODIAL */
        !            96: 
        !            97: extern int local, quiet, binary, bctu, rptflg, ebqflg, network, server,
        !            98:   what, spsiz, urpsiz, wmax, czseen, cxseen, winlo, displa, timint, parity,
        !            99:   npad, ebq, ebqflg, bctr, rptq, atcapu, lpcapu, swcapu, wslotn, wslotr, rtimo,
        !           100:   mypadn, sq, capas, rpsiz, tsecs, dfloc, tralog, pktlog, seslog, lscapu,
        !           101:   xitsta, escape, tlevel, bgset, backgrd, wslots, suspend, srvdis,
        !           102:   spackets, spktl, rpktl, retrans, wcur, numerrs, fsecs;
        !           103: 
        !           104: #ifdef datageneral                     /* 2/12/92 ENH */
        !           105: #include <sysid.h>
        !           106: extern int con_reads_mt, conint_ch, conint_avl;
        !           107: #endif /* datageneral */
        !           108: 
        !           109: extern long speed, filcnt, ffc, tfc, rptn, fsize;
        !           110: 
        !           111: extern CHAR *rdatap, padch, seol, ctlq, mypadc, eol;
        !           112: 
        !           113: extern char ttname[], *dftty, *cmarg, **cmlist, *versio, myhost[];
        !           114: #ifndef NOICP
        !           115: #ifdef DCMDBUF
        !           116: extern char *cmdbuf;                   /* Command buffer */
        !           117: #else
        !           118: extern char cmdbuf[];                  /* Command buffer */
        !           119: #endif /* DCMDBUF */
        !           120: #endif /* NOICP */
        !           121: 
        !           122: #ifndef NOCCTRAP
        !           123: #include <setjmp.h>                    /* Control-C trap */
        !           124: jmp_buf cmjbuf;
        !           125: #endif /* NOCCTRAP */
        !           126: 
        !           127: 
        !           128: /*  P A R N A M  --  Return parity name */
        !           129: 
        !           130: char *
        !           131: #ifdef CK_ANSIC
        !           132: parnam(char c)
        !           133: #else
        !           134: parnam(c) char c;
        !           135: #endif /* CK_ANSIC */
        !           136: /* parnam */ {
        !           137:     switch (c) {
        !           138:        case 'e': return("even");
        !           139:        case 'o': return("odd");
        !           140:        case 'm': return("mark");
        !           141:        case 's': return("space");
        !           142:        case 0:   return("none");
        !           143:        default:  return("invalid");
        !           144:     }
        !           145: }
        !           146: 
        !           147: /*  S H O M D M  --  Show modem signals  */
        !           148: 
        !           149: VOID
        !           150: shomdm() {
        !           151: /*
        !           152:   Note use of "\r\n" to make sure this report prints right, even when
        !           153:   called during CONNECT mode.
        !           154: */
        !           155:     int y;
        !           156:     y = ttgmdm();
        !           157:     switch (y) {
        !           158:       case -3: printf(
        !           159:                 "Modem signals unavailable in this version of Kermit\r\n");
        !           160:               break;
        !           161:       case -2: printf("No modem control for this device\r\n"); break;
        !           162:       case -1: printf("Modem signals unavailable\r\n"); break;
        !           163:       default:
        !           164: #ifndef MAC
        !           165:         printf(
        !           166:          " Carrier Detect      (CD):  %s\r\n",(y & BM_DCD) ? "On": "Off");
        !           167:        printf(
        !           168:           " Dataset Ready       (DSR): %s\r\n",(y & BM_DSR) ? "On": "Off");
        !           169: #endif /* MAC */
        !           170:        printf(
        !           171:           " Clear To Send       (CTS): %s\r\n",(y & BM_CTS) ? "On": "Off");
        !           172: #ifndef MAC
        !           173:         printf(
        !           174:           " Ring Indicator      (RI):  %s\r\n",(y & BM_RNG) ? "On": "Off");
        !           175: #endif /* MAC */
        !           176:         printf(
        !           177:           " Data Terminal Ready (DTR): %s\r\n",(y & BM_DTR) ? "On": "Off");
        !           178: #ifndef MAC
        !           179:         printf(
        !           180:           " Request to Send     (RTS): %s\r\n",(y & BM_RTS) ? "On": "Off");
        !           181: #endif /* MAC */
        !           182:     }
        !           183: }
        !           184: 
        !           185: /*  S D E B U  -- Record spar results in debugging log  */
        !           186: 
        !           187: VOID
        !           188: sdebu(len) int len; {
        !           189:     debug(F111,"spar: data",(char *) rdatap,len);
        !           190:     debug(F101," spsiz ","", spsiz);
        !           191:     debug(F101," timint","",timint);
        !           192:     debug(F101," npad  ","",  npad);
        !           193:     debug(F101," padch ","", padch);
        !           194:     debug(F101," seol  ","",  seol);
        !           195:     debug(F101," ctlq  ","",  ctlq);
        !           196:     debug(F101," ebq   ","",   ebq);
        !           197:     debug(F101," ebqflg","",ebqflg);
        !           198:     debug(F101," bctr  ","",  bctr);
        !           199:     debug(F101," rptq  ","",  rptq);
        !           200:     debug(F101," rptflg","",rptflg);
        !           201:     debug(F101," lscapu","",lscapu);
        !           202:     debug(F101," atcapu","",atcapu);
        !           203:     debug(F101," lpcapu","",lpcapu);
        !           204:     debug(F101," swcapu","",swcapu);
        !           205:     debug(F101," wslotn","", wslotn);
        !           206: }
        !           207: /*  R D E B U -- Debugging display of rpar() values  */
        !           208: 
        !           209: VOID
        !           210: rdebu(d,len) CHAR *d; int len; {
        !           211:     debug(F111,"rpar: data",d,len);
        !           212:     debug(F101," rpsiz ","", xunchar(d[0]));
        !           213:     debug(F101," rtimo ","", rtimo);
        !           214:     debug(F101," mypadn","",mypadn);
        !           215:     debug(F101," mypadc","",mypadc);
        !           216:     debug(F101," eol   ","",   eol);
        !           217:     debug(F101," ctlq  ","",  ctlq);
        !           218:     debug(F101," sq    ","",    sq);
        !           219:     debug(F101," ebq   ","",   ebq);
        !           220:     debug(F101," ebqflg","",ebqflg);
        !           221:     debug(F101," bctr  ","",  bctr);
        !           222:     debug(F101," rptq  ","",  d[8]);
        !           223:     debug(F101," rptflg","",rptflg);
        !           224:     debug(F101," capas ","", capas);
        !           225:     debug(F101," bits  ","",d[capas]);
        !           226:     debug(F101," lscapu","",lscapu);
        !           227:     debug(F101," atcapu","",atcapu);
        !           228:     debug(F101," lpcapu","",lpcapu);
        !           229:     debug(F101," swcapu","",swcapu);
        !           230:     debug(F101," wslotr","", wslotr);
        !           231:     debug(F101," rpsiz(extended)","",rpsiz);
        !           232: }
        !           233: 
        !           234: #ifdef COMMENT
        !           235: /*  C H K E R R  --  Decide whether to exit upon a protocol error  */
        !           236: 
        !           237: VOID
        !           238: chkerr() {
        !           239:     if (backgrd && !server) fatal("Protocol error");
        !           240: }
        !           241: #endif /* COMMENT */
        !           242: 
        !           243: /*  F A T A L  --  Fatal error message */
        !           244: 
        !           245: VOID
        !           246: fatal(msg) char *msg; {
        !           247: #ifdef VMS
        !           248: #ifndef NOICP
        !           249:     if (strncmp(msg,"%CKERMIT",8)) {
        !           250:        sprintf(cmdbuf,"%%CKERMIT-E-FATAL, %s",msg);
        !           251:        msg = cmdbuf;
        !           252:     }
        !           253: #endif /* NOICP */
        !           254:     conoll(msg);
        !           255: #else
        !           256:     screen(SCR_EM,0,0L,msg);
        !           257: #endif /* VMS */
        !           258:     debug(F110,"fatal",msg,0);
        !           259:     tlog(F110,"Fatal:",msg,0L);
        !           260:     doexit(BAD_EXIT,xitsta | 1);       /* Exit indicating failure */
        !           261: }
        !           262: 
        !           263: /*  B L D L E N  --  Make length-encoded copy of string  */
        !           264: 
        !           265: char *
        !           266: bldlen(str,dest) char *str, *dest; {
        !           267:     int len;
        !           268:     len = (int)strlen(str);
        !           269:     *dest = tochar(len);
        !           270:     strcpy(dest+1,str);
        !           271:     return(dest+len+1);
        !           272: }
        !           273: 
        !           274: 
        !           275: /*  S E T G E N  --  Construct a generic command  */
        !           276: 
        !           277: CHAR
        !           278: #ifdef CK_ANSIC
        !           279: setgen(char type,char * arg1, char * arg2, char * arg3)
        !           280: #else
        !           281: setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3;
        !           282: #endif /* CK_ANSIC */
        !           283: /* setgen */ {
        !           284:     char *upstr, *cp;
        !           285: 
        !           286:     cp = cmdstr;
        !           287:     *cp++ = type;
        !           288:     *cp = NUL;
        !           289:     if (*arg1 != NUL) {
        !           290:        upstr = bldlen(arg1,cp);
        !           291:        if (*arg2 != NUL) {
        !           292:            upstr = bldlen(arg2,upstr);
        !           293:            if (*arg3 != NUL) bldlen(arg3,upstr);
        !           294:        }
        !           295:     }
        !           296:     cmarg = cmdstr;
        !           297:     debug(F110,"setgen",cmarg,0);
        !           298: 
        !           299:     return('g');
        !           300: }
        !           301: 
        !           302: #ifndef NOMSEND
        !           303: static char *mgbufp = NULL;
        !           304: 
        !           305: /*  F N P A R S E  --  */
        !           306: 
        !           307: /*
        !           308:   Argument is a character string containing one or more filespecs.
        !           309:   This function breaks the string apart into an array of pointers, one
        !           310:   to each filespec, and returns the number of filespecs.  Used by server
        !           311:   when it receives a GET command to allow it to process multiple file
        !           312:   specifications in one transaction.  Sets cmlist to point to a list of
        !           313:   file pointers, exactly as if they were command line arguments.
        !           314: 
        !           315:   This version of fnparse treats spaces as filename separators.  If your
        !           316:   operating system allows spaces in filenames, you'll need a different
        !           317:   separator.
        !           318: 
        !           319:   This version of fnparse mallocs a string buffer to contain the names.  It
        !           320:   cannot assume that the string that is pointed to by the argument is safe.
        !           321: */
        !           322: int
        !           323: fnparse(string) char *string; {
        !           324:     char *p, *s, *q;
        !           325:     int r = 0, x;                      /* Return code */
        !           326: 
        !           327:     if (mgbufp) free(mgbufp);          /* Free this from last time. */
        !           328:     mgbufp = malloc((int)strlen(string)+2);
        !           329:     if (!mgbufp) {
        !           330:        debug(F100,"fnparse malloc error","",0);
        !           331:        return(0);
        !           332:     }  
        !           333: #ifndef NOICP
        !           334: #ifndef NOSPL
        !           335:     strncpy(fspec,string,FSPECL);      /* Make copy for \v(filespec) */
        !           336: #endif /* NOSPL */
        !           337: #endif /* NOICP */
        !           338:     s = string;                                /* Input string */
        !           339:     p = q = mgbufp;                    /* Point to the copy */
        !           340:     r = 0;                             /* Initialize our return code */
        !           341:     while (*s == SP || *s == HT)       /* Skip leading spaces and tabs */
        !           342:       s++;
        !           343:     for (x = strlen(s);                        /* Strip trailing spaces */
        !           344:         (x > 1) && (s[x-1] == SP || s[x-1] == HT);
        !           345:         x--)
        !           346:       s[x-1] = NUL;
        !           347:     while (1) {                                /* Loop through rest of string */
        !           348:        if (*s == CMDQ) {               /* Backslash (quote character)? */
        !           349:            if ((x = xxesc(&s)) > -1) { /* Go interpret it. */
        !           350:                *q++ = (char) x;        /* Numeric backslash code, ok */
        !           351:            } else {                    /* Just let it quote next char */
        !           352:                s++;                    /* get past the backslash */
        !           353:                *q++ = *s++;            /* deposit next char */
        !           354:            }
        !           355:            continue;
        !           356:        } else if (*s == SP || *s == NUL) { /* Unquoted space or NUL? */
        !           357:            *q++ = NUL;                 /* End of output filename. */
        !           358:            msfiles[r] = p;             /* Add this filename to the list */
        !           359:            debug(F111,"fnparse",msfiles[r],r);
        !           360:            r++;                        /* Count it */
        !           361:            if (*s == NUL) break;       /* End of string? */
        !           362:            while (*s == SP) s++;       /* Skip repeated spaces */
        !           363:            p = q;                      /* Start of next name */
        !           364:            continue;
        !           365:        } else *q++ = *s;               /* Otherwise copy the character */
        !           366:        s++;                            /* Next input character */
        !           367:     }
        !           368:     debug(F101,"fnparse r","",r);
        !           369:     msfiles[r] = "";                   /* Put empty string at end of list */
        !           370:     cmlist = msfiles;
        !           371:     return(r);
        !           372: }
        !           373: #endif /* NOMSEND */
        !           374: 
        !           375: char *                                 /* dbchr() for DEBUG SESSION */
        !           376: dbchr(c) int c; {
        !           377:     static char s[8];
        !           378:     char *cp = s;
        !           379: 
        !           380:     c &= 0xff;
        !           381:     if (c & 0x80) {                    /* 8th bit on */
        !           382:        *cp++ = '~';
        !           383:        c &= 0x7f;
        !           384:     }
        !           385:     if (c < SP) {                      /* Control character */
        !           386:        *cp++ = '^';
        !           387:        *cp++ = ctl(c);
        !           388:     } else if (c == DEL) {
        !           389:        *cp++ = '^';
        !           390:        *cp++ = '?';
        !           391:     } else {                           /* Printing character */
        !           392:        *cp++ = c;
        !           393:     }
        !           394:     *cp = '\0';                                /* Terminate string */
        !           395:     cp = s;                            /* Return pointer to it */
        !           396:     return(cp);
        !           397: }
        !           398: 
        !           399: /*  C K H O S T  --  Get name of local host (where C-Kermit is running)  */
        !           400: 
        !           401: /*
        !           402:   Call with pointer to buffer to put hostname in, and length of buffer.
        !           403:   Copies hostname into buffer on success, puts null string in buffer on
        !           404:   failure.
        !           405: */
        !           406: #ifdef BSD44
        !           407: #define BSD4
        !           408: #undef ATTSV
        !           409: #endif /* BSD44 */
        !           410: 
        !           411: #ifdef ATTSV
        !           412: #include <sys/utsname.h>
        !           413: #endif /* ATTSV */
        !           414: 
        !           415: VOID
        !           416: ckhost(vvbuf,vvlen) char * vvbuf; int vvlen; {
        !           417:     char *g;
        !           418: #ifdef VMS
        !           419:     int x;
        !           420: #endif /* VMS */
        !           421: #ifdef ATTSV
        !           422:     struct utsname hname;
        !           423: #endif /* ATTSV */
        !           424: #ifdef datageneral
        !           425:     int ac0 = (char *) vvbuf, ac1 = -1, ac2 = 0;
        !           426: #endif /* datageneral */
        !           427: 
        !           428:     *vvbuf = NUL;
        !           429: #ifdef ATTSV
        !           430:     if (uname(&hname) > -1) strncpy(vvbuf,hname.nodename,vvlen);
        !           431: #else
        !           432: #ifdef BSD4
        !           433:     if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL;
        !           434: #else
        !           435: #ifdef VMS
        !           436:     g = getenv("SYS$NODE");
        !           437:     if (g) strncpy(vvbuf,g,vvlen);
        !           438:     x = (int)strlen(vvbuf);
        !           439:     if (x > 1 && vvbuf[x-1] == ':' && vvbuf[x-2] == ':') vvbuf[x-2] = NUL;
        !           440: #else
        !           441: #ifdef datageneral
        !           442:     if (sys($HNAME,&ac0,&ac1,&ac2) == 0) /* successful */
        !           443:         vvlen = ac2 + 1;               /* enh - have to add one */
        !           444: #else
        !           445: #ifdef OS2                             /* OS/2 */
        !           446:     g = getenv("SYSTEMNAME");
        !           447:     if (!g) g = getenv("HOSTNAME");
        !           448:     if (g) strncpy(vvbuf,g,vvlen);
        !           449: #endif /* OS2 */
        !           450: #endif /* datageneral */
        !           451: #endif /* VMS */
        !           452: #endif /* BSD4 */
        !           453: #endif /* ATTSV */
        !           454:     if (*vvbuf == NUL) {               /* If it's still empty */
        !           455:         g = getenv("HOST");            /* try this */
        !           456:         if (g) strncpy(vvbuf,g,vvlen);
        !           457:     }
        !           458:     vvbuf[vvlen-1] = NUL;              /* Make sure result is terminated. */
        !           459: }
        !           460: #ifdef BSD44
        !           461: #undef BSD4
        !           462: #define ATTSV
        !           463: #endif /* BSD44 */
        !           464: 
        !           465: 
        !           466: #ifndef NOSPL
        !           467: #define ASKMORE
        !           468: #endif /* NOSPL */
        !           469: #ifndef NOHELP
        !           470: #ifndef ASKMORE
        !           471: #define ASKMORE
        !           472: #endif /* ASKMORE */
        !           473: #endif /* NOHELP */
        !           474: 
        !           475: #ifdef ASKMORE
        !           476: /*
        !           477:   A S K M O R E  --  Poor person's "more".
        !           478:   Returns 0 if no more, 1 if more wanted.
        !           479:   Presently used by SHO MAC, SHO GLOB, SHO VAR, and HELP, so compiled out if
        !           480:   those options are also compiled out.
        !           481: */
        !           482: int
        !           483: askmore() {
        !           484:     char c; int rv;
        !           485: 
        !           486:     rv = -1;
        !           487:     while (rv < 0) {
        !           488: #ifndef OS2
        !           489:        printf("more? ");
        !           490: #ifdef UNIX
        !           491: #ifdef NOSETBUF
        !           492:        fflush(stdout);
        !           493: #endif /* NOSETBUF */
        !           494: #endif /* UNIX */
        !           495: #else
        !           496:        printf("more? (Y or space-bar for yes, N for no) ");
        !           497:        fflush(stdout);
        !           498: #endif /* OS2 */
        !           499:        c = coninc(0);
        !           500:        switch (c) {
        !           501:          /* Yes */
        !           502:          case SP: case 'y': case 'Y': case 012:  case 015:
        !           503:            printf("\015      \015");
        !           504:            rv = 1;
        !           505:            break;
        !           506:           /* No */
        !           507:          case 'n': case 'N': case 'q': case 'Q':
        !           508:            printf("\015\012");
        !           509:            rv = 0;
        !           510:            break;
        !           511:          /* Invalid answer */
        !           512:          default:
        !           513:            printf("Y or space-bar for yes, N for no\n");
        !           514:            continue;
        !           515:        }
        !           516: #ifdef OS2
        !           517:        printf("\r                                         \r");
        !           518:        fflush(stdout);
        !           519: #endif /* OS2 */
        !           520:     }
        !           521:     return(rv);
        !           522: }
        !           523: #endif /* ASKMORE */
        !           524: 
        !           525: /*  T R A P  --  Terminal interrupt handler */
        !           526: 
        !           527: SIGTYP
        !           528: trap(sig) int sig; {
        !           529: #ifdef VMS
        !           530:     int i; FILE *f;
        !           531: #endif /* VMS */
        !           532: #ifdef __EMX__
        !           533:   signal(SIGINT, SIG_ACK);
        !           534: #endif
        !           535: #ifdef GEMDOS
        !           536: /* GEM is not reentrant, no i/o from interrupt level */
        !           537:     longjmp(cmjbuf,1);                 /* Jump back to parser now! */
        !           538: #endif /* GEMDOS */
        !           539:     debug(F101,"^C trap() caught signal","",sig);
        !           540:     zclose(ZIFILE);                    /* If we were transferring a file, */
        !           541:     zclose(ZOFILE);                    /* close it. */
        !           542: #ifdef VMS
        !           543: /*
        !           544:   Fix terminal.
        !           545: */
        !           546:     if (ft_win) {                      /* If curses window open */
        !           547:        screen(SCR_CW,0,0L,"");         /* Close it */
        !           548:        conres();                       /* Restore terminal */
        !           549:        i = printf("^C...");            /* Echo ^C to standard output */
        !           550:     } else {
        !           551:        conres();
        !           552:        i = printf("^C...\n");          /* Echo ^C to standard output */
        !           553:     }
        !           554:     if (i < 1 && ferror(stdout)) {     /* If there was an error */
        !           555:        fclose(stdout);                 /* close standard output */
        !           556:        f = fopen(dftty, "w");          /* open the controlling terminal */
        !           557:        if (f) stdout = f;              /* and make it standard output */
        !           558:        printf("^C...\n");              /* and echo the ^C again. */
        !           559:     }
        !           560: #else                                  /* Not VMS */
        !           561:     if (ft_win) {                      /* If curses window open, */
        !           562:        screen(SCR_CW,0,0L,"");         /* close it. */
        !           563:        printf("^C...");                /* Echo ^C to standard output */
        !           564:     } else {
        !           565:        printf("^C...\n");
        !           566:     }
        !           567: #endif /* VMS */
        !           568: #ifdef datageneral
        !           569:     connoi_mt();                       /* Kill asynch task that listens to */
        !           570:     ttimoff();                         /* the keyboard */
        !           571:     conres();
        !           572: #endif /* datageneral */
        !           573: 
        !           574: #ifndef NOCCTRAP
        !           575: #ifdef UNIX
        !           576:     ttimoff();                         /* Turn off any timer interrupts */
        !           577: #endif /* UNIX */
        !           578: #ifdef OSK
        !           579:     ttimoff();                         /* Turn off any timer interrupts */
        !           580:     sigmask(-1);
        !           581: /*
        !           582:   We are in an intercept routine but do not perform a F$RTE (done implicitly
        !           583:   but rts).  We have to decrement the sigmask as F$RTE does.  Warning:
        !           584:   longjump only restores the cpu registers, NOT the fpu registers.  So don't
        !           585:   use fpu at all or at least don't use common fpu (double or float) register
        !           586:   variables.
        !           587: */
        !           588: #endif /* OSK */
        !           589:     longjmp(cmjbuf,1);                 /* Jump back to parser */
        !           590: #else
        !           591: /* No Ctrl-C trap, just exit. */
        !           592: #ifdef CK_CURSES                       /* Curses support? */
        !           593:     screen(SCR_CW,0,0L,"");            /* Close curses window */
        !           594: #endif /* CK_CURSES */
        !           595:     doexit(BAD_EXIT,what);             /* Exit poorly */
        !           596: #endif /* NOCCTRAP */
        !           597:     SIGRETURN;
        !           598: }
        !           599: 
        !           600: /*  C C _ C L E A N  --  Cleanup after terminal interrupt handler */
        !           601: 
        !           602: #ifdef GEMDOS
        !           603: int
        !           604: cc_clean() {
        !           605:     zclose(ZIFILE);                    /* If we were transferring a file, */
        !           606:     zclose(ZOFILE);                    /* close it. */
        !           607:     printf("^C...\n");                 /* Not VMS, no problem... */
        !           608: }
        !           609: #endif /* GEMDOS */
        !           610: 
        !           611: 
        !           612: /*  S T P T R A P -- Handle SIGTSTP (suspend) signals */
        !           613: 
        !           614: SIGTYP
        !           615: stptrap(sig) int sig; {
        !           616: #ifndef NOJC
        !           617:     int x; extern int cmflgs;
        !           618:     debug(F101,"stptrap() caught signal","",sig);
        !           619:     if (!suspend) {
        !           620:        printf("\r\nsuspend disabled\r\n");
        !           621: #ifndef NOICP
        !           622:        if (what == W_COMMAND) {        /* If we were parsing commands */
        !           623:            prompt(xxstring);           /* reissue the prompt and partial */
        !           624:            if (!cmflgs)                /* command (if any) */
        !           625:              printf("%s",cmdbuf);
        !           626:        }
        !           627: #endif /* NOICP */
        !           628:     } else {
        !           629:        conres();                       /* Reset the console */
        !           630: #ifndef OS2
        !           631:        /* Flush pending output first, in case we are continued */
        !           632:        /* in the background, which could make us block */
        !           633:        fflush(stdout);
        !           634: 
        !           635:        x = psuspend(suspend);          /* Try to suspend. */
        !           636:        if (x < 0)
        !           637: #endif /* OS2 */
        !           638:          printf("Job control not supported\r\n");
        !           639:        conint(trap,stptrap);           /* Rearm the trap. */
        !           640:        debug(F100,"stptrap back from suspend","",0);
        !           641:        switch (what) {
        !           642:          case W_CONNECT:               /* If suspended during CONNECT? */
        !           643:            conbin((char)escape);       /* put console back in binary mode */
        !           644:            debug(F100,"stptrap W_CONNECT","",0);
        !           645:            break;
        !           646: #ifndef NOICP
        !           647:          case W_COMMAND:               /* Suspended in command mode */
        !           648:            debug(F101,"stptrap W_COMMAND pflag","",pflag);
        !           649:            concb((char)escape);        /* Put back CBREAK tty mode */
        !           650:            if (pflag) {                /* If command parsing was */
        !           651:                prompt(xxstring);       /* reissue the prompt and partial */
        !           652:                if (!cmflgs)            /* command (if any) */
        !           653:                  printf("%s",cmdbuf);
        !           654:            }
        !           655:            break;
        !           656: #endif /* NOICP */
        !           657:          default:                      /* All other cases... */
        !           658:            debug(F100,"stptrap default","",0);
        !           659:            concb((char)escape);        /* Put it back in CBREAK mode */
        !           660:            break;
        !           661:        }
        !           662:     }
        !           663: #endif /* NOJC */
        !           664:     SIGRETURN;
        !           665: }
        !           666: 
        !           667: #ifndef MAC
        !           668: /*
        !           669:   The rest of this file is for all implementations but the Macintosh.
        !           670: */
        !           671: 
        !           672: /*  C H K I N T  --  Check for console interrupts  */
        !           673: 
        !           674: int
        !           675: chkint() {
        !           676:     int ch, cn; long zz;
        !           677: 
        !           678:     if ((!local) || (quiet)) return(0);        /* Only do this if local & not quiet */
        !           679: #ifdef datageneral
        !           680:     if (con_reads_mt)                   /* if conint_mt task is active */
        !           681:         if (conint_avl) {               /* and there's an interrupt pending */
        !           682:             cn = 1;                     /* process it */
        !           683:             ch = conint_ch;
        !           684:             conint_avl = 0;             /* turn off flag so conint_mt can */
        !           685:         } else                          /* proceed */
        !           686:             return(0);
        !           687:     else                                /* if conint_mt not active */
        !           688:         if ((ch = coninc(2)) < 0)       /* try to get char manually */
        !           689:             return(0);                  /* I/O error, or no data */
        !           690:         else                            /* if successful, set cn so we */
        !           691:             cn = 1;                     /* know we got one */
        !           692:     debug(F101,"chkint got keyboard character",ch,cn);
        !           693: #else
        !           694:     cn = conchk();                     /* Any input waiting? */
        !           695:     debug(F101,"conchk","",cn);
        !           696:     if (cn < 1) return(0);
        !           697:     if ((ch = coninc(5)) < 0) return(0);
        !           698: #endif /* datageneral */
        !           699: 
        !           700:     switch (ch & 0177) {
        !           701:       case 'A': case 'a': case 0001:           /* Status report */
        !           702:        if (fdispla != XYFD_R && fdispla != XYFD_S)
        !           703:          return(0);                            /* Only for serial or simple */
        !           704:        screen(SCR_TN,0,0l,"Status report:");
        !           705:        screen(SCR_TN,0,0l," file type: ");
        !           706:        if (binary) {
        !           707: #ifdef VMS
        !           708:            if (binary == XYFT_I)               /* VMS-only file types */
        !           709:              screen(SCR_TZ,0,0l,"image");
        !           710:            else if (binary == XYFT_L)
        !           711:              screen(SCR_TZ,0,0l,"labeled");
        !           712:            else screen(SCR_TZ,0,0l,"binary");
        !           713: #else
        !           714:            screen(SCR_TZ,0,0l,"binary");
        !           715: #endif /* VMS */
        !           716:        } else {
        !           717:            screen(SCR_TZ,0,0l,"text");
        !           718:        }
        !           719:        screen(SCR_QE,0,filcnt," file number");
        !           720:        if (fsize) screen(SCR_QE,0,fsize," size");
        !           721:        screen(SCR_QE,0,ffc,   " characters so far");
        !           722:        if (fsize > 0L) {
        !           723:            zz = ( ffc * 100L ) / fsize;
        !           724:            screen(SCR_QE,0,zz,      " percent done");
        !           725:        }
        !           726:        if (bctu == 4) {                /* Block check */
        !           727:            screen(SCR_TU,0,0L," block check: ");
        !           728:            screen(SCR_TZ,0,0L,"blank-free-2");
        !           729:        } else screen(SCR_QE,0,(long)bctu,  " block check");
        !           730:        screen(SCR_QE,0,(long)rptflg," compression");
        !           731:        screen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
        !           732:        screen(SCR_QE,0,(long)lscapu," locking shifts");
        !           733:        if (!network)
        !           734:          screen(SCR_QE,0, speed, " speed");
        !           735:        if (what == W_SEND)
        !           736:          screen(SCR_QE,0,(long)spsiz, " packet length");
        !           737:        else if (what == W_RECV || what == W_REMO)
        !           738:          screen(SCR_QE,0,(long)urpsiz," packet length");
        !           739:        screen(SCR_QE,0,(long)wslots,  " window slots");
        !           740:        return(0);
        !           741: 
        !           742:       case 'B': case 'b': case 0002:   /* Cancel batch */
        !           743:       case 'Z': case 'z': case 0032:
        !           744:        screen(SCR_TN,0,0l,"Cancelling Batch ");
        !           745:        czseen = 1;
        !           746:        return(0);
        !           747: 
        !           748:       case 'F': case 'f': case 0006:   /* Cancel file */
        !           749:       case 'X': case 'x': case 0030:
        !           750:        screen(SCR_TN,0,0l,"Cancelling File ");
        !           751:        cxseen = 1;
        !           752:        return(0);
        !           753: 
        !           754:       case 'R': case 'r': case 0022:   /* Resend */
        !           755:       case 0015: case 0012:
        !           756:        screen(SCR_TN,0,0l,"Resending packet ");
        !           757:        numerrs++;
        !           758:        resend(winlo);
        !           759:        return(1);
        !           760: 
        !           761:       case 'E': case 'e':              /* Send error packet */
        !           762:       case 0005:
        !           763:        return(-1);
        !           764: 
        !           765: #ifdef datageneral
        !           766:       case '\03':                       /* We're not trapping ^C's with */
        !           767:         trap(0);                        /* signals, so we check here    */
        !           768: #endif /* datageneral */
        !           769: 
        !           770:       default:                         /* Anything else, print message */
        !           771:        intmsg(1);
        !           772:        return(0);
        !           773:     }
        !           774: }
        !           775: 
        !           776: /*  I N T M S G  --  Issue message about terminal interrupts  */
        !           777: 
        !           778: VOID
        !           779: #ifdef CK_ANSIC
        !           780: intmsg(long n)
        !           781: #else
        !           782: intmsg(n) long n;
        !           783: #endif /* CK_ANSIC */
        !           784: /* intmsg */ {
        !           785:     char buf[80];
        !           786: 
        !           787:     if (!displa || quiet)              /* Not if we're being quiet */
        !           788:       return;
        !           789:     if (server && (!srvdis || n > -1L))        /* Special for server */
        !           790:       return;
        !           791:     buf[0] = NUL;                      /* Keep compilers happy */
        !           792: #ifdef SVORPOSIX
        !           793:     conchk();                          /* Clear out pending escape-signals */
        !           794: #endif /* SVORPOSIX */
        !           795: #ifdef VMS
        !           796:     conres();                          /* So Ctrl-C will work */
        !           797: #endif /* VMS */
        !           798:     if ((!server && n == 1L) || (server && n < 0L)) {
        !           799: 
        !           800: #ifdef SVORPOSIX                       /* We need to signal before kb input */
        !           801: #ifndef aegis
        !           802: #ifndef datageneral
        !           803:        sprintf(buf,"Type escape character (%s) followed by:",dbchr(escape));
        !           804:        screen(SCR_TN,0,0l,buf);
        !           805: #endif /* datageneral */
        !           806: #endif /* aegis */
        !           807: #endif /* SVORPOSIX */
        !           808: 
        !           809:  screen(SCR_TN,0,0l,"X to cancel file,  CR to resend current packet");
        !           810:  screen(SCR_TN,0,0l,"Z to cancel group, A for status report");
        !           811:  screen(SCR_TN,0,0l,"E to send Error packet, Ctrl-C to quit immediately: ");
        !           812: /* if (server) */ screen(SCR_TN,0,0l,"");
        !           813:     }
        !           814:     else screen(SCR_TU,0,0l," ");
        !           815: }
        !           816: 
        !           817: static int newdpy = 0;                 /* New display flag */
        !           818: static char fbuf[80];                  /* Filename buffer */
        !           819: static char abuf[80];                  /* As-name buffer */
        !           820: static long oldffc = 0L;
        !           821: static long dots = 0L;
        !           822: static int hpos = 0;
        !           823: 
        !           824: static VOID                            /* Initialize Serial or CTR display */
        !           825: dpyinit() {
        !           826:     newdpy = 0;                                /*  Don't do this again */
        !           827:     oldffc = 0L;                       /*  Reset this */
        !           828:     dots = 0L;                         /*  and this.. */
        !           829:     conoll("");                                                /* New line */
        !           830:     if (what == W_SEND) conol("Sending: ");            /* Action */
        !           831:     else if (what == W_RECV) conol("Receiving: ");
        !           832:     conol(fbuf);
        !           833:     if (*abuf) conol(" => "); conoll(abuf);            /* Names */
        !           834:     *fbuf = NUL; *abuf = NUL;
        !           835:     if (fsize > -1L) {                                 /* Size */
        !           836:        sprintf(fbuf,"Size: %ld, Type: ",fsize);
        !           837:        conol(fbuf); *fbuf = NUL;
        !           838:     } else conol("Size: unknown, Type: ");
        !           839:     if (binary) {                                      /* Type */
        !           840: #ifdef VMS
        !           841:        if (binary == XYFT_I)           /* VMS-only file types */
        !           842:          conoll("image");
        !           843:        else if (binary == XYFT_L)
        !           844:          conoll("labeled");
        !           845:        else
        !           846: #endif /* VMS */
        !           847:          conoll("binary");
        !           848:     } else conoll("text");
        !           849:     if (fdispla == XYFD_S) {           /* CRT field headings */
        !           850: 
        !           851: /*
        !           852:   Define CK_CPS to show current transfer rate.
        !           853:   Leave it undefined to show estimated time remaining.
        !           854:   Estimated-time-remaining code from Andy Fyfe, not tested on
        !           855:   pathological cases.
        !           856: */
        !           857: #define CK_CPS
        !           858: 
        !           859: #ifdef CK_CPS
        !           860:        conoll("    File   Percent       Packet");
        !           861:        conoll("    Bytes  Done     CPS  Length");
        !           862: #else
        !           863:        conoll("    File   Percent  Secs Packet");
        !           864:        conoll("    Bytes  Done     Left Length");
        !           865: #endif /* CK_CPS */
        !           866:        newdpy = 0;
        !           867:     }
        !           868:     hpos = 0;
        !           869: }
        !           870: 
        !           871: /*
        !           872:   showpkt(c)
        !           873:   c = completion code: 0 means transfer in progress, nonzero means it's done.
        !           874:   show the file transfer progress counter and perhaps verbose packet type.
        !           875:   Original by: Kai Uwe Rommel.
        !           876: */
        !           877: VOID
        !           878: #ifdef CK_ANSIC
        !           879: showpkt(char c)
        !           880: #else
        !           881: showpkt(c) char c;
        !           882: #endif /* CK_ANSIC */
        !           883: /* showpkt */ {
        !           884: 
        !           885:     if (newdpy)                                /* Put up filenames, etc, */
        !           886:       dpyinit();                       /* if they're not there already. */
        !           887: 
        !           888:     if (fdispla == XYFD_S) {           /* CRT display */
        !           889:        char buffer[40];
        !           890:        long et;                        /* Elapsed time, entire batch  */
        !           891:        long pd;                        /* Percent done, this file     */
        !           892:        long tp;                        /* Transfer rate, entire batch */
        !           893:        long ps;                        /* Packet size, current packet */
        !           894:        long myffc, mytfc;              /* Local copies of byte counters */
        !           895: 
        !           896:        et = gtimer();                  /* Elapsed time  */
        !           897:        ps = (what == W_RECV) ? rpktl+1 : spktl+1; /* Packet length */
        !           898:        pd = -1;                        /* Percent done. */
        !           899:        if (c == NUL) {                 /* Still going, figure % done */
        !           900:            if (fsize == 0L) return;    /* Empty file, don't bother */
        !           901:            pd = (fsize > 99L) ? (ffc / (fsize / 100L)) : 0L;
        !           902:            if (pd > 100) pd = 100;     /* Expansion */
        !           903:        } else pd = 100;                /* File complete, so 100%. */
        !           904: 
        !           905: #ifndef CK_CPS
        !           906: /*
        !           907:   fsecs = time (from gtimer) that this file started (set in sfile()).
        !           908:   Rate so far is ffc / (et - fsecs),  estimated time for remaining bytes
        !           909:   is (fsize - ffc) / ( ffc / (et - fsecs )).
        !           910: */
        !           911:        tp = (ffc > 0L) ? (fsize - ffc) * (et - fsecs) / ffc : 0L;
        !           912: #endif /* CK_CPS */
        !           913: 
        !           914:        myffc = (ffc > 0) ? ffc - 1L : ffc; /* No, I don't know why... */
        !           915:        if (myffc < 0L) myffc = 0L;
        !           916: #ifdef CK_CPS
        !           917:        mytfc = (pd < 100) ? tfc + myffc : tfc;
        !           918:        tp = (et > 0) ? mytfc / et : 0; /* Transfer rate */
        !           919:        if (c && (tp == 0))             /* Watch out for subsecond times */
        !           920:          tp = myffc;
        !           921: #endif /* CK_CPS */
        !           922:        if (pd > -1L)
        !           923:          sprintf(buffer, "%c%9ld%5ld%%%8ld%8ld ", CR, myffc, pd, tp, ps);
        !           924:        else
        !           925:          sprintf(buffer, "%c%9ld      %8ld%8ld ", CR, myffc, tp, ps);
        !           926:        conol(buffer);
        !           927:        hpos = 31;
        !           928:     } else {                           /* SERIAL display */
        !           929:        long i, k;
        !           930:        if (ffc - oldffc < 1024)        /* Update display every 1K */
        !           931:          return;
        !           932:        oldffc = ffc;                   /* Time for new display */
        !           933:        k = (ffc / 1024L) - dots;       /* How many K so far */
        !           934:        for (i = 0L; i < k; i++) {
        !           935:            if (hpos++ > 77) {          /* Time to wrap? */
        !           936:                conoll("");
        !           937:                hpos = 0;
        !           938:            }
        !           939:            conoc('.');                 /* Print a dot for this K */
        !           940:            dots++;                     /* Count it */
        !           941:        }
        !           942:     }
        !           943: }
        !           944: 
        !           945: /*  S C R E E N  --  Screen display function  */
        !           946: 
        !           947: /*
        !           948:   screen(f,c,n,s)
        !           949:     f - argument descriptor
        !           950:     c - a character or small integer
        !           951:     n - a long integer
        !           952:     s - a string.
        !           953:   Fill in this routine with the appropriate display update for the system.
        !           954:     FILE DISPLAY SERIAL:     Default, works on any terminal, even hardcopy.
        !           955:     FILE DISPLAY CRT:        Works on any CRT, writes over current line.
        !           956:     FILE DISPLAY FULLSCREEN: Requires terminal-dependent screen control.
        !           957: */
        !           958: VOID
        !           959: #ifdef CK_ANSIC
        !           960: screen(int f, char c,long n,char *s)
        !           961: #else
        !           962: screen(f,c,n,s) int f; char c; long n; char *s;
        !           963: #endif /* CK_ANSIC */
        !           964: /* screen */ {
        !           965:     char buf[80];
        !           966:     int len;                           /* Length of string */
        !           967: #ifdef UNIX
        !           968: #ifndef NOJC
        !           969:     int obg;
        !           970: _PROTOTYP( VOID conbgt, (int) );
        !           971: 
        !           972:     if (local) {
        !           973:        obg = backgrd;                  /* Previous background status */
        !           974:        conbgt(1);                      /* See if running in background */
        !           975:        if (!backgrd && obg) {          /* Just came into foreground? */
        !           976:            concb((char)escape);        /* Put console back in CBREAK mode */
        !           977:            conint(trap,stptrap);       /* Turn interrupts back on. */
        !           978:        }
        !           979:     }
        !           980: #endif /* NOJC */
        !           981: #endif /* UNIX */
        !           982: 
        !           983:     if ((f != SCR_WM) && (f != SCR_EM)) /* Always update warnings & errors */
        !           984:       if (!displa || quiet || backgrd || fdispla == XYFD_N ||
        !           985:          (server && !srvdis))
        !           986:        return;
        !           987: 
        !           988: #ifdef CK_CURSES
        !           989:     if (fdispla == XYFD_C) {           /* If fullscreen display selected */
        !           990:        screenc(f,c,n,s);               /* call the fullscreen version */
        !           991:        return;
        !           992:     }
        !           993: #endif /* CK_CURSES */
        !           994: 
        !           995:     len = (int)strlen(s);              /* Length of string */
        !           996: 
        !           997:     switch (f) {                       /* Handle our function code */
        !           998: 
        !           999: case SCR_FN:                           /* Filename */
        !          1000: #ifdef MAC
        !          1001:     conoll(""); conol(s); conoc(SP); hpos = len + 1;
        !          1002: #else
        !          1003:     strncpy(fbuf,s,80);
        !          1004:     newdpy = 1;                                /* New file so refresh display */
        !          1005: #endif /* MAC */
        !          1006:     return;
        !          1007: 
        !          1008: case SCR_AN:                           /* As-name */
        !          1009: #ifdef MAC
        !          1010:     if (hpos + len > 75) { conoll(""); hpos = 0; }
        !          1011:     conol("=> "); conol(s);
        !          1012:     if ((hpos += (len + 3)) > 78) { conoll(""); hpos = 0; }
        !          1013: #else
        !          1014:     strncpy(abuf,s,80);
        !          1015: #endif /* MAC */
        !          1016:     return;
        !          1017: 
        !          1018: case SCR_FS:                           /* File-size */
        !          1019: #ifdef MAC
        !          1020:     sprintf(buf,", Size: %ld",n);  conoll(buf);  hpos = 0;
        !          1021: #endif /* MAC */
        !          1022:     return;
        !          1023: 
        !          1024: case SCR_XD:                           /* X-packet data */
        !          1025: #ifdef MAC
        !          1026:     conoll(""); conoll(s); hpos = 0;
        !          1027: #else
        !          1028:     strncpy(fbuf,s,80);
        !          1029: #endif /* MAC */
        !          1030:     return;
        !          1031: 
        !          1032: case SCR_ST:                           /* File status */
        !          1033:     switch (c) {
        !          1034:       case ST_OK:                      /* Transferred OK */
        !          1035:        showpkt('Z');                   /* Update numbers one last time */
        !          1036:        if ((hpos += 5) > 78) conoll(""); /* Wrap screen line if necessary. */
        !          1037:        conoll(" [OK]"); hpos = 0;      /* Print OK message. */
        !          1038:        if (fdispla == XYFD_S) {        /* We didn't show Z packet when */
        !          1039:            conoc('Z');                 /* it came, so show it now. */
        !          1040:            hpos = 1;
        !          1041:        }
        !          1042:        return;       
        !          1043: 
        !          1044:       case ST_DISC:                    /*  Discarded */
        !          1045:        if ((hpos += 12) > 78) conoll("");
        !          1046:        conoll(" [discarded]"); hpos = 0;
        !          1047:        return;
        !          1048: 
        !          1049:       case ST_INT:                     /*  Interrupted */
        !          1050:        if ((hpos += 14) > 78) conoll("");
        !          1051:        conoll(" [interrupted]"); hpos = 0;
        !          1052:        return;
        !          1053: 
        !          1054:       case ST_SKIP:                    /*  Skipped */
        !          1055:        if ((hpos += 10) > 78) conoll("");
        !          1056:        conol(" [skipped]"); hpos = 0;
        !          1057:        return;
        !          1058: 
        !          1059:       case ST_ERR:                     /* Error */
        !          1060:        conoll("");
        !          1061:        conol("Error: "); conoll(s); hpos = 0;
        !          1062:        return;
        !          1063: 
        !          1064:       case ST_REFU:                    /* Refused */
        !          1065:        conoll("");
        !          1066:        conol("Refused: "); conoll(s); hpos = 0;
        !          1067:        return;
        !          1068: 
        !          1069:       case ST_INC:                     /* Incomplete */
        !          1070:        if ((hpos += 12) > 78) conoll("");
        !          1071:        conoll(" [incomplete]"); hpos = 0;
        !          1072:        return;
        !          1073: 
        !          1074:       default:
        !          1075:        conoll("*** screen() called with bad status ***");
        !          1076:        hpos = 0;
        !          1077:        return;
        !          1078:     }
        !          1079: 
        !          1080: #ifdef MAC
        !          1081: case SCR_PN:                           /* Packet number */
        !          1082:     sprintf(buf,"%s: %ld",s,n); conol(buf); hpos += (int)strlen(buf); return;
        !          1083: #endif /* MAC */
        !          1084: 
        !          1085: case SCR_PT:                           /* Packet type or pseudotype */
        !          1086:     if (c == 'Y') return;              /* Don't bother with ACKs */
        !          1087:     if (c == 'D') {                    /* In data transfer phase, */
        !          1088:        showpkt(NUL);                   /* show progress. */
        !          1089:        return;
        !          1090:     }
        !          1091: #ifndef AMIGA
        !          1092:     if (hpos++ > 77) {                 /* If near right margin, */
        !          1093:        conoll("");                     /* Start new line */
        !          1094:        hpos = 0;                       /* and reset counter. */
        !          1095:     }
        !          1096: #endif /* AMIGA */
        !          1097:     if (c == 'Z' && fdispla == XYFD_S)
        !          1098:       return;
        !          1099:     else
        !          1100:       conoc(c);                                /* Display the packet type. */
        !          1101: #ifdef AMIGA
        !          1102:     if (c == 'G') conoll("");           /* New line after G packets */
        !          1103: #endif /* AMIGA */
        !          1104:     return;
        !          1105: 
        !          1106: case SCR_TC:                           /* Transaction complete */
        !          1107:     conoc(BEL); conoll(""); return;
        !          1108: 
        !          1109: case SCR_EM:                           /* Error message */
        !          1110:     conoll(""); conoc('?'); conoll(s); hpos = 0; return;
        !          1111: 
        !          1112: case SCR_WM:                           /* Warning message */
        !          1113:     conoll(""); conoll(s); hpos = 0; return;
        !          1114: 
        !          1115: case SCR_TU:                           /* Undelimited text */
        !          1116:     if ((hpos += len) > 77) { conoll(""); hpos = len; }
        !          1117:     conol(s); return;
        !          1118: 
        !          1119: case SCR_TN:                           /* Text delimited at beginning */
        !          1120:     conoll(""); conol(s); hpos = len; return;
        !          1121: 
        !          1122: case SCR_TZ:                           /* Text delimited at end */
        !          1123:     if ((hpos += len) > 77) { conoll(""); hpos = len; }
        !          1124:     conoll(s); return;
        !          1125: 
        !          1126: case SCR_QE:                           /* Quantity equals */
        !          1127:     sprintf(buf,"%s: %ld",s,n);
        !          1128:     conoll(buf); hpos = 0; return;
        !          1129: 
        !          1130: case SCR_CW:                           /* Close fullscreen window */
        !          1131:     return;                            /* No window to close */
        !          1132: 
        !          1133: default:
        !          1134:     conoll("*** screen() called with bad object ***");
        !          1135:     hpos = 0;
        !          1136:     return;
        !          1137:     }
        !          1138: }
        !          1139: 
        !          1140: /*  E R M S G  --  Nonfatal error message  */
        !          1141: 
        !          1142: /* Should be used only for printing the message text from an Error packet. */
        !          1143: 
        !          1144: VOID
        !          1145: ermsg(msg) char *msg; {                        /* Print error message */
        !          1146:     if (local)
        !          1147:       screen(SCR_EM,0,0L,msg);
        !          1148:     tlog(F110,"Protocol Error:",msg,0L);
        !          1149: }
        !          1150: 
        !          1151: VOID
        !          1152: doclean() {                            /* General cleanup upon exit */
        !          1153: #ifndef NOICP
        !          1154: #ifndef NOSPL
        !          1155:     extern struct mtab *mactab;                /* For ON_EXIT macro. */
        !          1156:     extern int nmac;
        !          1157: #endif /* NOSPL */
        !          1158: #endif /* NOICP */
        !          1159: 
        !          1160: #ifdef DEBUG
        !          1161:     if (deblog) {                      /* Close any open logs. */
        !          1162:        debug(F100,"Debug Log Closed","",0);
        !          1163:        *debfil = '\0';
        !          1164:        deblog = 0;
        !          1165:        zclose(ZDFILE);
        !          1166:     }
        !          1167: #endif /* DEBUG */
        !          1168:     if (pktlog) {
        !          1169:        *pktfil = '\0';
        !          1170:        pktlog = 0;
        !          1171:        zclose(ZPFILE);
        !          1172:     }
        !          1173:     if (seslog) {
        !          1174:        *sesfil = '\0';
        !          1175:        seslog = 0;
        !          1176:        zclose(ZSFILE);
        !          1177:     }
        !          1178: #ifdef TLOG
        !          1179:     if (tralog) {
        !          1180:        tlog(F100,"Transaction Log Closed","",0L);
        !          1181:        *trafil = '\0';
        !          1182:        tralog = 0;
        !          1183:        zclose(ZTFILE);
        !          1184:     }
        !          1185: #endif /* TLOG */
        !          1186: 
        !          1187: #ifndef NOICP
        !          1188: #ifndef NOSPL
        !          1189:     zclose(ZRFILE);                    /* READ and WRITE files, if any. */
        !          1190:     zclose(ZWFILE);
        !          1191: #ifndef NODIAL
        !          1192:     if (dialfd) fclose(dialfd);                /* Dial directory, if any. */
        !          1193: #endif /* NODIAL */
        !          1194: /*
        !          1195:   If a macro named "on_exit" is defined, execute it.  Also remove it from the
        !          1196:   macro table, in case its definition includes an EXIT or QUIT command, which
        !          1197:   would cause much recursion and would prevent the program from ever actually
        !          1198:   EXITing.
        !          1199: */
        !          1200:     if (nmac) {                                /* Any macros defined? */
        !          1201:        int k;                          /* Yes */
        !          1202:        k = mlook(mactab,"on_exit",nmac); /* Look up "on_exit" */
        !          1203:        if (k >= 0) {                   /* If found, */
        !          1204:            *(mactab[k].kwd) = NUL;     /* poke its name from the table, */
        !          1205:            if (dodo(k,"") > -1)        /* set it up, */
        !          1206:              parser(1);                /* and execute it */
        !          1207:         }
        !          1208:     }
        !          1209: #endif /* NOSPL */
        !          1210: #endif /* NOICP */
        !          1211: 
        !          1212: /*
        !          1213:   Put console terminal back to normal.  This is done here because the
        !          1214:   ON_EXIT macro calls the parser, which meddles with console terminal modes.
        !          1215: */
        !          1216:     ttclos(0);                         /* Close external line, if any */
        !          1217:     if (local) {
        !          1218:        strcpy(ttname,dftty);           /* Restore default tty */
        !          1219:        local = dfloc;                  /* And default remote/local status */
        !          1220:     }
        !          1221:     conres();                          /* Restore console terminal. */
        !          1222: 
        !          1223: #ifdef COMMENT
        !          1224: /* Should be no need for this, and maybe it's screwing things up? */
        !          1225:     connoi();                          /* Turn off console interrupt traps */
        !          1226: #endif /* COMMENT */
        !          1227: 
        !          1228:     syscleanup();                      /* System-dependent cleanup, last */
        !          1229: }
        !          1230: 
        !          1231: /*  D O E X I T  --  Exit from the program.  */
        !          1232: 
        !          1233: /*
        !          1234:   First arg is general, system-independent symbol: GOOD_EXIT or BAD_EXIT.
        !          1235:   If second arg is -1, take 1st arg literally.
        !          1236:   If second arg is not -1, work it into the exit code.
        !          1237: */
        !          1238: VOID
        !          1239: doexit(exitstat,what) int exitstat, what; {
        !          1240: #ifdef VMS
        !          1241:     char envstr[64];
        !          1242:     static $DESCRIPTOR(symnam,"CKERMIT_STATUS");
        !          1243:     static struct dsc$descriptor_s symval;
        !          1244:     int i;
        !          1245: #endif /* VMS */
        !          1246: 
        !          1247:     debug(F101,"doexit exitstat","",exitstat);
        !          1248:     debug(F101,"doexit what","",what);
        !          1249: 
        !          1250:     doclean();                         /* First, clean up everything */
        !          1251: 
        !          1252: #ifdef VMS
        !          1253:     if (what == -1)
        !          1254:        what = 0;                       /* Since we set two different items */
        !          1255:     sprintf(envstr,"%d", exitstat | what);
        !          1256:     symval.dsc$w_length = (int)strlen(envstr);
        !          1257:     symval.dsc$a_pointer = envstr;
        !          1258:     symval.dsc$b_class = DSC$K_CLASS_S;
        !          1259:     symval.dsc$b_dtype = DSC$K_DTYPE_T;
        !          1260:     i = 2;                             /* Store in global table */
        !          1261:     LIB$SET_SYMBOL(&symnam, &symval, &i);
        !          1262:     if (exitstat == BAD_EXIT)
        !          1263:        exitstat = SS$_ABORT | STS$M_INHIB_MSG;
        !          1264:     if (exitstat == GOOD_EXIT)
        !          1265:        exitstat = SS$_NORMAL | STS$M_INHIB_MSG;
        !          1266:     exit(exitstat);
        !          1267: #else /* Not VMS */
        !          1268:     if (what == -1)                    /* Take 1st arg literally */
        !          1269:       exit(exitstat);                  /* e.g. user-supplied exit code */
        !          1270:     else                               /* otherwise */
        !          1271:       exit(exitstat | what);           /* OR in the bits */
        !          1272: #endif /* VMS */
        !          1273: }
        !          1274: 
        !          1275: /* Set up interrupts */
        !          1276: 
        !          1277: VOID
        !          1278: setint() {
        !          1279:     conint(trap,stptrap);       /* Turn on console terminal interrupts. */
        !          1280:     bgchk();                   /* Check background status */
        !          1281: }
        !          1282: 
        !          1283: VOID
        !          1284: bgchk() {                              /* Check background status */
        !          1285:     if (bgset < 0)
        !          1286:       pflag = !backgrd;                        /* Set prompt flag */
        !          1287:     else                               /* based on foreground/background */
        !          1288:       pflag = (bgset == 0 ? 1 : 0);
        !          1289: 
        !          1290:     /* Message flag on only if at top level, pflag is on, and QUIET is OFF */
        !          1291: 
        !          1292:     if (
        !          1293: #ifndef NOSPL
        !          1294:        cmdlvl == 0
        !          1295: #else
        !          1296:        tlevel < 0
        !          1297: #endif /* NOSPL */
        !          1298:        )
        !          1299:       msgflg = (pflag == 0) ? 0 : !quiet;
        !          1300:     else msgflg = 0;
        !          1301: }
        !          1302: 
        !          1303: #ifdef DEBUG
        !          1304: /*  D E B U G  --  Enter a record in the debugging log  */
        !          1305: 
        !          1306: /*
        !          1307:  Call with a format, two strings, and a number:
        !          1308:    f  - Format, a bit string in range 0-7.
        !          1309:         If bit x is on, then argument number x is printed.
        !          1310:    s1 - String, argument number 1.  If selected, printed as is.
        !          1311:    s2 - String, argument number 2.  If selected, printed in brackets.
        !          1312:    n  - Int, argument 3.  If selected, printed preceded by equals sign.
        !          1313: 
        !          1314:    f=0 is special: print s1,s2, and interpret n as a char.
        !          1315: */
        !          1316: #define DBUFL 2300
        !          1317: static char *dbptr = (char *)0;
        !          1318: 
        !          1319: int
        !          1320: dodebug(f,s1,s2,n) int f; char *s1, *s2; long n; {
        !          1321:     char *sp;
        !          1322: 
        !          1323:     if (!deblog) return(0);    /* If no debug log, don't. */
        !          1324:     if (!dbptr) {
        !          1325:        dbptr = malloc(DBUFL+1);
        !          1326:        if (!dbptr)
        !          1327:          return(0);
        !          1328:     }
        !          1329:     sp = dbptr;
        !          1330:     if (!s1) s1="(NULL)";
        !          1331:     if (!s2) s2="(NULL)";
        !          1332:     switch (f) {
        !          1333:        case F000:              /* 0, print both strings, and n as a char */
        !          1334:            if ((int)strlen(s1) + (int)strlen(s2) + 5 > DBUFL) {
        !          1335:                sprintf(sp,"DEBUG string too long\n");
        !          1336:            } else {
        !          1337:                if (n > 31 && n < 127)
        !          1338:                  sprintf(sp,"%s%s:%c\n",s1,s2,n);
        !          1339:                else if (n < 32 || n == 127)
        !          1340:                  sprintf(sp,"%s%s:^%c\n",s1,s2,(n+64) & 0x7F);
        !          1341:                else if (n > 127 && n < 160)
        !          1342:                  sprintf(sp,"%s%s:~^%c\n",s1,s2,(n-64) & 0x7F);
        !          1343:                else if (n > 159 && n < 256)
        !          1344:                  sprintf(sp,"%s%s:~%c\n",s1,s2,n & 0x7F);
        !          1345:                else sprintf(sp,"%s%s:%ld\n",s1,s2,n);
        !          1346:            }
        !          1347:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1348:            break;
        !          1349:        case F001:                      /* 1, "=n" */
        !          1350:            sprintf(sp,"=%ld\n",n);
        !          1351:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1352:            break;
        !          1353:        case F010:                      /* 2, "[s2]" */
        !          1354:            if ((int)strlen(s2) + 4 > DBUFL)
        !          1355:              sprintf(sp,"DEBUG string too long\n");
        !          1356:            else sprintf(sp,"[%s]\n",s2);
        !          1357:            if (zsout(ZDFILE,"") < 0) deblog = 0;
        !          1358:            break;
        !          1359:        case F011:                      /* 3, "[s2]=n" */
        !          1360:            if ((int)strlen(s2) + 15 > DBUFL)
        !          1361:              sprintf(sp,"DEBUG string too long\n");
        !          1362:            else sprintf(sp,"[%s]=%ld\n",s2,n);
        !          1363:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1364:            break;
        !          1365:        case F100:                      /* 4, "s1" */
        !          1366:            if (zsoutl(ZDFILE,s1) < 0) deblog = 0;
        !          1367:            break;
        !          1368:        case F101:                      /* 5, "s1=n" */
        !          1369:            if ((int)strlen(s1) + 15 > DBUFL)
        !          1370:              sprintf(sp,"DEBUG string too long\n");
        !          1371:            else sprintf(sp,"%s=%ld\n",s1,n);
        !          1372:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1373:            break;
        !          1374:        case F110:                      /* 6, "s1[s2]" */
        !          1375:            if ((int)strlen(s1) + (int)strlen(s2) + 4 > DBUFL)
        !          1376:              sprintf(sp,"DEBUG string too long\n");
        !          1377:            else sprintf(sp,"%s[%s]\n",s1,s2);
        !          1378:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1379:            break;
        !          1380:        case F111:                      /* 7, "s1[s2]=n" */
        !          1381:            if ((int)strlen(s1) + (int)strlen(s2) + 15 > DBUFL)
        !          1382:              sprintf(sp,"DEBUG string too long\n");
        !          1383:            else sprintf(sp,"%s[%s]=%ld\n",s1,s2,n);
        !          1384:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1385:            break;
        !          1386:        default:
        !          1387:            sprintf(sp,"\n?Invalid format for debug() - %d\n",f);
        !          1388:            if (zsout(ZDFILE,dbptr) < 0) deblog = 0;
        !          1389:     }
        !          1390:     return(0);
        !          1391: }
        !          1392: #endif /* DEBUG */
        !          1393: 
        !          1394: #ifdef TLOG
        !          1395: #define TBUFL 300
        !          1396: /*  T L O G  --  Log a record in the transaction file  */
        !          1397: /*
        !          1398:  Call with a format and 3 arguments: two strings and a number:
        !          1399:    f  - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
        !          1400:    s1,s2 - String arguments 1 and 2.
        !          1401:    n  - Int, argument 3.
        !          1402: */
        !          1403: VOID
        !          1404: tlog(f,s1,s2,n) int f; long n; char *s1, *s2; {
        !          1405:     static char s[TBUFL];
        !          1406:     char *sp = s; int x;
        !          1407: 
        !          1408:     if (!tralog) return;               /* If no transaction log, don't */
        !          1409:     switch (f) {
        !          1410:        case F000:                      /* 0 (special) "s1 n s2"  */
        !          1411:            if ((int)strlen(s1) + (int)strlen(s2) + 15 > TBUFL)
        !          1412:              sprintf(sp,"?T-Log string too long\n");
        !          1413:            else sprintf(sp,"%s %ld %s\n",s1,n,s2);
        !          1414:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1415:            break;
        !          1416:        case F001:                      /* 1, " n" */
        !          1417:            sprintf(sp," %ld\n",n);
        !          1418:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1419:            break;
        !          1420:        case F010:                      /* 2, "[s2]" */
        !          1421:            x = (int)strlen(s2);
        !          1422:            if (s2[x] == '\n') s2[x] = '\0';
        !          1423:            if (x + 6 > TBUFL)
        !          1424:              sprintf(sp,"?T-Log string too long\n");
        !          1425:            else sprintf(sp,"[%s]\n",s2);
        !          1426:            if (zsout(ZTFILE,"") < 0) tralog = 0;
        !          1427:            break;
        !          1428:        case F011:                      /* 3, "[s2] n" */
        !          1429:            x = (int)strlen(s2);
        !          1430:            if (s2[x] == '\n') s2[x] = '\0';
        !          1431:            if (x + 6 > TBUFL)
        !          1432:              sprintf(sp,"?T-Log string too long\n");
        !          1433:            else sprintf(sp,"[%s] %ld\n",s2,n);
        !          1434:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1435:            break;
        !          1436:        case F100:                      /* 4, "s1" */
        !          1437:            if (zsoutl(ZTFILE,s1) < 0) tralog = 0;
        !          1438:            break;
        !          1439:        case F101:                      /* 5, "s1: n" */
        !          1440:            if ((int)strlen(s1) + 15 > TBUFL)
        !          1441:              sprintf(sp,"?T-Log string too long\n");
        !          1442:            else sprintf(sp,"%s: %ld\n",s1,n);
        !          1443:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1444:            break;
        !          1445:        case F110:                      /* 6, "s1 s2" */
        !          1446:            x = (int)strlen(s2);
        !          1447:            if (s2[x] == '\n') s2[x] = '\0';
        !          1448:            if ((int)strlen(s1) + x + 4 > TBUFL)
        !          1449:              sprintf(sp,"?T-Log string too long\n");
        !          1450:            else sprintf(sp,"%s %s\n",s1,s2);
        !          1451:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1452:            break;
        !          1453:        case F111:                      /* 7, "s1 s2: n" */
        !          1454:            x = (int)strlen(s2);
        !          1455:            if (s2[x] == '\n') s2[x] = '\0';
        !          1456:            if ((int)strlen(s1) + x + 15 > TBUFL)
        !          1457:              sprintf(sp,"?T-Log string too long\n");
        !          1458:            else sprintf(sp,"%s %s: %ld\n",s1,s2,n);
        !          1459:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1460:            break;
        !          1461:        default:
        !          1462:            sprintf(sp,"\n?Invalid format for tlog() - %ld\n",n);
        !          1463:            if (zsout(ZTFILE,s) < 0) tralog = 0;
        !          1464:     }
        !          1465: }
        !          1466: #endif /* TLOG */
        !          1467: 
        !          1468: #ifdef CK_CURSES
        !          1469: 
        !          1470: /*
        !          1471:   There are three different ways to do fullscreen on VMS.
        !          1472:   1. Use the real curses library, VAXCCURSE.
        !          1473:   2. Use do-it-yourself code.
        !          1474:   3. Use the Screen Manager, SMG$.
        !          1475: 
        !          1476:   Method 1 doesn't work quite right; you can't call endwin(), so once you've
        !          1477:   started curses mode, you can never leave.
        !          1478: 
        !          1479:   Method 2 doesn't optimize the screen, and so much more time is spent in
        !          1480:   screen writes.  This actually causes file transfers to fail because the
        !          1481:   tty device input buffer can be overrun while the screen is being updated,
        !          1482:   especially on a slow MicroVAX that has small typeahead buffers.
        !          1483: 
        !          1484:   In the following #ifdef block, #define one of them and #undef the other 2.
        !          1485: 
        !          1486:   So now let's try method 3...
        !          1487: */
        !          1488: #ifdef VMS
        !          1489: #define CK_SMG                         /* Screen Manager */
        !          1490: #undef MYCURSES                                /* Do-it-yourself */
        !          1491: #undef VMSCURSE                                /* VAXCCURSE library */
        !          1492: #endif /* VMS */
        !          1493: 
        !          1494: /*  S C R E E N C  --  Screen display function, uses curses  */
        !          1495: 
        !          1496: /* Idea for curses display contributed by Chris Pratt of APV Baker, UK */
        !          1497: 
        !          1498: /* Avoid conficts with curses.h */
        !          1499: 
        !          1500: #ifndef MYCURSES
        !          1501: #undef VOID                            /* This was defined in ckcdeb.h */
        !          1502: #endif /* MYCURSES */
        !          1503: 
        !          1504: #undef BS                              /* These were defined in ckcasc.h */
        !          1505: #undef CR
        !          1506: #undef NL
        !          1507: #undef SO
        !          1508: #undef US
        !          1509: 
        !          1510: #ifdef VMS                             /* VMS fullscreen display */
        !          1511: #ifdef MYCURSES                                /* Do-it-yourself method */
        !          1512: extern int isvt52;                     /* From CKVTIO.C */
        !          1513: #define printw printf
        !          1514: #else
        !          1515: #ifdef VMSCURSE                                /* VMS curses library VAXCCURSE */
        !          1516: #include <curses.h> 
        !          1517: /* Note: Screen manager doesn't need a header file */
        !          1518: #endif /* VMSCURSE */
        !          1519: #endif /* MYCURSES */
        !          1520: #else                                  /* Not VMS */
        !          1521: #ifdef MYCURSES                                /* Do-it-yourself method */
        !          1522: #define isvt52 0                       /* Used by OS/2, VT-100/ANSI always */
        !          1523: #define printw printf
        !          1524: #else
        !          1525: #include <curses.h>                    /* So use real curses */
        !          1526: #endif /* MYCURSES */
        !          1527: #endif /* VMS */
        !          1528: 
        !          1529: #ifdef CK_SMG
        !          1530: /*
        !          1531:   Long section for Screen Manager starts here...
        !          1532:   By William Bader.
        !          1533: */
        !          1534: #include "ckvvms.h"
        !          1535: /* #include <smgdef.h> */
        !          1536: /* #include <smgmsg.h> */
        !          1537: 
        !          1538: extern unsigned int vms_status;            /* Used for system service return status */
        !          1539: 
        !          1540: static long smg_pasteboard_id = -1;    /* pasteboard identifier */
        !          1541: static long smg_display_id = -1;       /* display identifier */
        !          1542: static int smg_open = 0;               /* flag if smg current open */
        !          1543: 
        !          1544: #define        clrtoeol()      SMG$ERASE_LINE(&smg_display_id, 0, 0)
        !          1545: 
        !          1546: #define clear()                SMG$ERASE_DISPLAY(&smg_display_id, 0, 0, 0, 0)
        !          1547: 
        !          1548: #define        touchwin(scr)   SMG$REPAINT_SCREEN(&smg_pasteboard_id)
        !          1549: 
        !          1550: static void
        !          1551: move(row, col) int row, col; {
        !          1552:     /* Change from 0-based for curses to 1-based for SMG */
        !          1553:     ++row; ++col;
        !          1554:     CHECK_ERR("move: smg$set_cursor_abs",
        !          1555:              SMG$SET_CURSOR_ABS(&smg_display_id, &row, &col));
        !          1556: }
        !          1557: 
        !          1558: static void
        !          1559: refresh() {
        !          1560:     CHECK_ERR("refresh: smg$end_pasteboard_update",
        !          1561:              SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
        !          1562:     CHECK_ERR("refresh: smg$begin_pasteboard_update",
        !          1563:              SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
        !          1564: }
        !          1565: 
        !          1566: #ifdef VMS_V40
        !          1567: #define        OLD_VMS
        !          1568: #endif /* VMS_V40 */
        !          1569: #ifdef VMS_V42
        !          1570: #define        OLD_VMS
        !          1571: #endif /* VMS_V42 */
        !          1572: #ifdef VMS_V44
        !          1573: #define        OLD_VMS
        !          1574: #endif /* VMS_V44 */
        !          1575: 
        !          1576: static int
        !          1577: initscr() {
        !          1578:     int rows = 24, cols = 80;
        !          1579:     int row = 1, col = 1;
        !          1580: 
        !          1581:     if (smg_pasteboard_id == -1) {     /* Open the screen */
        !          1582: #ifdef OLD_VMS
        !          1583:        CHECK_ERR("initscr: smg$create_pasteboard",
        !          1584:                  SMG$CREATE_PASTEBOARD(&smg_pasteboard_id, 0, 0, 0, 0));
        !          1585: #else
        !          1586:        /* For VMS V5, not tested */
        !          1587:        CHECK_ERR("initscr: smg$create_pasteboard",
        !          1588:                  SMG$CREATE_PASTEBOARD(&smg_pasteboard_id, 0, 0, 0, 0, 0));
        !          1589: #endif /* OLD_VMS */
        !          1590:     }
        !          1591: 
        !          1592:     if (smg_display_id == -1) {                /* Create a display window */
        !          1593: 
        !          1594:        CHECK_ERR("initscr: smg$create_virtual_display",
        !          1595:                  SMG$CREATE_VIRTUAL_DISPLAY(&rows, &cols, &smg_display_id,
        !          1596:                                             0, 0, 0));
        !          1597: 
        !          1598:        /* Connect the display window to the screen */
        !          1599:        CHECK_ERR("initscr: smg$paste_virtual_display",
        !          1600:                  SMG$PASTE_VIRTUAL_DISPLAY(&smg_display_id,&smg_pasteboard_id,
        !          1601:                                            &row,&col));
        !          1602:     }
        !          1603: 
        !          1604:     if (!smg_open) {                   /* Start a batch update */
        !          1605:        smg_open = 1;
        !          1606:        CHECK_ERR("initscr: smg$begin_pasteboard_update",
        !          1607:                  SMG$BEGIN_PASTEBOARD_UPDATE(&smg_pasteboard_id));
        !          1608:     }
        !          1609:     return(1);
        !          1610: }
        !          1611: 
        !          1612: static void
        !          1613: endwin() {
        !          1614:     if (!smg_open)
        !          1615:       return;
        !          1616: 
        !          1617:     smg_open = 0;
        !          1618: 
        !          1619:     CHECK_ERR("endwin: smg$end_pasteboard_update",
        !          1620:              SMG$END_PASTEBOARD_UPDATE(&smg_pasteboard_id));
        !          1621: 
        !          1622:     move(22, 0);
        !          1623: 
        !          1624: #ifdef COMMENT
        !          1625: /*
        !          1626:   These calls clear the screen.
        !          1627: */
        !          1628:     CHECK_ERR("endwin: smg$delete_virtual_display",
        !          1629:              SMG$DELETE_VIRTUAL_DISPLAY(&smg_display_id));
        !          1630:     smg_display_id = -1;
        !          1631: 
        !          1632:     CHECK_ERR("endwin: smg$delete_pasteboard",
        !          1633:              SMG$DELETE_PASTEBOARD(&smg_pasteboard_id, 0));
        !          1634:     smg_pasteboard_id = -1;
        !          1635: #endif /* COMMENT */
        !          1636: }
        !          1637: 
        !          1638: static void printw(str, a1, a2, a3, a4, a5, a6, a7, a8)
        !          1639: char *str;
        !          1640: long a1, a2, a3, a4, a5, a6, a7, a8;
        !          1641: /* printw */ {
        !          1642:     char buf[255];
        !          1643:     $DESCRIPTOR(text_dsc, buf);
        !          1644: 
        !          1645:     text_dsc.dsc$w_length = sprintf(buf, str, a1, a2, a3, a4, a5, a6, a7, a8);
        !          1646:     CHECK_ERR("printw: smg$put_chars",
        !          1647:              SMG$PUT_CHARS(&smg_display_id, &text_dsc, 0, 0, 0, 0, 0));
        !          1648: }
        !          1649: #endif /* CK_SMG */
        !          1650: 
        !          1651: #ifdef MYCURSES
        !          1652: /*
        !          1653:   Do-it-yourself curses implementation for VMS, OS/2 and other ANSI/VT-100's.
        !          1654:   Supports only the VT52 and VT1xx (and later VT2xx/3xx/4xx) terminals.
        !          1655:   By Terry Kennedy, St Peters College.
        !          1656:  
        !          1657:   First, some stuff we can just ignore:
        !          1658: */
        !          1659: 
        !          1660: int
        !          1661: touchwin(x) int x; {
        !          1662: }
        !          1663: int
        !          1664: initscr() {
        !          1665: }
        !          1666: int
        !          1667: refresh() {
        !          1668: }
        !          1669: int
        !          1670: endwin() {
        !          1671: }
        !          1672: 
        !          1673: /*
        !          1674:  * Now, some stuff we need to do:
        !          1675:  */
        !          1676: 
        !          1677: _PROTOTYP( int move, (int, int) );
        !          1678: 
        !          1679: int
        !          1680: move(row, col) int row, col; {
        !          1681:     if (isvt52)
        !          1682:       printf("\033Y%c%c", row + 037, col + 037);
        !          1683:     else
        !          1684:       printf("\033[%d;%dH", row + 1, col + 1);
        !          1685: }
        !          1686: 
        !          1687: int
        !          1688: clear() {
        !          1689:     move(1,1);
        !          1690:     if (isvt52)
        !          1691:       printf("\033J");
        !          1692:     else
        !          1693:       printf("\033[J");
        !          1694: }
        !          1695: 
        !          1696: int
        !          1697: clrtoeol() {
        !          1698:     if (isvt52)
        !          1699:       printf("\033K");
        !          1700:     else
        !          1701:       printf("\033[K");
        !          1702: }
        !          1703: #endif /* MYCURSES */
        !          1704: 
        !          1705: /* Screen line numbers */
        !          1706: 
        !          1707: #define CW_BAN  0                      /* Curses Window Banner */
        !          1708: #define CW_DIR  2                      /* Current directory */
        !          1709: #define CW_LIN  3                      /* Communication device */
        !          1710: #define CW_SPD  4                      /* Communication speed */
        !          1711: #define CW_PAR  5                      /* Parity */
        !          1712: #define CW_NAM  7                      /* Filename */
        !          1713: #define CW_TYP  8                      /* File type */
        !          1714: #define CW_SIZ  9                      /* File size */
        !          1715: #define CW_PCD 10                      /* Percent done */
        !          1716: #define CW_TR  11                      /* Time remaining */
        !          1717: #define CW_WS  12                      /* Window slots */
        !          1718: #define CW_PT  13                      /* Packet type */
        !          1719: #define CW_PC  14                      /* Packet count */
        !          1720: #define CW_PL  15                      /* Packet length */
        !          1721: #define CW_PR  16                      /* Packet retry */
        !          1722: #define CW_PB  17                      /* Packet block check */
        !          1723: #define CW_ERR 19                      /* Error message */
        !          1724: #define CW_MSG 20                      /* Info message */
        !          1725: #define CW_INT 22                      /* Instructions */
        !          1726: 
        !          1727: static int cinit = 0;                  /* Flag for curses init'd */
        !          1728: static int cendw = 0;                  /* endwin() was called */
        !          1729: 
        !          1730: static
        !          1731: #ifdef CK_ANSIC                                /* Because VOID used by curses.h */
        !          1732: void
        !          1733: #else
        !          1734: #ifdef MYCURSES
        !          1735: VOID
        !          1736: #else
        !          1737: int
        !          1738: #endif /* MYCURSES */
        !          1739: #endif /* CK_ANSIC */
        !          1740: scrft() {                              /* Display file type */
        !          1741:     move(CW_TYP,22);
        !          1742:     if (binary) {
        !          1743: #ifdef VMS
        !          1744:        if (binary == XYFT_I)
        !          1745:          printw("image");
        !          1746:        else if (binary == XYFT_L)
        !          1747:          printw("labeled");
        !          1748:        else printw("binary");
        !          1749: #else /* Not VMS */
        !          1750:        printw("binary");
        !          1751: #endif /* VMS */
        !          1752:     } else {
        !          1753:        printw("text");
        !          1754:     }
        !          1755:     clrtoeol();
        !          1756:     return;
        !          1757: }
        !          1758: 
        !          1759: char *                                 /* Convert seconds to hh:mm:ss */
        !          1760: #ifdef CK_ANSIC
        !          1761: hhmmss(long x)
        !          1762: #else
        !          1763: hhmmss(x) long x;
        !          1764: #endif /* CK_ANSIC */
        !          1765: /* hhmmss(x) */ {
        !          1766:     static char buf[10];
        !          1767:     long s, h, m;
        !          1768:     h = x / 3600L;                     /* Hours */
        !          1769:     x = x % 3600L;
        !          1770:     m = x / 60L;                       /* Minutes */
        !          1771:     s = x % 60L;                       /* Seconds */
        !          1772:     if (x > -1L)
        !          1773:       sprintf(buf,"%02ld:%02ld:%02ld",h,m,s);
        !          1774:     else buf[0] = NUL;
        !          1775:     return((char *)buf);
        !          1776: }
        !          1777: 
        !          1778: #ifdef CK_NEWTERM
        !          1779: static FILE *ck_stdout = NULL;
        !          1780: static int ck_fd = -1;
        !          1781: #endif /* CK_NEWTERM */
        !          1782: 
        !          1783: static long pct = 100, oldpct = 0;     /* Percent done */
        !          1784: static int oldtyp = 0, oldwin = -1, oldtry = -1, oldlen = -1;
        !          1785: 
        !          1786: #ifdef CK_ANSIC
        !          1787: void
        !          1788: screenc(int f, char c,long n,char *s)
        !          1789: #else
        !          1790: #ifdef MYCURSES
        !          1791: VOID
        !          1792: #else
        !          1793: int
        !          1794: #endif /* MYCURSES */
        !          1795: screenc(f,c,n,s)
        !          1796: int f;         /* argument descriptor */
        !          1797: char c;                /* a character or small integer */
        !          1798: long n;                /* a long integer */
        !          1799: char *s;       /* a string */
        !          1800: #endif /* CK_ANSIC */
        !          1801: /* screenc() */ {
        !          1802: 
        !          1803:     static int q = 0;
        !          1804:     static long fsiz = -1L;            /* Copy of file size */
        !          1805:     static long fcnt = 0L;             /* File count */
        !          1806:     static long fbyt = 0L;             /* Total file bytes */
        !          1807: 
        !          1808:     int len;                           /* Length of string */
        !          1809:     int x;                             /* Worker */
        !          1810: 
        !          1811:     if (cinit == 0 || cendw > 0) {     /* Handle borderline cases... */
        !          1812:        if (f == SCR_CW) {              /* Close window, but it's not open */
        !          1813:            ft_win = 0;
        !          1814:            return;
        !          1815:        }
        !          1816:        if (f == SCR_EM ||
        !          1817:           (f == SCR_PT && c == 'E')) { /* Fatal error before window open */
        !          1818:            conoll(""); conoc('?'); conoll(s); return; /* Regular display */
        !          1819:        }
        !          1820:     }
        !          1821:     if (cinit == 0) {                  /* Only call initscr() once */
        !          1822:        cendw = 1;                      /* New window needs repainting */
        !          1823: #ifdef COMMENT
        !          1824:        if (!initscr()) {               /* Oops, can't initialize window? */
        !          1825: /*
        !          1826:   In fact, this doesn't happen.  "man curses" says initscr() halts the
        !          1827:   entire program if it fails, which is true on the systems where I've
        !          1828:   tested it.  It will fail if your terminal type is not known to it.
        !          1829:   That's why SET FILE DISPLAY FULLSCREEN calls tgetent() to make sure the
        !          1830:   terminal type is known before allowing a curses display.
        !          1831: */
        !          1832:            fprintf(stderr,"CURSES INITSCR ERROR\r\n");
        !          1833:            fdispla = XYFD_R;           /* Go back to regular display */
        !          1834:            return;
        !          1835:        } else {
        !          1836:            cinit++;                    /* Window initialized ok */
        !          1837:            debug(F100,"CURSES INITSCR OK","",0);
        !          1838:        }
        !          1839: #else                                  /* Save some memory. */
        !          1840: #ifdef CK_NEWTERM
        !          1841:        /* (From Andy Fyfe <[email protected]>)
        !          1842:           System V curses seems to reserve the right to alter the buffering
        !          1843:           on the output FILE* without restoring it.  Fortunately System V
        !          1844:           curses provides newterm(), an alternative to initscr(), that
        !          1845:           allows us to specify explicitly the terminal type and input and
        !          1846:           output FILE pointers.  Thus we duplicate stdout, and let curses
        !          1847:           have the copy.  The original remains unaltered.  Unfortunately,
        !          1848:           newterm() seems to be particular to System V.
        !          1849:        */
        !          1850:        s = getenv("TERM");
        !          1851:        if (ck_fd < 0) {
        !          1852:            ck_fd = dup(fileno(stdout));
        !          1853:            ck_stdout = (ck_fd >= 0) ? fdopen(ck_fd, "w") : NULL;
        !          1854:        }
        !          1855:        if (ck_stdout == NULL || newterm(s, ck_stdout, stdin) == 0) {
        !          1856:            fprintf(stderr,
        !          1857:              "Fullscreen display not supported for terminal type: %s\r\n",s);
        !          1858:            fdispla = XYFD_R;           /* Go back to regular display */
        !          1859:            return;
        !          1860:        }
        !          1861: #else
        !          1862:        initscr();                      /* Initialize curses. */
        !          1863: #endif /* CK_NEWTERM */
        !          1864:        cinit++;                        /* Remember curses was initialized. */
        !          1865: #endif /* COMMENT */
        !          1866:     }
        !          1867:     ft_win = 1;                                /* Window is open */
        !          1868:     if (cendw) {                       /* endwin() was called previously */
        !          1869: #ifdef VMS
        !          1870:        initscr();                      /* (or should have been!) */
        !          1871:        clear();
        !          1872:        touchwin(stdscr);
        !          1873:        refresh();
        !          1874: #else /* All others... */
        !          1875:        clear();
        !          1876: #endif /* VMS */
        !          1877: 
        !          1878:        move(CW_BAN,0);                 /* Display the banner */
        !          1879:        if (*myhost) printw("%s, %s",versio,(char *)myhost);
        !          1880:        else printw("%s",versio);
        !          1881:        move(CW_DIR,3);  printw("Current Directory: %s",zgtdir());
        !          1882:        if (network) {
        !          1883:            move(CW_LIN,9); printw("Remote Host: %s",ttname);
        !          1884:        } else {
        !          1885:            move(CW_LIN,0);  printw("Communication Device: %s",ttname);
        !          1886:        }
        !          1887:        move(CW_SPD,1);  printw("Communication Speed: ");
        !          1888:        move(CW_SPD,22);                /* Speed */
        !          1889:        if (network) {
        !          1890:            printw("(network)");
        !          1891:        } else {
        !          1892:            if (speed < 0L) speed = ttgspd();
        !          1893:            if (speed > 0L) {
        !          1894:                if (speed == 8880) printw("75/1200");
        !          1895:                else printw("%ld",speed);
        !          1896:            } else printw("unknown");
        !          1897:        }
        !          1898:        move(CW_PAR,14); printw("Parity: %s",parnam((char)parity));
        !          1899:        move(CW_TYP,11); printw("File Type:");
        !          1900:        move(CW_SIZ,11); printw("File Size:");
        !          1901:        move(CW_PCD, 8); printw("Percent Done:");
        !          1902:        move(CW_TR,  1); printw("Estimated Time Left:");
        !          1903:        move(CW_WS,  8); printw("Window Slots:");
        !          1904:        move(CW_PT,  9); printw("Packet Type:");
        !          1905:        move(CW_PC,  8); printw("Packet Count:");
        !          1906:        move(CW_PL,  7); printw("Packet Length:");
        !          1907:        move(CW_PR,  2); printw("Packet Retry Count:");
        !          1908:        move(CW_PB,  2); printw("Packet Block Check:");
        !          1909:        move(CW_ERR,10); printw("Last Error:");
        !          1910:        move(CW_MSG, 8); printw("Last Message:");
        !          1911: #ifdef ATTSV
        !          1912: #ifndef aegis
        !          1913: #ifndef datageneral
        !          1914: #define CK_NEED_SIG
        !          1915: #endif /* datageneral */
        !          1916: #endif /* aegis */
        !          1917: #endif /* ATTSV */
        !          1918: #ifdef POSIX
        !          1919: #ifndef CK_NEED_SIG
        !          1920: #define CK_NEED_SIG
        !          1921: #endif /* CK_NEED_SIG */
        !          1922: #endif /* POSIX */
        !          1923: 
        !          1924: #ifdef CK_NEED_SIG
        !          1925:        move(CW_INT, 0); printw(
        !          1926: "<%s>X to cancel file, <%s>Z to cancel group, <%s><CR> to resend packet",
        !          1927:                                dbchr(escape), dbchr(escape), dbchr(escape));
        !          1928:        move(CW_INT + 1, 0); printw(
        !          1929: "<%s>E to send Error packet, or Ctrl-C to quit immediately.", dbchr(escape));
        !          1930: #else
        !          1931:        move(CW_INT, 0);
        !          1932: #ifdef OS2
        !          1933:        printw(
        !          1934:          "X to cancel file, Z to cancel group, <Enter> to resend packet,");
        !          1935: #else
        !          1936:        printw("X to cancel file, Z to cancel group, <CR> to resend packet,");
        !          1937: #endif /* OS2 */
        !          1938:        move(CW_INT + 1, 0);
        !          1939:        printw("E to send Error packet, or Ctrl-C to quit immediately.");
        !          1940: #endif /* CK_NEED_SIG */
        !          1941:        refresh();
        !          1942:        cendw = 0;
        !          1943:     }
        !          1944:     len = strlen(s);                   /* Length of argument string */
        !          1945: 
        !          1946:     debug(F101,"SCREENC switch","",f); /* Handle our function code */
        !          1947:     switch (f) {
        !          1948:       case SCR_FN:                     /* Filename */
        !          1949:        fsiz = -1L;                     /* Invalidate previous file size */
        !          1950:        move(CW_PCD,22);                /* Erase percent done from last time */
        !          1951:        clrtoeol();
        !          1952:        move(CW_SIZ,22);                /* Erase file size from last time */
        !          1953:        clrtoeol();
        !          1954:        move(CW_ERR,22);                /* And last error message */
        !          1955:        clrtoeol();
        !          1956:        if (what == W_SEND) {           /* If we're sending... */
        !          1957:            move(CW_NAM,13);
        !          1958:            printw("Sending:");
        !          1959:        } else if (what == W_RECV) {    /* If we're receiving... */
        !          1960:            move(CW_NAM,11);
        !          1961:            printw("Receiving:");
        !          1962:        } else {                        /* If we don't know... */
        !          1963:            move(CW_NAM,11);            /* (should never see this) */
        !          1964:            printw("File Name:");
        !          1965:        }
        !          1966:        move(CW_NAM,22);                /* Display the filename */
        !          1967:        if (len > 57) {
        !          1968:            printw("%.54s..",s);
        !          1969:            len = 57;
        !          1970:        } else printw("%s",s);
        !          1971:        q = len;                        /* Remember name length for later */
        !          1972:        clrtoeol();
        !          1973:        scrft();                        /* Display file type */
        !          1974:        refresh(); return;
        !          1975: 
        !          1976:       case SCR_AN:                     /* File as-name */
        !          1977:        if (q + len < 58) {             /* Will fit */
        !          1978:            move(CW_NAM, 22 + q);
        !          1979:            printw(" => %s",s);
        !          1980:        } else {                        /* Too long */
        !          1981:            move(CW_NAM, 22);           /* Overwrite previous name */
        !          1982:            q = 0;
        !          1983:            len = 54;
        !          1984:            printw(" => %.51s..", s);   /* Truncate */
        !          1985:        }
        !          1986:        q += len + 4;                   /* Remember horizontal position */
        !          1987:        clrtoeol(); refresh(); return;
        !          1988: 
        !          1989:       case SCR_FS:                     /* File size */
        !          1990:        fsiz = n;
        !          1991:        move(CW_SIZ,22);
        !          1992:        if (fsiz > -1L) printw("%ld",n);
        !          1993:        clrtoeol();
        !          1994:        scrft();                        /* File type */
        !          1995:        refresh(); return;
        !          1996: 
        !          1997:       case SCR_PT:                     /* Packet type or pseudotype */
        !          1998:        if (spackets < 5) {
        !          1999:            /* Things that won't change after the 4th packet */
        !          2000:            move(CW_PAR,22); printw("%s",parnam((char)parity)); clrtoeol();
        !          2001:            clrtoeol();
        !          2002:            move(CW_PB, 22);            /* Block check on this packet */
        !          2003:            if (bctu == 4) printw("B"); else printw("%d",bctu);
        !          2004:            clrtoeol();
        !          2005:        }
        !          2006: 
        !          2007:        x = (what == W_RECV) ?          /* Packet length */
        !          2008:          rpktl+1 :
        !          2009:            spktl+1;
        !          2010:        if (x != oldlen) {              /* But only if it changed. */
        !          2011:            move(CW_PL, 22);
        !          2012:            printw("%d",x);
        !          2013:            clrtoeol();
        !          2014:            oldlen = x;
        !          2015:        }
        !          2016:        move(CW_PC, 22);                /* Packet count (always). */
        !          2017:        printw("%d",spackets);          /* WARNING: this can slow us way */
        !          2018:        clrtoeol();                     /* down with short packets. */
        !          2019: 
        !          2020:        if (wcur != oldwin) {           /* Window slots, if changed. */
        !          2021:            move(CW_WS, 22);
        !          2022:            printw("%d of %d",wcur,wslotr);
        !          2023:            clrtoeol();
        !          2024:            oldwin = wcur;
        !          2025:        }
        !          2026:        if (retrans != oldtry) {        /* Retry count, if changed */
        !          2027:            move(CW_PR, 22);
        !          2028:            printw("%d",retrans);
        !          2029:            clrtoeol();
        !          2030:            oldtry = retrans;
        !          2031:        }
        !          2032:        if (c != oldtyp && c != 'Y' && c != 'N') { /* Sender's packet type */
        !          2033:            move(CW_PT,22);
        !          2034:            printw("%c",c);
        !          2035:            clrtoeol();
        !          2036:            oldtyp = c;
        !          2037:        }
        !          2038:        switch (c) {                    /* Now handle specific packet types */
        !          2039:          case 'S':                     /* Beginning of transfer */
        !          2040:            fcnt = fbyt = 0L;           /* Clear counters */
        !          2041:            break;
        !          2042:          case 'D':                     /* Data packet */
        !          2043:            if (fsiz > 0L) {            /* Show percent done if known */
        !          2044:                long s, x;
        !          2045:                oldpct = pct;           /* Remember previous percent */
        !          2046:                pct = (fsiz > 99L) ? (ffc / (fsiz / 100L)) : 0L; /* New one */
        !          2047:                if (pct > 100L ||       /* Allow expansion */
        !          2048:                    oldpct == 99L && pct < 0L) /* other boundary conditions */
        !          2049:                  pct = 100L;
        !          2050:                if (pct != oldpct) {    /* Only do this 100 times per file */
        !          2051:                    move(CW_PCD,22);
        !          2052:                    printw("%ld", pct);
        !          2053:                    clrtoeol();
        !          2054: 
        !          2055:                    /* Time remaining for this file */
        !          2056: 
        !          2057:                    s = (long) ((unsigned) gtimer() - fsecs); /* Secs so far */
        !          2058:                    if (s > 0L) {
        !          2059:                        /*
        !          2060:                          Time remaining must be calculated using the smallest
        !          2061:                          possible quantities, to prevent overflow:
        !          2062:                            (seconds_so_far * percent_left) / percent_done.
        !          2063:                          And avoid divide_by_zero.
        !          2064:                        */
        !          2065:                        x = (pct > 0L) ? ((s * (100 - pct)) / pct) : -1L;
        !          2066:                        if (x > -1L) {
        !          2067:                            move(CW_TR,22);
        !          2068:                            printw("%s",hhmmss(x));
        !          2069:                            clrtoeol();
        !          2070:                        }
        !          2071:                    }
        !          2072:                }
        !          2073:            }
        !          2074:            break;
        !          2075:          case 'E':                     /* Error packet */
        !          2076: #ifdef COMMENT
        !          2077:            move(CW_ERR,22);            /* Print its data field */
        !          2078:            if (*s) printw("%s",s);
        !          2079:            clrtoeol();
        !          2080: #endif /* COMMENT */
        !          2081:            fcnt = fbyt = 0;            /* So no bytes for this file */
        !          2082:            break;
        !          2083:          case 'Q':                     /* Crunched packet */
        !          2084:            move(CW_ERR,22);
        !          2085:            printw("Damaged Packet");
        !          2086:            clrtoeol();
        !          2087:            break;
        !          2088:          case 'T':                     /* Timeout */
        !          2089:            move(CW_ERR,22);
        !          2090:            printw("Timeout");
        !          2091:            clrtoeol();
        !          2092:            break;
        !          2093:          default:                      /* Others, do nothing */
        !          2094:            break;
        !          2095:        }
        !          2096:        refresh(); return;
        !          2097: 
        !          2098:       case SCR_ST:                     /* File transfer status */
        !          2099:        move(CW_PCD,22);                /* Update percent done */
        !          2100:        if (c == ST_OK) {               /* OK, print 100 % */
        !          2101:            pct = 100;
        !          2102:            printw("100");
        !          2103:        } else if (fsiz > 0L)           /* Not OK, update final percent */
        !          2104:          printw("%ld",( ffc * 100L ) / fsiz);
        !          2105:        clrtoeol();
        !          2106:        move(CW_MSG,22);                /* Remove any previous message */
        !          2107:        clrtoeol(); refresh();
        !          2108:        move(CW_TR, 22);
        !          2109:        clrtoeol(); refresh();
        !          2110: 
        !          2111:        switch (c) {                    /* Print new status message */
        !          2112:          case ST_OK:                   /* Transfer OK */
        !          2113:            fcnt++;                     /* Count this file */
        !          2114:            if (ffc > 0L)               /* For some reason ffc is off by 1 */
        !          2115:              fbyt += ffc - 1L;         /* Count its bytes */
        !          2116:            move(CW_MSG,22);
        !          2117:            printw("Transfer OK");      /* Say Transfer was OK */
        !          2118:            clrtoeol(); refresh();
        !          2119:            return;
        !          2120: 
        !          2121:          case ST_DISC:                 /* Discarded */
        !          2122:            move(CW_ERR,22); printw("File discarded");
        !          2123:            clrtoeol(); refresh();
        !          2124:            return;
        !          2125: 
        !          2126:          case ST_INT:                  /* Interrupted */
        !          2127:            move(CW_ERR,22); printw("Transfer interrupted");
        !          2128:            clrtoeol(); refresh();
        !          2129:            return;
        !          2130: 
        !          2131:          case ST_SKIP:                 /* Skipped */
        !          2132:            move(CW_ERR,22); printw("File skipped");
        !          2133:            clrtoeol(); refresh();
        !          2134:            return;
        !          2135: 
        !          2136:          case ST_ERR:                  /* Error message */
        !          2137:            move(CW_ERR,22); printw("%s",s);
        !          2138:            clrtoeol(); refresh();
        !          2139:            return;
        !          2140: 
        !          2141:          case ST_REFU:                 /* Refused */
        !          2142:            move(CW_ERR,22);
        !          2143:            if (*s)
        !          2144:              printw("Refused, %s",s);
        !          2145:            else printw("Refused");
        !          2146:            clrtoeol(); refresh();
        !          2147:            return;
        !          2148: 
        !          2149:          case ST_INC:
        !          2150:            move(CW_ERR,22); printw("Incomplete");
        !          2151:            clrtoeol(); refresh();
        !          2152:            return;
        !          2153: 
        !          2154:          default:                      /* Bad call */
        !          2155:            move(CW_ERR,22); printw("*** screen() called with bad status ***");
        !          2156:            clrtoeol(); refresh(); return;
        !          2157:        }
        !          2158: 
        !          2159:       case SCR_TC:                     /* Transaction complete */      
        !          2160:        move(CW_MSG,22);                /* Print statistics in message line */
        !          2161:        if (tsecs > 0)
        !          2162:          printw("Files: %ld, Total Bytes: %ld, %ld cps",
        !          2163:                 fcnt, fbyt, ((fbyt * 10L) / (long) tsecs) / 10L);
        !          2164:        else printw("Files: %ld, Total Bytes: %ld",fcnt,fbyt);
        !          2165:        clrtoeol();
        !          2166:        move(CW_TR, 1);
        !          2167:        printw("       Elapsed Time: %s",hhmmss((long)tsecs));
        !          2168:        clrtoeol();
        !          2169:        move(23,0); clrtoeol();         /* Clear instructions lines */
        !          2170:        move(22,0); clrtoeol();         /* to make room for prompt. */
        !          2171:        refresh();
        !          2172: #ifndef VMSCURSE
        !          2173:        endwin();
        !          2174: #endif /* VMSCURSE */
        !          2175:        pct = 100; oldpct = 0;          /* Reset these for next time. */
        !          2176:        oldtyp = 0; oldwin = -1; oldtry = -1; oldlen = -1;
        !          2177:        cendw = 1; conoc(BEL);          /* Close window, then beep. */
        !          2178:        ft_win = 0;                     /* Window closed. */
        !          2179:        return;
        !          2180: 
        !          2181:       case SCR_EM:                     /* Error packet (fatal) */
        !          2182:        move (CW_ERR,22);
        !          2183:        printw("? %s",s);
        !          2184:        conoc(BEL);
        !          2185:        clrtoeol(); refresh(); return;
        !          2186: 
        !          2187:       case SCR_QE:                     /* Quantity equals */
        !          2188:       case SCR_TU:                     /* Undelimited text */
        !          2189:       case SCR_TN:                     /* Text delimited at start */
        !          2190:       case SCR_TZ:                     /* Text delimited at end */
        !          2191:        return;                         /* (ignored in fullscreen display) */
        !          2192: 
        !          2193:       case SCR_XD:                     /* X-packet data */
        !          2194:        move(CW_NAM,22);
        !          2195:        printw("%s",s);
        !          2196:        clrtoeol(); refresh(); return;
        !          2197: 
        !          2198:       case SCR_CW:                     /* Close Window */
        !          2199:        clrtoeol(); move(23,0); clrtoeol(); move(22,0); clrtoeol();
        !          2200:        refresh();
        !          2201:        pct = 100; oldpct = 0;          /* Reset these for next time. */
        !          2202:        oldtyp = 0; oldwin = -1; oldtry = -1; oldlen = -1;
        !          2203: 
        !          2204: #ifndef VMSCURSE
        !          2205:        endwin();
        !          2206: #endif /* VMSCURSE */
        !          2207:        ft_win = 0;                     /* Flag that window is closed. */
        !          2208:        cendw = 1; return;
        !          2209: 
        !          2210:       default:                         /* Bad call */
        !          2211:        move (CW_ERR,22);
        !          2212:        printw("*** screen() called with bad function code ***");
        !          2213:        clrtoeol(); refresh(); return;
        !          2214:     }
        !          2215: }
        !          2216: #endif /* CK_CURSES */
        !          2217: 
        !          2218: #endif /* MAC */

unix.superglobalmegacorp.com

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