Annotation of coherent/g/usr/bin/ckermit/ckuusx.c, revision 1.1.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.