|
|
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, copy, or ! 9: redistribute this software so long as it is not sold for profit, provided this ! 10: copyright notice is retained. ! 11: */ ! 12: ! 13: /* ! 14: This module contains user interface functions needed by both the interactive ! 15: user interface and the command-line-only user interface. ! 16: */ ! 17: ! 18: /* Includes */ ! 19: ! 20: #include "ckcdeb.h" ! 21: #include "ckcasc.h" ! 22: #include "ckcker.h" ! 23: #include "ckuusr.h" ! 24: #include <signal.h> ! 25: ! 26: #ifdef VMS ! 27: #include <descrip.h> ! 28: #include <ssdef.h> ! 29: #include <stsdef.h> ! 30: #endif /* VMS */ ! 31: ! 32: /* Variables declared here */ ! 33: ! 34: #ifdef DEBUG ! 35: char debfil[50]; /* Debugging log file name */ ! 36: #endif /* DEBUG */ ! 37: ! 38: #ifdef TLOG ! 39: char trafil[50]; /* Transaction log file name */ ! 40: #endif /* TLOG */ ! 41: ! 42: char pktfil[50]; /* Packet log file name */ ! 43: char sesfil[50]; /* Session log file name */ ! 44: ! 45: #ifndef NOFRILLS ! 46: char optbuf[50]; /* Options for MAIL or REMOTE PRINT */ ! 47: #endif /* NOFRILLS */ ! 48: char cmdstr[256]; /* Place to build generic command */ ! 49: ! 50: char fspec[FSPECL]; /* Filename string for \v(filespec) */ ! 51: ! 52: int success = 1, /* Command success/failure flag */ ! 53: ! 54: #ifndef NOSPL ! 55: cmdlvl = 0, /* Command level */ ! 56: #endif /* NOSPL */ ! 57: action, /* Action selected on command line*/ ! 58: sessft = 0, /* Session log file type, 0 = text */ ! 59: pflag = 1; /* Print prompt & messages */ ! 60: ! 61: #ifndef NOMSEND /* Multiple SEND */ ! 62: char *msfiles[MSENDMAX]; ! 63: #endif /* NOMSEND */ ! 64: ! 65: /* External variables */ ! 66: ! 67: extern int local, quiet, binary, bctu, rptflg, ebqflg, network, server, ! 68: what, spsiz, urpsiz, wmax, czseen, cxseen, winlo, displa, timint, ! 69: npad, ebq, ebqflg, bctr, rptq, atcapu, lpcapu, swcapu, wslotn, wslotr, rtimo, ! 70: mypadn, sq, capas, rpsiz, tsecs, dfloc, tralog, pktlog, seslog, lscapu, ! 71: xitsta, escape, tlevel, bgset, backgrd, wslots, suspend, srvdis; ! 72: ! 73: extern long speed, filcnt, ffc, rptn, fsize; ! 74: ! 75: extern CHAR *rdatap, padch, seol, ctlq, mypadc, eol; ! 76: ! 77: extern char ttname[], *dftty, *cmarg, **cmlist; ! 78: #ifndef NOICP ! 79: #ifdef DCMDBUF ! 80: extern char *cmdbuf; /* Command buffer */ ! 81: #else ! 82: extern char cmdbuf[]; /* Command buffer */ ! 83: #endif /* DCMDBUF */ ! 84: #endif /* NOICP */ ! 85: ! 86: #ifndef NOCCTRAP ! 87: #include <setjmp.h> /* Control-C trap */ ! 88: jmp_buf cmjbuf; ! 89: #endif /* NOCCTRAP */ ! 90: ! 91: /* S D E B U -- Record spar results in debugging log */ ! 92: ! 93: VOID ! 94: sdebu(len) int len; { ! 95: debug(F111,"spar: data",(char *) rdatap,len); ! 96: debug(F101," spsiz ","", spsiz); ! 97: debug(F101," timint","",timint); ! 98: debug(F101," npad ","", npad); ! 99: debug(F101," padch ","", padch); ! 100: debug(F101," seol ","", seol); ! 101: debug(F101," ctlq ","", ctlq); ! 102: debug(F101," ebq ","", ebq); ! 103: debug(F101," ebqflg","",ebqflg); ! 104: debug(F101," bctr ","", bctr); ! 105: debug(F101," rptq ","", rptq); ! 106: debug(F101," rptflg","",rptflg); ! 107: debug(F101," lscapu","",lscapu); ! 108: debug(F101," atcapu","",atcapu); ! 109: debug(F101," lpcapu","",lpcapu); ! 110: debug(F101," swcapu","",swcapu); ! 111: debug(F101," wslotn","", wslotn); ! 112: } ! 113: /* R D E B U -- Debugging display of rpar() values */ ! 114: ! 115: VOID ! 116: rdebu(d,len) CHAR *d; int len; { ! 117: debug(F111,"rpar: data",d,len); ! 118: debug(F101," rpsiz ","", xunchar(d[0])); ! 119: debug(F101," rtimo ","", rtimo); ! 120: debug(F101," mypadn","",mypadn); ! 121: debug(F101," mypadc","",mypadc); ! 122: debug(F101," eol ","", eol); ! 123: debug(F101," ctlq ","", ctlq); ! 124: debug(F101," sq ","", sq); ! 125: debug(F101," ebq ","", ebq); ! 126: debug(F101," ebqflg","",ebqflg); ! 127: debug(F101," bctr ","", bctr); ! 128: debug(F101," rptq ","", d[8]); ! 129: debug(F101," rptflg","",rptflg); ! 130: debug(F101," capas ","", capas); ! 131: debug(F101," bits ","",d[capas]); ! 132: debug(F101," lscapu","",lscapu); ! 133: debug(F101," atcapu","",atcapu); ! 134: debug(F101," lpcapu","",lpcapu); ! 135: debug(F101," swcapu","",swcapu); ! 136: debug(F101," wslotr","", wslotr); ! 137: debug(F101," rpsiz(extended)","",rpsiz); ! 138: } ! 139: ! 140: /* F A T A L -- Fatal error message */ ! 141: ! 142: VOID ! 143: fatal(msg) char *msg; { ! 144: screen(SCR_EM,0,0L,msg); ! 145: debug(F110,"fatal",msg,0); ! 146: tlog(F110,"Fatal:",msg,0L); ! 147: doexit(BAD_EXIT,xitsta); /* Exit indicating failure */ ! 148: } ! 149: ! 150: /* B L D L E N -- Make length-encoded copy of string */ ! 151: ! 152: char * ! 153: bldlen(str,dest) char *str, *dest; { ! 154: int len; ! 155: len = (int)strlen(str); ! 156: *dest = tochar(len); ! 157: strcpy(dest+1,str); ! 158: return(dest+len+1); ! 159: } ! 160: ! 161: ! 162: /* S E T G E N -- Construct a generic command */ ! 163: ! 164: CHAR ! 165: #ifdef CK_ANSIC ! 166: setgen(char type,char * arg1, char * arg2, char * arg3) ! 167: #else ! 168: setgen(type,arg1,arg2,arg3) char type, *arg1, *arg2, *arg3; ! 169: #endif /* CK_ANSIC */ ! 170: /* setgen */ { ! 171: char *upstr, *cp; ! 172: ! 173: cp = cmdstr; ! 174: *cp++ = type; ! 175: *cp = NUL; ! 176: if (*arg1 != NUL) { ! 177: upstr = bldlen(arg1,cp); ! 178: if (*arg2 != NUL) { ! 179: upstr = bldlen(arg2,upstr); ! 180: if (*arg3 != NUL) bldlen(arg3,upstr); ! 181: } ! 182: } ! 183: cmarg = cmdstr; ! 184: debug(F110,"setgen",cmarg,0); ! 185: ! 186: return('g'); ! 187: } ! 188: ! 189: #ifndef NOMSEND ! 190: static char *mgbufp = NULL; ! 191: ! 192: /* F N P A R S E -- */ ! 193: ! 194: /* ! 195: Argument is a character string containing one or more filespecs. ! 196: This function breaks the string apart into an array of pointers, one ! 197: to each filespec, and returns the number of filespecs. Used by server ! 198: when it receives a GET command to allow it to process multiple file ! 199: specifications in one transaction. Sets cmlist to point to a list of ! 200: file pointers, exactly as if they were command line arguments. ! 201: ! 202: This version of fnparse treats spaces as filename separators. If your ! 203: operating system allows spaces in filenames, you'll need a different ! 204: separator. ! 205: ! 206: This version of fnparse mallocs a string buffer to contain the names. It ! 207: cannot assume that the string that is pointed to by the argument is safe. ! 208: */ ! 209: int ! 210: fnparse(string) char *string; { ! 211: char *p, *s, *q; ! 212: int r = 0, x; /* Return code */ ! 213: ! 214: if (mgbufp) free(mgbufp); /* Free this from last time. */ ! 215: mgbufp = malloc((int)strlen(string)+2); ! 216: if (!mgbufp) { ! 217: debug(F100,"fnparse malloc error","",0); ! 218: return(0); ! 219: } ! 220: #ifndef NOICP ! 221: #ifndef NOSPL ! 222: strncpy(fspec,string,FSPECL); /* Make copy for \v(filespec) */ ! 223: #endif /* NOSPL */ ! 224: #endif /* NOICP */ ! 225: s = string; /* Input string */ ! 226: p = q = mgbufp; /* Point to the copy */ ! 227: r = 0; /* Initialize our return code */ ! 228: while (*s == SP) s++; /* Skip leading spaces */ ! 229: while (1) { /* Loop through rest of string */ ! 230: if (*s == CMDQ) { /* Backslash (quote character)? */ ! 231: if ((x = xxesc(&s)) > -1) { /* Go interpret it. */ ! 232: *q++ = (char) x; /* Numeric backslash code, ok */ ! 233: } else { /* Just let it quote next char */ ! 234: s++; /* get past the backslash */ ! 235: *q++ = *s++; /* deposit next char */ ! 236: } ! 237: continue; ! 238: } else if (*s == SP || *s == NUL) { /* Unquoted space or NUL? */ ! 239: *q++ = NUL; /* End of output filename. */ ! 240: msfiles[r] = p; /* Add this filename to the list */ ! 241: debug(F111,"fnparse",msfiles[r],r); ! 242: r++; /* Count it */ ! 243: if (*s == NUL) break; /* End of string? */ ! 244: while (*s == SP) s++; /* Skip repeated spaces */ ! 245: p = q; /* Start of next name */ ! 246: continue; ! 247: } else *q++ = *s; /* Otherwise copy the character */ ! 248: s++; /* Next input character */ ! 249: } ! 250: debug(F101,"fnparse r","",r); ! 251: cmlist = msfiles; ! 252: return(r); ! 253: } ! 254: #endif /* NOMSEND */ ! 255: ! 256: char * /* dbchr() for DEBUG SESSION */ ! 257: dbchr(c) int c; { ! 258: static char s[8]; ! 259: char *cp = s; ! 260: ! 261: c &= 0xff; ! 262: if (c & 0x80) { /* 8th bit on */ ! 263: sprintf(cp++,"~"); ! 264: c &= 0x7f; ! 265: } ! 266: if (c < SP) { /* Control character */ ! 267: sprintf(cp,"^%c",ctl(c)); ! 268: } else if (c == DEL) { ! 269: sprintf(cp,"^?"); ! 270: } else { /* Printing character */ ! 271: sprintf(cp,"%c",c); ! 272: } ! 273: cp = s; /* Return pointer to it */ ! 274: return(cp); ! 275: } ! 276: ! 277: /* C K H O S T -- Get name of local host (where C-Kermit is running) */ ! 278: ! 279: /* ! 280: Call with pointer to buffer to put hostname in, and length of buffer. ! 281: Copies hostname into buffer on success, puts null string in buffer on ! 282: failure. ! 283: */ ! 284: #ifdef ATTSV ! 285: #include <sys/utsname.h> ! 286: #endif /* ATTSV */ ! 287: ! 288: VOID ! 289: ckhost(vvbuf,vvlen) char * vvbuf; int vvlen; { ! 290: char *g; ! 291: #ifdef VMS ! 292: int x; ! 293: #endif /* VMS */ ! 294: #ifdef ATTSV ! 295: struct utsname hname; ! 296: #endif /* ATTSV */ ! 297: ! 298: *vvbuf = NUL; ! 299: #ifdef ATTSV ! 300: if (uname(&hname) > -1) strncpy(vvbuf,hname.nodename,vvlen); ! 301: #else ! 302: #ifdef BSD4 ! 303: if (gethostname(vvbuf,vvlen) < 0) *vvbuf = NUL; ! 304: #else ! 305: #ifdef VMS ! 306: g = getenv("SYS$NODE"); ! 307: if (g) strncpy(vvbuf,g,vvlen); ! 308: x = (int)strlen(vvbuf); ! 309: if (x > 1 && vvbuf[x-1] == ':' && vvbuf[x-2] == ':') vvbuf[x-2] = NUL; ! 310: #endif /* VMS */ ! 311: #endif /* BSD4 */ ! 312: #endif /* ATTSV */ ! 313: if (*vvbuf == NUL) { /* If it's still empty */ ! 314: g = getenv("HOST"); /* try this */ ! 315: if (g) strncpy(vvbuf,g,vvlen); ! 316: } ! 317: vvbuf[vvlen-1] = NUL; /* Make sure result is terminated. */ ! 318: } ! 319: ! 320: #ifndef NOSPL ! 321: #define ASKMORE ! 322: #endif /* NOSPL */ ! 323: #ifndef NOHELP ! 324: #define ASKMORE ! 325: #endif /* NOHELP */ ! 326: ! 327: #ifdef ASKMORE ! 328: /* ! 329: A S K M O R E -- Poor person's "more". ! 330: Returns 0 if no more, 1 if more wanted. ! 331: Presently used by SHO MAC, SHO GLOB, and HELP, so compiled out if ! 332: those options are also compiled out. ! 333: */ ! 334: int ! 335: askmore() { ! 336: char c; int rv; ! 337: ! 338: rv = -1; ! 339: while (rv < 0) { ! 340: #ifdef UNIX ! 341: #ifdef NOSETBUF ! 342: printf("more? "); ! 343: fflush(stdout); ! 344: #endif /* NOSETBUF */ ! 345: #endif /* UNIX */ ! 346: c = coninc(0); ! 347: switch (c) { ! 348: /* Yes */ ! 349: case SP: case 'y': case 'Y': case 012: case 015: ! 350: printf("\015 \015"); ! 351: rv = 1; ! 352: break; ! 353: /* No */ ! 354: case 'n': case 'N': case 'q': case 'Q': ! 355: printf("\015\012"); ! 356: rv = 0; ! 357: break; ! 358: /* Invalid answer */ ! 359: default: ! 360: printf("Y or space-bar for yes, N for no\n"); ! 361: continue; ! 362: } ! 363: } ! 364: return(rv); ! 365: } ! 366: #endif /* ASKMORE */ ! 367: ! 368: /* T R A P -- Terminal interrupt handler */ ! 369: ! 370: SIGTYP ! 371: trap(sig) int sig; { ! 372: #ifdef VMS ! 373: int i; FILE *f; ! 374: #endif /* VMS */ ! 375: #ifdef GEMDOS ! 376: /* GEM is not reentrant, no i/o from interrupt level */ ! 377: longjmp(cmjbuf,1); /* Jump back to parser now! */ ! 378: #endif /* GEMDOS */ ! 379: debug(F101,"^C trap() caught signal","",sig); ! 380: zclose(ZIFILE); /* If we were transferring a file, */ ! 381: zclose(ZOFILE); /* close it. */ ! 382: #ifdef VMS ! 383: /* ! 384: Fix terminal. ! 385: */ ! 386: conres(); ! 387: i = printf("^C...\n"); /* Echo ^C to standard output */ ! 388: if (i < 1 && ferror(stdout)) { /* If there was an error */ ! 389: fclose(stdout); /* close standard output */ ! 390: f = fopen(dftty, "w"); /* open the controlling terminal */ ! 391: if (f) stdout = f; /* and make it standard output */ ! 392: printf("^C...\n"); /* and echo the ^C again. */ ! 393: } ! 394: #else ! 395: printf("^C...\n"); /* Not VMS, no problem... */ ! 396: #endif /* VMS */ ! 397: ! 398: #ifndef NOCCTRAP ! 399: #ifdef UNIX ! 400: ttimoff(); /* Turn off any timer interrupts */ ! 401: #endif /* UNIX */ ! 402: #ifdef OSK ! 403: ttimoff(); /* Turn off any timer interrupts */ ! 404: #endif /* OSK */ ! 405: longjmp(cmjbuf,1); /* Jump back to parser */ ! 406: #else ! 407: /* No Ctrl-C trap, just exit. */ ! 408: doexit(BAD_EXIT,what); /* Exit poorly */ ! 409: #endif /* NOCCTRAP */ ! 410: } ! 411: ! 412: /* C C _ C L E A N -- Cleanup after terminal interrupt handler */ ! 413: ! 414: #ifdef GEMDOS ! 415: int ! 416: cc_clean() { ! 417: zclose(ZIFILE); /* If we were transferring a file, */ ! 418: zclose(ZOFILE); /* close it. */ ! 419: printf("^C...\n"); /* Not VMS, no problem... */ ! 420: } ! 421: #endif /* GEMDOS */ ! 422: ! 423: ! 424: /* S T P T R A P -- Handle SIGTSTP (suspend) signals */ ! 425: ! 426: SIGTYP ! 427: stptrap(sig) int sig; { ! 428: #ifndef NOJC ! 429: int x; extern int cmflgs; ! 430: debug(F101,"stptrap() caught signal","",sig); ! 431: if (!suspend) { ! 432: printf("\r\nsuspend disabled\r\n"); ! 433: #ifndef NOICP ! 434: if (what == W_COMMAND) { /* If command parsing was */ ! 435: prompt(xxstring); /* reissue the prompt and partial */ ! 436: if (!cmflgs) /* command (if any) */ ! 437: printf("%s",cmdbuf); ! 438: } ! 439: #endif /* NOICP */ ! 440: } else { ! 441: conres(); /* Reset the console */ ! 442: #ifndef OS2 ! 443: x = psuspend(suspend); /* Try to suspend. */ ! 444: if (x < 0) ! 445: #endif /* OS2 */ ! 446: printf("Job control not supported\r\n"); ! 447: conint(trap,stptrap); /* Rearm the trap. */ ! 448: debug(F100,"stptrap back from suspend","",0); ! 449: switch (what) { ! 450: case W_CONNECT: /* If suspended during CONNECT? */ ! 451: conbin((char)escape); /* put console back in binary mode */ ! 452: debug(F100,"stptrap W_CONNECT","",0); ! 453: break; ! 454: #ifndef NOICP ! 455: case W_COMMAND: /* Suspended in command mode */ ! 456: debug(F101,"stptrap W_COMMAND pflag","",pflag); ! 457: concb((char)escape); /* Put back CBREAK tty mode */ ! 458: if (pflag) { /* If command parsing was */ ! 459: prompt(xxstring); /* reissue the prompt and partial */ ! 460: if (!cmflgs) /* command (if any) */ ! 461: printf("%s",cmdbuf); ! 462: } ! 463: break; ! 464: #endif /* NOICP */ ! 465: default: /* All other cases... */ ! 466: debug(F100,"stptrap default","",0); ! 467: concb((char)escape); /* Put it back in CBREAK mode */ ! 468: break; ! 469: } ! 470: } ! 471: #endif /* NOJC */ ! 472: } ! 473: ! 474: #ifndef MAC ! 475: /* ! 476: The rest of this file is for all implementations but the Macintosh. ! 477: */ ! 478: ! 479: /* C H K I N T -- Check for console interrupts */ ! 480: ! 481: int ! 482: chkint() { ! 483: int ch, cn; long zz; ! 484: ! 485: if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */ ! 486: #ifdef datageneral ! 487: cn = (con_reads_mt) ? 1 : conchk(); /* Any input waiting? */ ! 488: #else ! 489: cn = conchk(); /* Any input waiting? */ ! 490: #endif /* datageneral */ ! 491: debug(F101,"conchk","",cn); ! 492: ! 493: if (cn < 1) return(0); ! 494: ! 495: #ifdef datageneral ! 496: /* We must be careful to just print out one result for each character ! 497: * read. The flag, conint_avl, controls duplication of characters. ! 498: * Only one character is handled at a time, which is a reasonable ! 499: * limit. More complicated schemes could handle a buffer. ! 500: */ ! 501: if (con_reads_mt) { ! 502: if ((ch = conint_ch) <= 0) return(0); /* I/O error, or no data */ ! 503: else if (conint_avl == 0) return(0); /* Char already read */ ! 504: else conint_avl = 0; /* Flag char as read */ ! 505: } ! 506: else { if ((ch = coninc(5)) < 0) return(0); } ! 507: #else ! 508: if ((ch = coninc(5)) < 0) return(0); ! 509: #endif /* datageneral */ ! 510: switch (ch & 0177) { ! 511: case 'A': case 'a': case 0001: /* Status report */ ! 512: screen(SCR_TN,0,0l,"Status report:"); ! 513: screen(SCR_TN,0,0l," file type: "); ! 514: if (binary) { ! 515: #ifdef VMS ! 516: if (binary == XYFT_I) ! 517: screen(SCR_TZ,0,0l,"image"); ! 518: else if (binary == XYFT_L) ! 519: screen(SCR_TZ,0,0l,"labeled"); ! 520: else screen(SCR_TZ,0,0l,"binary"); ! 521: #else ! 522: screen(SCR_TZ,0,0l,"binary"); ! 523: #endif /* VMS */ ! 524: } else { ! 525: screen(SCR_TZ,0,0l,"text"); ! 526: } ! 527: screen(SCR_QE,0,filcnt," file number"); ! 528: if (fsize) screen(SCR_QE,0,fsize," size"); ! 529: screen(SCR_QE,0,ffc, " characters so far"); ! 530: if (fsize) { ! 531: zz = ( ffc * 100L ) / fsize; ! 532: screen(SCR_QE,0,zz, " percent done"); ! 533: } ! 534: screen(SCR_QE,0,(long)bctu, " block check"); ! 535: screen(SCR_QE,0,(long)rptflg," compression"); ! 536: screen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing"); ! 537: screen(SCR_QE,0,(long)lscapu," locking shifts"); ! 538: if (!network) ! 539: screen(SCR_QE,0, speed, " speed"); ! 540: if (what == W_SEND) ! 541: screen(SCR_QE,0,(long)spsiz, " packet length"); ! 542: else if (what == W_RECV || what == W_REMO) ! 543: screen(SCR_QE,0,(long)urpsiz," packet length"); ! 544: screen(SCR_QE,0,(long)wslots, " window slots"); ! 545: return(0); ! 546: ! 547: case 'B': case 'b': case 0002: /* Cancel batch */ ! 548: case 'Z': case 'z': case 0032: ! 549: screen(SCR_TN,0,0l,"Cancelling Batch "); ! 550: czseen = 1; ! 551: return(0); ! 552: ! 553: case 'F': case 'f': case 0006: /* Cancel file */ ! 554: case 'X': case 'x': case 0030: ! 555: screen(SCR_TN,0,0l,"Cancelling File "); ! 556: cxseen = 1; ! 557: return(0); ! 558: ! 559: case 'R': case 'r': case 0022: /* Resend */ ! 560: case 0015: case 0012: ! 561: screen(SCR_TN,0,0l,"Resending packet "); ! 562: resend(winlo); ! 563: return(1); ! 564: ! 565: case 'E': case 'e': /* Send error packet */ ! 566: case 0005: ! 567: return(-1); ! 568: ! 569: default: /* Anything else, print message */ ! 570: intmsg(1); ! 571: return(0); ! 572: } ! 573: } ! 574: ! 575: /* I N T M S G -- Issue message about terminal interrupts */ ! 576: ! 577: VOID ! 578: intmsg(n) long n; { ! 579: char buf[80]; ! 580: ! 581: if (!displa || quiet) /* Not if we're being quiet */ ! 582: return; ! 583: if (server && (!srvdis || n > -1L)) /* Special for server */ ! 584: return; ! 585: buf[0] = NUL; /* Keep compilers happy */ ! 586: #ifdef ATTSV ! 587: conchk(); /* Clear out pending escape-signals */ ! 588: #endif /* ATTSV */ ! 589: #ifdef VMS ! 590: conres(); /* So Ctrl-C will work */ ! 591: #endif /* VMS */ ! 592: if ((!server && n == 1L) || (server && n < 0L)) { ! 593: ! 594: #ifdef ATTSV /* We need to signal before kb input */ ! 595: #ifndef aegis ! 596: #ifndef datageneral ! 597: sprintf(buf,"Type escape character (%s) followed by:",dbchr(escape)); ! 598: screen(SCR_TN,0,0l,buf); ! 599: #endif /* datageneral */ ! 600: #endif /* aegis */ ! 601: #endif /* ATTSV */ ! 602: ! 603: screen(SCR_TN,0,0l,"X to cancel file, CR to resend current packet"); ! 604: screen(SCR_TN,0,0l,"Z to cancel group, A for status report"); ! 605: screen(SCR_TN,0,0l,"E to send Error packet, Ctrl-C to quit immediately: "); ! 606: /* if (server) */ screen(SCR_TN,0,0l,""); ! 607: } ! 608: else screen(SCR_TU,0,0l," "); ! 609: } ! 610: ! 611: /* S C R E E N -- Screen display function */ ! 612: ! 613: /* screen(f,c,n,s) ! 614: f - argument descriptor ! 615: c - a character or small integer ! 616: n - a long integer ! 617: s - a string. ! 618: Fill in this routine with the appropriate display update for the system. ! 619: This version is for a dumb tty. ! 620: */ ! 621: VOID ! 622: #ifdef CK_ANSIC ! 623: screen(int f, char c,long n,char *s) ! 624: #else ! 625: screen(f,c,n,s) int f; char c; long n; char *s; ! 626: #endif /* CK_ANSIC */ ! 627: /* screen */ { ! 628: static int p = 0; /* Screen position */ ! 629: int len; /* Length of string */ ! 630: char buf[80]; /* Output buffer */ ! 631: len = (int)strlen(s); /* Length of string */ ! 632: if ((f != SCR_WM) && (f != SCR_EM)) /* Always update warning & errors */ ! 633: if (!displa || quiet || backgrd || (server && !srvdis)) ! 634: return; ! 635: ! 636: switch (f) { ! 637: ! 638: case SCR_FN: /* filename */ ! 639: conoll(""); conol(s); conoc(SP); p = len + 1; return; ! 640: ! 641: case SCR_AN: /* as-name */ ! 642: if (p + len > 75) { conoll(""); p = 0; } ! 643: conol("=> "); conol(s); if ((p += (len + 3)) > 78) { conoll(""); p = 0; } ! 644: return; ! 645: ! 646: case SCR_FS: /* file-size */ ! 647: sprintf(buf,", Size: %ld",n); conoll(buf); p = 0; return; ! 648: ! 649: case SCR_XD: /* x-packet data */ ! 650: conoll(""); conoll(s); p = 0; return; ! 651: ! 652: case SCR_ST: /* File status */ ! 653: switch (c) { ! 654: case ST_OK: /* Transferred OK */ ! 655: if ((p += 5) > 78) { conoll(""); p = 0; } ! 656: conoll(" [OK]"); p += 5; return; ! 657: ! 658: case ST_DISC: /* Discarded */ ! 659: if ((p += 12) > 78) { conoll(""); p = 0; } ! 660: conoll(" [discarded]"); p += 12; return; ! 661: ! 662: case ST_INT: /* Interrupted */ ! 663: if ((p += 14) > 78) { conoll(""); p = 0; } ! 664: conoll(" [interrupted]"); p += 14; return; ! 665: ! 666: case ST_SKIP: /* Skipped */ ! 667: conoll(""); ! 668: conol("Skipping "); conoll(s); p = 0; ! 669: return; ! 670: ! 671: case ST_ERR: ! 672: conoll(""); ! 673: conol("Error "); conoll(s); p = 0; ! 674: return; ! 675: ! 676: case ST_REFU: ! 677: conoll(""); ! 678: conol("Refused: "); conoll(s); p = 0; ! 679: return; ! 680: ! 681: default: ! 682: conoll("*** screen() called with bad status ***"); p = 0; return; ! 683: } ! 684: ! 685: case SCR_PN: /* Packet number */ ! 686: sprintf(buf,"%s: %ld",s,n); conol(buf); p += (int)strlen(buf); return; ! 687: ! 688: case SCR_PT: /* Packet type or pseudotype */ ! 689: if (c == 'Y') return; /* Don't bother with ACKs */ ! 690: if (c == 'D') { /* Only show every 4th data packet */ ! 691: if (n % 4) return; ! 692: c = '.'; ! 693: } ! 694: #ifndef AMIGA ! 695: if (p++ > 77) { /* If near right margin, */ ! 696: conoll(""); /* Start new line */ ! 697: p = 0; /* and reset counter. */ ! 698: } ! 699: #endif /* AMIGA */ ! 700: conoc(c); /* Display the character. */ ! 701: #ifdef AMIGA ! 702: if (c == 'G') conoll(""); /* new line after G packets */ ! 703: #endif /* AMIGA */ ! 704: return; ! 705: ! 706: case SCR_TC: /* transaction complete */ ! 707: conoc(BEL); return; ! 708: ! 709: case SCR_EM: /* Error message */ ! 710: conoll(""); conoc('?'); conoll(s); p = 0; return; /* +1 */ ! 711: ! 712: case SCR_WM: /* Warning message */ ! 713: conoll(""); conoll(s); p = 0; return; ! 714: ! 715: case SCR_TU: /* Undelimited text */ ! 716: if ((p += len) > 77) { conoll(""); p = len; } ! 717: conol(s); return; ! 718: ! 719: case SCR_TN: /* Text delimited at beginning */ ! 720: conoll(""); conol(s); p = len; return; ! 721: ! 722: case SCR_TZ: /* Text delimited at end */ ! 723: if ((p += len) > 77) { conoll(""); p = len; } ! 724: conoll(s); return; ! 725: ! 726: case SCR_QE: /* Quantity equals */ ! 727: sprintf(buf,"%s: %ld",s,n); ! 728: conoll(buf); p = 0; return; ! 729: ! 730: default: ! 731: conoll("*** screen() called with bad object ***"); p = 0; return; ! 732: } ! 733: } ! 734: ! 735: /* E R M S G -- Nonfatal error message */ ! 736: ! 737: /* Should be used only for printing the message text from an Error packet. */ ! 738: ! 739: VOID ! 740: ermsg(msg) char *msg; { /* Print error message */ ! 741: if (local && !quiet) { ! 742: #ifdef OSK ! 743: printf("\n%s %s\n","Protocol Error:",msg); ! 744: #else ! 745: printf("\r\n%s %s\r\n","Protocol Error:",msg); ! 746: #endif /* OSK */ ! 747: } ! 748: tlog(F110,"Protocol Error:",msg,0L); ! 749: } ! 750: ! 751: VOID ! 752: doclean() { /* General cleanup upon exit */ ! 753: #ifndef NOICP ! 754: #ifndef NOSPL ! 755: extern struct mtab *mactab; /* For ON_EXIT macro. */ ! 756: extern int nmac; ! 757: #endif /* NOSPL */ ! 758: #endif /* NOICP */ ! 759: ! 760: #ifdef DEBUG ! 761: if (deblog) { /* Close any open logs. */ ! 762: debug(F100,"Debug Log Closed","",0); ! 763: *debfil = '\0'; ! 764: deblog = 0; ! 765: zclose(ZDFILE); ! 766: } ! 767: #endif /* DEBUG */ ! 768: if (pktlog) { ! 769: *pktfil = '\0'; ! 770: pktlog = 0; ! 771: zclose(ZPFILE); ! 772: } ! 773: if (seslog) { ! 774: *sesfil = '\0'; ! 775: seslog = 0; ! 776: zclose(ZSFILE); ! 777: } ! 778: #ifdef TLOG ! 779: if (tralog) { ! 780: tlog(F100,"Transaction Log Closed","",0L); ! 781: *trafil = '\0'; ! 782: tralog = 0; ! 783: zclose(ZTFILE); ! 784: } ! 785: #endif /* TLOG */ ! 786: ! 787: #ifndef NOICP ! 788: #ifndef NOSPL ! 789: zclose(ZRFILE); /* READ and WRITE files, if any. */ ! 790: zclose(ZWFILE); ! 791: /* ! 792: If a macro named "on_exit" is defined, execute it. Also remove it from the ! 793: macro table, in case its definition includes an EXIT or QUIT command, which ! 794: would cause much recursion and would prevent the program from ever actually ! 795: EXITing. ! 796: */ ! 797: if (nmac) { /* Any macros defined? */ ! 798: int k; /* Yes */ ! 799: k = mlook(mactab,"on_exit",nmac); /* Look up "on_exit" */ ! 800: if (k >= 0) { /* If found, */ ! 801: *(mactab[k].kwd) = NUL; /* poke its name from the table, */ ! 802: if (dodo(k,"") > -1) /* set it up, */ ! 803: parser(1); /* and execute it */ ! 804: } ! 805: } ! 806: #endif /* NOSPL */ ! 807: #endif /* NOICP */ ! 808: ! 809: /* ! 810: Put console terminal back to normal. This is done here because the ! 811: ON_EXIT macro calls the parser, which meddles with console terminal modes. ! 812: */ ! 813: ttclos(0); /* Close external line, if any */ ! 814: if (local) { ! 815: strcpy(ttname,dftty); /* Restore default tty */ ! 816: local = dfloc; /* And default remote/local status */ ! 817: } ! 818: conres(); /* Restore console terminal. */ ! 819: ! 820: #ifdef COMMENT ! 821: /* Should be no need for this, and maybe it's screwing this up? */ ! 822: connoi(); /* Turn off console interrupt traps */ ! 823: #endif /* COMMENT */ ! 824: ! 825: syscleanup(); /* System-dependent cleanup, last */ ! 826: } ! 827: ! 828: /* D O E X I T -- Exit from the program. */ ! 829: ! 830: /* ! 831: First arg is general, system-independent symbol: GOOD_EXIT or BAD_EXIT. ! 832: If second arg is -1, take 1st arg literally. ! 833: If second arg is not -1, work it into the exit code. ! 834: */ ! 835: VOID ! 836: doexit(exitstat,what) int exitstat, what; { ! 837: #ifdef VMS ! 838: char envstr[64]; ! 839: static $DESCRIPTOR(symnam,"CKERMIT_STATUS"); ! 840: static struct dsc$descriptor_s symval; ! 841: int i; ! 842: #endif /* VMS */ ! 843: ! 844: debug(F101,"doexit exitstat","",exitstat); ! 845: debug(F101,"doexit what","",what); ! 846: ! 847: doclean(); /* First, clean up everything */ ! 848: ! 849: #ifdef VMS ! 850: if (what == -1) ! 851: what = 0; /* Since we set two different items */ ! 852: sprintf(envstr,"%d", exitstat | what); ! 853: symval.dsc$w_length = (int)strlen(envstr); ! 854: symval.dsc$a_pointer = envstr; ! 855: symval.dsc$b_class = DSC$K_CLASS_S; ! 856: symval.dsc$b_dtype = DSC$K_DTYPE_T; ! 857: i = 2; /* Store in global table */ ! 858: LIB$SET_SYMBOL(&symnam, &symval, &i); ! 859: if (exitstat == BAD_EXIT) ! 860: exitstat = SS$_ABORT | STS$M_INHIB_MSG; ! 861: if (exitstat == GOOD_EXIT) ! 862: exitstat = SS$_NORMAL | STS$M_INHIB_MSG; ! 863: exit(exitstat); ! 864: #else /* Not VMS */ ! 865: if (what == -1) /* Take 1st arg literally */ ! 866: exit(exitstat); /* e.g. user-supplied exit code */ ! 867: else /* otherwise */ ! 868: exit(exitstat | what); /* OR in the bits */ ! 869: #endif /* VMS */ ! 870: } ! 871: ! 872: /* Set up interrupts */ ! 873: ! 874: VOID ! 875: setint() { ! 876: conint(trap,stptrap); /* Turn on console terminal interrupts. */ ! 877: bgchk(); /* Check background status */ ! 878: } ! 879: ! 880: VOID ! 881: bgchk() { /* Check background status */ ! 882: if (bgset < 0) pflag = !backgrd; ! 883: else pflag = (bgset == 0 ? 1 : 0); ! 884: } ! 885: ! 886: #ifdef DEBUG ! 887: /* D E B U G -- Enter a record in the debugging log */ ! 888: ! 889: /* ! 890: Call with a format, two strings, and a number: ! 891: f - Format, a bit string in range 0-7. ! 892: If bit x is on, then argument number x is printed. ! 893: s1 - String, argument number 1. If selected, printed as is. ! 894: s2 - String, argument number 2. If selected, printed in brackets. ! 895: n - Int, argument 3. If selected, printed preceded by equals sign. ! 896: ! 897: f=0 is special: print s1,s2, and interpret n as a char. ! 898: */ ! 899: #define DBUFL 2300 ! 900: static char *dbptr = (char *)0; ! 901: ! 902: int ! 903: dodebug(f,s1,s2,n) int f; char *s1, *s2; long n; { ! 904: char *sp; ! 905: ! 906: if (!dbptr) { ! 907: dbptr = malloc(DBUFL+1); ! 908: if (!dbptr) ! 909: return(0); ! 910: } ! 911: sp = dbptr; ! 912: if (!deblog) return(0); /* If no debug log, don't. */ ! 913: switch (f) { ! 914: case F000: /* 0, print both strings, and n as a char */ ! 915: if ((int)strlen(s1) + (int)strlen(s2) + 5 > DBUFL) { ! 916: sprintf(sp,"DEBUG string too long\n"); ! 917: } else { ! 918: if (n > 31 && n < 127) ! 919: sprintf(sp,"%s%s:%c\n",s1,s2,n); ! 920: else if (n < 32 || n == 127) ! 921: sprintf(sp,"%s%s:^%c\n",s1,s2,(n+64) & 0x7F); ! 922: else if (n > 127 && n < 160) ! 923: sprintf(sp,"%s%s:~^%c\n",s1,s2,(n-64) & 0x7F); ! 924: else if (n > 159 && n < 256) ! 925: sprintf(sp,"%s%s:~%c\n",s1,s2,n & 0x7F); ! 926: else sprintf(sp,"%s%s:%ld\n",s1,s2,n); ! 927: } ! 928: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 929: break; ! 930: case F001: /* 1, "=n" */ ! 931: sprintf(sp,"=%ld\n",n); ! 932: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 933: break; ! 934: case F010: /* 2, "[s2]" */ ! 935: if ((int)strlen(s2) + 4 > DBUFL) ! 936: sprintf(sp,"DEBUG string too long\n"); ! 937: else sprintf(sp,"[%s]\n",s2); ! 938: if (zsout(ZDFILE,"") < 0) deblog = 0; ! 939: break; ! 940: case F011: /* 3, "[s2]=n" */ ! 941: if ((int)strlen(s2) + 15 > DBUFL) ! 942: sprintf(sp,"DEBUG string too long\n"); ! 943: else sprintf(sp,"[%s]=%ld\n",s2,n); ! 944: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 945: break; ! 946: case F100: /* 4, "s1" */ ! 947: if (zsoutl(ZDFILE,s1) < 0) deblog = 0; ! 948: break; ! 949: case F101: /* 5, "s1=n" */ ! 950: if ((int)strlen(s1) + 15 > DBUFL) ! 951: sprintf(sp,"DEBUG string too long\n"); ! 952: else sprintf(sp,"%s=%ld\n",s1,n); ! 953: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 954: break; ! 955: case F110: /* 6, "s1[s2]" */ ! 956: if ((int)strlen(s1) + (int)strlen(s2) + 4 > DBUFL) ! 957: sprintf(sp,"DEBUG string too long\n"); ! 958: else sprintf(sp,"%s[%s]\n",s1,s2); ! 959: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 960: break; ! 961: case F111: /* 7, "s1[s2]=n" */ ! 962: if ((int)strlen(s1) + (int)strlen(s2) + 15 > DBUFL) ! 963: sprintf(sp,"DEBUG string too long\n"); ! 964: else sprintf(sp,"%s[%s]=%ld\n",s1,s2,n); ! 965: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 966: break; ! 967: default: ! 968: sprintf(sp,"\n?Invalid format for debug() - %d\n",f); ! 969: if (zsout(ZDFILE,dbptr) < 0) deblog = 0; ! 970: } ! 971: return(0); ! 972: } ! 973: #endif /* DEBUG */ ! 974: ! 975: #ifdef TLOG ! 976: #define TBUFL 300 ! 977: /* T L O G -- Log a record in the transaction file */ ! 978: /* ! 979: Call with a format and 3 arguments: two strings and a number: ! 980: f - Format, a bit string in range 0-7, bit x is on, arg #x is printed. ! 981: s1,s2 - String arguments 1 and 2. ! 982: n - Int, argument 3. ! 983: */ ! 984: VOID ! 985: tlog(f,s1,s2,n) int f; long n; char *s1, *s2; { ! 986: static char s[TBUFL]; ! 987: char *sp = s; int x; ! 988: ! 989: if (!tralog) return; /* If no transaction log, don't */ ! 990: switch (f) { ! 991: case F000: /* 0 (special) "s1 n s2" */ ! 992: if ((int)strlen(s1) + (int)strlen(s2) + 15 > TBUFL) ! 993: sprintf(sp,"?T-Log string too long\n"); ! 994: else sprintf(sp,"%s %ld %s\n",s1,n,s2); ! 995: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 996: break; ! 997: case F001: /* 1, " n" */ ! 998: sprintf(sp," %ld\n",n); ! 999: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 1000: break; ! 1001: case F010: /* 2, "[s2]" */ ! 1002: x = (int)strlen(s2); ! 1003: if (s2[x] == '\n') s2[x] = '\0'; ! 1004: if (x + 6 > TBUFL) ! 1005: sprintf(sp,"?T-Log string too long\n"); ! 1006: else sprintf(sp,"[%s]\n",s2); ! 1007: if (zsout(ZTFILE,"") < 0) tralog = 0; ! 1008: break; ! 1009: case F011: /* 3, "[s2] n" */ ! 1010: x = (int)strlen(s2); ! 1011: if (s2[x] == '\n') s2[x] = '\0'; ! 1012: if (x + 6 > TBUFL) ! 1013: sprintf(sp,"?T-Log string too long\n"); ! 1014: else sprintf(sp,"[%s] %ld\n",s2,n); ! 1015: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 1016: break; ! 1017: case F100: /* 4, "s1" */ ! 1018: if (zsoutl(ZTFILE,s1) < 0) tralog = 0; ! 1019: break; ! 1020: case F101: /* 5, "s1: n" */ ! 1021: if ((int)strlen(s1) + 15 > TBUFL) ! 1022: sprintf(sp,"?T-Log string too long\n"); ! 1023: else sprintf(sp,"%s: %ld\n",s1,n); ! 1024: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 1025: break; ! 1026: case F110: /* 6, "s1 s2" */ ! 1027: x = (int)strlen(s2); ! 1028: if (s2[x] == '\n') s2[x] = '\0'; ! 1029: if ((int)strlen(s1) + x + 4 > TBUFL) ! 1030: sprintf(sp,"?T-Log string too long\n"); ! 1031: else sprintf(sp,"%s %s\n",s1,s2); ! 1032: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 1033: break; ! 1034: case F111: /* 7, "s1 s2: n" */ ! 1035: x = (int)strlen(s2); ! 1036: if (s2[x] == '\n') s2[x] = '\0'; ! 1037: if ((int)strlen(s1) + x + 15 > TBUFL) ! 1038: sprintf(sp,"?T-Log string too long\n"); ! 1039: else sprintf(sp,"%s %s: %ld\n",s1,s2,n); ! 1040: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 1041: break; ! 1042: default: ! 1043: sprintf(sp,"\n?Invalid format for tlog() - %ld\n",n); ! 1044: if (zsout(ZTFILE,s) < 0) tralog = 0; ! 1045: } ! 1046: } ! 1047: #endif /* TLOG */ ! 1048: #endif /* MAC */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.