home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archimedes / araus3.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  24KB  |  903 lines

  1. /* -> c.ckaus3
  2.  */
  3.  
  4. /*  C K A U S 3 --  "User Interface" for Unix Kermit, part 3  */
  5.  
  6. /*
  7.  Author: Frank da Cruz (SY.FDC@CU20B),
  8.  Columbia University Center for Computing Activities, January 1985.
  9.  Copyright (C) 1985, Trustees of Columbia University in the City of New York.
  10.  Permission is granted to any individual or institution to use, copy, or
  11.  redistribute this software so long as it is not sold for profit, provided this
  12.  copyright notice is retained. 
  13. */
  14.  
  15. /*  SET and REMOTE commands; screen, debug, interrupt, and logging functions */
  16.  
  17. /* Includes */
  18.  
  19. #include "ckcdeb.h"
  20. #ifdef ANSI
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include "ckcker.h"
  24. #include "ckucmd.h"
  25. #include "ckuusr.h"
  26. #include <string.h>
  27. #include "ckatio.h"
  28. #include "ckafio.h"
  29. #include "ckamis.h"
  30. #else
  31. #include <stdio-h>
  32. #include <ctype-h>
  33. #include "ckcker-h"
  34. #include "ckucmd-h"
  35. #include "ckuusr-h"
  36. #endif
  37.  
  38. #ifdef ANSI
  39. #include <string.h>
  40. #endif
  41. /* Variables */
  42.  
  43. extern int size, spsiz, rpsiz, npad, timint, rtimo, speed, local, server, 
  44.   image, flow, displa, binary, fncnv, delay, parity, deblog, escape, xargc,
  45.   turn, duplex, cxseen, czseen, nfils, ckxech, pktlog, seslog, tralog, stdouf,
  46.   turnch, chklen, bctr, bctu, dfloc, mdmtyp,
  47.   rptflg, ebqflg, warn, quiet, cnflg, timef, mypadn;
  48.  
  49. extern long filcnt, tlci, tlco, ffc, tfc, fsize;
  50.  
  51. extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
  52. extern char *cmarg, *cmarg2, **xargv, **cmlist;
  53. extern char stchr, mystch, sstate, padch, mypadc, eol, seol, ctlq;
  54. extern char filnam[], ttname[];
  55.  
  56. #ifndef ANSI
  57. char *strcpy();
  58. #endif
  59.  
  60. #ifdef ANSI
  61. extern void resend( void );
  62. #endif
  63.  
  64. /* Declarations from cmd package */
  65.  
  66. extern char cmdbuf[];           /* Command buffer */
  67.  
  68. /* From main ckuser module... */
  69.  
  70. extern char line[100], *lp;     /* Character buffer for anything */
  71. extern char debfil[50],         /* Debugging log file name */
  72.  pktfil[50],                /* Packet log file name */
  73.  sesfil[50],                /* Session log file name */
  74.  trafil[50];                /* Transaction log file name */
  75.  
  76. extern int tlevel;          /* Take Command file level */
  77. extern FILE *tfile[];           /* Array of take command fd's */
  78.  
  79. /* Keyword tables for SET commands */
  80.  
  81. /* Block checks */
  82.  
  83. struct keytab blktab[] = {
  84.     "1", 1, 0,
  85.     "2", 2, 0,
  86.     "3", 3, 0
  87. };
  88.  
  89. /* Duplex keyword table */
  90.  
  91. struct keytab dpxtab[] = {
  92.     "full",      0, 0,
  93.     "half",      1, 0
  94. };
  95.  
  96. struct keytab filtab[] = {
  97.     "display", XYFILD, 0,
  98.     "names",   XYFILN, 0,
  99.     "type",    XYFILT, 0,
  100.     "warning", XYFILW, 0
  101. };
  102. int nfilp = (sizeof(filtab) / sizeof(struct keytab));
  103.  
  104. /* Send/Receive Parameters */
  105.  
  106. struct keytab srtab[] = {
  107.     "end-of-packet", XYEOL, 0,
  108.     "packet-length", XYLEN, 0,
  109.     "pad-character", XYPADC, 0,
  110.     "padding", XYNPAD, 0,
  111.     "start-of-packet", XYMARK, 0,
  112.     "timeout", XYTIMO, 0
  113. };
  114. int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
  115.  
  116. /* Flow Control */
  117.  
  118. struct keytab flotab[] = {
  119.     "none",     0, 0,
  120.     "xon/xoff", 1, 0
  121. };
  122. int nflo = (sizeof(flotab) / sizeof(struct keytab));
  123.  
  124.  
  125. /*  Handshake characters  */
  126.  
  127. struct keytab hshtab[] = {
  128.     "bell", 007, 0,
  129.     "cr",   015, 0,
  130.     "esc",  033, 0,
  131.     "lf",   012, 0,
  132.     "none", 999, 0,  /* (can't use negative numbers) */
  133.     "xoff", 023, 0,
  134.     "xon",  021, 0
  135. };
  136. int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
  137.  
  138. struct keytab fntab[] = {           /* File naming */
  139.     "converted", 1, 0,
  140.     "literal",   0, 0
  141. };
  142.  
  143. struct keytab fttab[] = {       /* File types */
  144.     "binary",    1, 0,
  145.     "text",      0, 0
  146. };
  147.  
  148. extern struct keytab mdmtab[] ;     /* Modem types (in module ckdial.c) */
  149. extern int nmdm;
  150.  
  151.  
  152. /* Parity keyword table */
  153.  
  154. struct keytab partab[] = {
  155.     "even",    'e', 0,
  156.     "mark",    'm', 0,
  157.     "none",      0, 0,
  158.     "odd",     'o', 0,
  159.     "space",   's', 0
  160. };
  161. int npar = (sizeof(partab) / sizeof(struct keytab));
  162.  
  163.  
  164. /* On/Off table */
  165.  
  166. struct keytab onoff[] = {
  167.     "off",       0, 0,
  168.     "on",        1, 0
  169. };
  170.  
  171.  
  172. /*  D O P R M  --  Set a parameter.  */
  173. /*
  174.  Returns:
  175.   -2: illegal input
  176.   -1: reparse needed
  177.    0: success
  178. */
  179.  
  180. #ifdef ANSI
  181. int
  182. #endif
  183. doprm(xx) int xx; {
  184.     int x, y, z;
  185.     char *s;
  186.  
  187. switch (xx) {
  188.  
  189. case XYEOL: /* These have all been moved to set send/receive... */
  190. case XYLEN:     /* Let the user know what to do. */
  191. case XYMARK:
  192. case XYNPAD:
  193. case XYPADC:
  194. case XYTIMO:
  195.     printf("...Use 'set send' or 'set receive' instead.\n");
  196.     printf("Type 'help set send' or 'help set receive' for more info.\n");
  197.     return(0);
  198.  
  199. case XYLINE:
  200.     if ((x = cmtxt("Device name",dftty,&s)) < 0) return(x);
  201.     ttclos();               /* close old line, if any was open */
  202.  
  203. /** if (strcmp(ttname,dftty) == 0) local = dfloc; else local = 1; **/
  204.     local = -1;             /* Let ttopen figure it out... */
  205.  
  206.     if (ttopen(s,&local,mdmtyp) < 0 ) { /* Can we open the new line? */
  207.     perror("Sorry, can't open line");
  208.     return(-2);         /* If not, give bad return */
  209.     }
  210.     strcpy(ttname,s);           /* OK, copy name into real place. */
  211.     if (!local) speed = -1;     /* If remote, say speed unknown. */
  212.     debug(F111,"set line ",ttname,local);
  213.     return(0);
  214.  
  215. case XYCHKT:
  216.     if ((y = cmkey(blktab,3,"","1")) < 0) return(y);
  217.     if ((x = cmcfm()) < 0) return(x);
  218.     bctr = y;
  219.     return(0);
  220.  
  221. case XYDEBU:
  222.     return(seton(&deblog));
  223.  
  224. case XYDELA:
  225.     y = cmnum("Number of seconds before starting to send","5",10,&x);
  226.     debug(F101,"XYDELA: y","",y);
  227.     return(setnum(&delay,x,y));
  228.  
  229. case XYDUPL:
  230.     if ((y = cmkey(dpxtab,2,"","full")) < 0) return(y);
  231.     if ((x = cmcfm()) < 0) return(x);
  232.     duplex = y;
  233.     return(0);
  234.  
  235. case XYESC:
  236.     y = cmnum("Decimal ASCII code for escape character","",10,&x);
  237.     return(setcc(&escape,x,y));
  238.  
  239. case XYFILE:
  240.     if ((y = cmkey(filtab,nfilp,"File parameter","")) < 0) return(y);
  241.     switch (y) {
  242. #ifndef ANSI
  243.     int z;
  244. #endif
  245.     case XYFILD:            /* Display */
  246.         y = seton(&z);
  247.         if (y < 0) return(y);
  248.         quiet = !z;
  249.         return(0);
  250.  
  251.     case XYFILN:            /* Names */
  252.         if ((x = cmkey(fntab,2,"how to handle filenames","converted")) < 0)
  253.             return(x);
  254.         if ((z = cmcfm()) < 0) return(z);
  255.         fncnv = x;
  256.         return(0);
  257.  
  258.     case XYFILT:            /* Type */
  259.         if ((x = cmkey(fttab,2,"type of file","text")) < 0)
  260.             return(x);
  261.         if ((z = cmcfm()) < 0) return(z);
  262.         binary = x;
  263.         return(0);
  264.  
  265.     case XYFILW:            /* Warning/Write-Protect */
  266.         return(seton(&warn));
  267.  
  268.     default:
  269.         printf("?unexpected file parameter\n");
  270.         return(-2);
  271.     }
  272.  
  273. case XYFLOW:                /* Flow control */
  274.     if ((y = cmkey(flotab,nflo,"","xon/xoff")) < 0) return(y);
  275.     if ((x = cmcfm()) < 0) return(x);
  276.     flow = y;
  277.     return(0);
  278.  
  279. case XYHAND:                /* Handshake */
  280.     if ((y = cmkey(hshtab,nhsh,"","none")) < 0) return(y);
  281.     if ((x = cmcfm()) < 0) return(x);
  282.     turn = (y > 0127) ? 0 : 1 ;
  283.     turnch = y;
  284.     return(0);
  285.  
  286. case XYMODM:
  287.     if ((x=cmkey(mdmtab,nmdm,"type of modem, direct means none","direct")) < 0)
  288.     return(x);
  289.     if ((z = cmcfm()) < 0) return(z);
  290.     mdmtyp = x;
  291.     return(0);
  292.     
  293. case XYPARI:
  294.     if ((y = cmkey(partab,npar,"","none")) < 0) return(y);
  295.     if ((x = cmcfm()) < 0) return(x);
  296.     parity = y;
  297.     ebqflg = 1;             /* Flag we want 8th-bit prefixing */
  298.     return(0);
  299.  
  300. case XYPROM:
  301.     if ((x = cmtxt("Program's command prompt","Arthur-Kermit>",&s)) < 0) return(x);
  302.     cmsetp(s);
  303.     return(0);
  304.  
  305.  
  306. /* SET SEND/RECEIVE... */
  307.  
  308. case XYRECV:
  309. case XYSEND:
  310.     if (xx == XYRECV)
  311.         strcpy(line,"Parameter for inbound packets");
  312.     else
  313.         strcpy(line,"Parameter for outbound packets");
  314.  
  315.     if ((y = cmkey(srtab,nsrtab,line,"")) < 0) return(y);
  316.     switch (y) {
  317.  
  318. case XYEOL:
  319.     y = cmnum("Decimal ASCII code for packet terminator","0",10,&x);
  320.     if ((y = setcc(&z,x,y)) < 0) return(y);
  321.     if (xx == XYRECV) eol = z; else seol = z;
  322.     return(y);
  323.  
  324. case XYLEN:
  325.     y = cmnum("Maximum number of characters in a packet","90",10,&x);
  326.     if ((y = setnum(&z,x,y)) < 0) return(y);
  327.     if (xx == XYRECV) rpsiz = z; else spsiz = z;
  328.     return(y);
  329.  
  330. case XYMARK:
  331.     y = cmnum("Decimal ASCII code for packet-start character","1",10,&x);
  332.     if ((y = setcc(&z,x,y)) < 0) return(y);
  333.     if (xx == XYRECV) stchr = z; else mystch = z;
  334.     return(y);
  335.  
  336. case XYNPAD:
  337.     y = cmnum("How many padding characters for inbound packets","0",10,&x);
  338.     if ((y = setnum(&z,x,y)) < 0) return(y);
  339.     if (xx == XYRECV) npad = z; else mypadn = z;
  340.     return(y);
  341.  
  342. case XYPADC:
  343.     y = cmnum("Decimal ASCII code for inbound pad character","0",10,&x);
  344.     if ((y = setcc(&z,x,y)) < 0) return(y);
  345.     if (xx == XYRECV) padch = z; else mypadc = z;
  346.     return(y);
  347.  
  348. case XYTIMO:
  349.     y = cmnum("Interpacket timeout interval","5",10,&x);
  350.     if ((y = setnum(&z,x,y)) < 0) return(y);
  351.     if (xx == XYRECV) {
  352.     timef = 1;
  353.     timint = z;
  354.     } else rtimo = z;
  355.     return(y);
  356.  
  357.     }
  358.  
  359. case XYSPEE:
  360.     if (!local) {
  361.     printf("\nSpeed setting can only be done on an external line\n");
  362.     printf("You must 'set line' before issuing this command\n");
  363.     return(0);
  364.     }   
  365.     lp = line;
  366.     sprintf(lp,"Baud rate for %s",ttname);
  367.     if ((y = cmnum(line,"",10,&x)) < 0) return(y);
  368. #ifdef ANSI
  369.     if ( (y = cmcfm()) < 0) return(y);
  370. #else
  371.     if (y = (cmcfm()) < 0) return(y);
  372. #endif
  373.     y = chkspd(x);
  374.     if (y < 0) 
  375.         printf("?Unsupported line speed - %d\n",x);
  376.     else {
  377.         speed = y;
  378.     printf("%s: %d baud\n",ttname,speed);
  379.     }
  380.     return(0);
  381.  
  382. default:
  383.     if ((x = cmcfm()) < 0) return(x);
  384.     printf("Not working yet - %s\n",cmdbuf);
  385.     return(0);
  386.     }
  387. }
  388.  
  389. /*  C H K S P D  --  Check if argument is a valid baud rate  */
  390.  
  391. #ifdef ANSI
  392. int
  393. #endif
  394. chkspd(x) int x; {
  395.     switch (x) {
  396.     case 0:
  397.     case 110:
  398.     case 150:
  399.     case 300:
  400.     case 600:
  401.     case 1200:
  402.     case 1800:
  403.     case 2400:
  404.     case 4800:
  405.     case 9600:
  406.     case 19200:
  407.         return(x);
  408.     default: 
  409.         return(-1);
  410.       }
  411. }
  412.  
  413. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  414.  
  415. #ifdef ANSI
  416. int
  417. #endif
  418. seton(prm) int *prm; {
  419.     int x, y;
  420.     if ((y = cmkey(onoff,2,"","on")) < 0) return(y);
  421.     if ((x = cmcfm()) < 0) return(x);
  422.     *prm = y;
  423.     return(0);
  424. }
  425.  
  426. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  427. /*
  428.  Call with x - number from cnum parse, y - return code from cmnum
  429. */
  430.  
  431. #ifdef ANSI
  432. int
  433. #endif
  434. setnum(prm,x,y) int x, y, *prm; {
  435.     debug(F101,"setnum","",y);
  436.     if (y < 0) return(y);
  437.     if (x > 94) {
  438.     printf("\n?Sorry, 94 is the maximum\n");
  439.     return(-2);
  440.     }
  441.     if ((y = cmcfm()) < 0) return(y);
  442.     *prm = x;
  443.     return(0);
  444. }
  445.  
  446. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  447.  
  448. #ifdef ANSI
  449. int
  450. #endif
  451. setcc(prm,x,y) int x, y, *prm; {
  452.     if (y < 0) return(y);
  453.     if ((x > 037) && (x != 0177)) {
  454.     printf("\n?Not in ASCII control range - %d\n",x);
  455.     return(-2);
  456.     }
  457.     if ((y = cmcfm()) < 0) return(y);
  458.     *prm = x;
  459.     return(0);
  460. }
  461.  
  462. /*  D O R M T  --  Do a remote command  */
  463.  
  464. #ifdef ANSI
  465. int
  466. #endif
  467. dormt(xx) int xx; {
  468.     int x;
  469.     char *s, sbuf[50], *s2;
  470.     if (xx < 0) return(xx);
  471.     switch (xx) {
  472.  
  473. case XZCWD:             /* CWD */
  474.     if ((x = cmtxt("Remote directory name","",&s)) < 0) return(x);
  475.     debug(F111,"XZCWD: ",s,x);
  476.     *sbuf = NUL;
  477.     s2 = sbuf;
  478.     if (*s != NUL) {            /* If directory name given, */
  479.                     /* get password on separate line. */
  480.         if (tlevel > -1) {      /* From take file... */
  481.  
  482.         *line = NUL;
  483.         if (fgets(sbuf,50,tfile[tlevel]) == NULL)
  484.             ermsg("take file ends prematurely in 'remote cwd'");
  485.         debug(F110," pswd from take file",s2,0);
  486.  
  487.         } else {            /* From terminal... */
  488.  
  489.         printf(" Password: ");      /* get a password */
  490.         while (
  491.                    ( (x=coninc(0)) != NL)
  492.                 && (x != CR)
  493.                   ) { /* with no echo */
  494.             if ((x &= 0177) == '?') {
  495.                 printf("? Password of remote directory\n Password: ");
  496.             s2 = sbuf;
  497.             *sbuf = NUL;
  498.             }
  499.             else if (x == /*ESC*/HT)    /* Mini command line editor... */
  500.                 putchar(BEL);
  501.         else if (x == BS || x == 0177)
  502.             s2--;
  503.         else if (x == 025) {
  504.             s2 = sbuf;
  505.             *sbuf = NUL;
  506.         }
  507.             else
  508.             *s2++ = x;
  509.             }
  510.         *s2 = NUL;
  511.         putchar('\n');
  512.         }
  513.         s2 = sbuf;
  514.     } else s2 = "";
  515.     debug(F110," password",s2,0);
  516.     sstate = setgen('C',s,s2,"");
  517.     return(0);
  518.  
  519.  
  520. case XZDEL:             /* Delete */
  521.     if ((x = cmtxt("Name of remote file(s) to delete","",&s)) < 0) return(x);
  522.     return(sstate = rfilop(s,'E'));
  523.  
  524. case XZDIR:             /* Directory */
  525.     if ((x = cmtxt("Remote directory or file specification","",&s)) < 0)
  526.         return(x);
  527.     return(sstate = setgen('D',s,"",""));
  528.  
  529. case XZHLP:             /* Help */
  530. #ifdef ANSI
  531.     if ( (x = cmcfm()) < 0) return(x);
  532. #else
  533.     if (x = (cmcfm()) < 0) return(x);
  534. #endif
  535.     sstate = setgen('H',"","","");
  536.     return(0);
  537.  
  538. case XZHOS:             /* Host */
  539.     if ((x = cmtxt("Command for remote system","",&cmarg)) < 0) return(x);
  540.     return(sstate = 'c');
  541.  
  542. case XZPRI:             /* Print */
  543.     if ((x = cmtxt("Remote file(s) to print on remote printer","",&s)) < 0)
  544.         return(x);
  545.     return(sstate = rfilop(s,'S'));
  546.  
  547. case XZSPA:             /* Space */
  548.     if ((x = cmtxt("Confirm, or remote directory name","",&s)) < 0) return(x);
  549.     return(sstate = setgen('U',s,"",""));
  550.     
  551. case XZTYP:             /* Type */
  552.     if ((x = cmtxt("Remote file specification","",&s)) < 0) return(x);
  553.     return(sstate = rfilop(s,'T'));
  554.  
  555. case XZWHO:
  556.     if ((x = cmtxt("Remote user name, or carriage return","",&s)) < 0)
  557.         return(x);
  558.     return(sstate = setgen('W',s,"",""));
  559.  
  560. default:
  561. #ifdef ANSI
  562.     if ( (x = cmcfm()) < 0) return(x);
  563. #else
  564.     if (x = (cmcfm()) < 0) return(x);
  565. #endif
  566.     printf("not working yet - %s\n",cmdbuf);
  567.     return(-2);
  568.     }
  569. }
  570.  
  571. /*  R F I L O P  --  Remote File Operation  */
  572.  
  573. #ifdef ANSI
  574. int
  575. #endif
  576. rfilop(
  577. #ifdef ANSI
  578. char *s, char t)
  579. #else
  580. s,t) char *s, t;
  581. #endif
  582. {
  583.     if (*s == NUL) {
  584.     printf("?File specification required\n");
  585.     return(-2);
  586.     }
  587.     debug(F111,"rfilop",s,t);
  588.     return(setgen(t,s,"",""));
  589. }
  590.  
  591. /*  S C R E E N  --  Screen display function  */
  592.  
  593. /*  screen(f,c,n,s)
  594.       f - argument descriptor
  595.       c - a character or small integer
  596.       n - a long integer
  597.       s - a string.
  598.  Fill in this routine with the appropriate display update for the system.
  599.  This version is for a dumb tty.
  600. */
  601.  
  602. #ifdef ANSI
  603. void
  604. #endif
  605. screen(
  606. #ifdef ANSI
  607. int f, char c, long n, char *s)
  608. #else
  609. f,c,n,s) int f; long n; char c; char *s;
  610. #endif
  611. {
  612.     static int p = 0;           /* Screen position */
  613.     static char digit = '.';
  614.     int len;                /* Length of string */
  615.     char buf[80];           /* Output buffer */
  616.  
  617.     len = strlen(s);            /* Length of string */
  618.     if (!displa || quiet) {
  619.       return;   /* No update if display flag off */
  620.     }
  621.     switch (f) {
  622.  
  623. case SCR_FN:                /* filename */
  624.     conoll(""); conol(s); conoc(SP); p = len + 1; return;
  625.  
  626. case SCR_AN:                /* as-name */
  627.     if (p + len > 75) { conoll(""); p = 0; }
  628.     conol("=> "); conol(s); if ((p += (len + 3)) > 75) { conoll(""); p = 0; }
  629.     return;
  630.  
  631. case SCR_FS:                /* file-size */
  632.     sprintf(buf,", Size: %ld",n);  conoll(buf);  p = 0; return;
  633.  
  634. case SCR_XD:                /* x-packet data */
  635.     conoll(""); conoll(s); p = 0; return;
  636.     
  637. case SCR_ST:                /* File status */
  638.     switch (c) {
  639.     case ST_OK:             /*  Transferred OK */
  640.         if ((p += 5) > 75) { conoll(""); p = 0; }
  641.         conoll(" [OK]"); p = 0; digit = '.'; return;
  642.  
  643.     case ST_DISC:           /*  Discarded */
  644.         if ((p += 12) > 75) { conoll(""); p = 0; }
  645.         conoll(" [discarded]"); p = 0; digit = '.'; return;
  646.  
  647.     case ST_INT:            /*  Interrupted */
  648.         if ((p += 14) > 75) { conoll(""); p = 0; }
  649.         conoll(" [interrupted]"); p = 0; digit = '.'; return;
  650.  
  651.     case ST_SKIP:           /*  Skipped */
  652.         conoll("");
  653.         conol("Skipping "); conoll(s); p = 0; digit = '.';
  654.         return;
  655.  
  656.         default:
  657.         conoll("*** screen() called with bad status ***"); p = 0; return;
  658.     }
  659.  
  660. case SCR_PN:                /* Packet number */
  661.     sprintf(buf,"%s: %ld",s,n); conol(buf); p += strlen(buf); return;
  662.  
  663. case SCR_PT:                /* Packet type or pseudotype */
  664.     if (c == 'Y') return;       /* Don't bother with ACKs */
  665.     if (c == 'D') {         /* Only show every 4th data packet */
  666.     if (n % 4) return;                                    
  667.         if (fsize) {
  668.           c = (char) (ffc * 10 / fsize + (int) '0');
  669.           if (c != digit) digit = c; else   c = '.';
  670.         } else c = '.';
  671.     }
  672.     if (p++ > 75) /* BBC auto-lf*/ { /* If near right margin, */
  673.     conoll("");         /* Start new line */
  674.     p = 0;              /* and reset counter. */
  675.     }
  676.     conoc(c);               /* Display the character. */
  677.     return;
  678.  
  679. case SCR_TC:                /* transaction complete */
  680.     conoc(BEL); return;
  681.  
  682. case SCR_EM:                /* Error message */
  683.     conoll(""); conoc('?'); conoll(s); p = 0; return;       /* +1   */
  684.  
  685. case SCR_WM:                /* Warning message */
  686.     conoll(""); conoll(s); p = 0; return;
  687.  
  688. case SCR_TU:                /* Undelimited text */
  689.     if ((p += len) > 75) { conoll(""); p = len; }
  690.     conol(s); return;
  691.  
  692. case SCR_TN:                /* Text delimited at beginning */
  693.     conoll(""); conol(s); p = len; return;
  694.  
  695. case SCR_TZ:                /* Text delimited at end */
  696.     if ((p += len) > 75) conoll("");
  697.     conoll(s); p = 0; return;
  698.     
  699. case SCR_QE:                /* Quantity equals */
  700.     sprintf(buf,"%s: %ld",s,n);
  701.     conoll(buf); p = 0; return;
  702.  
  703. default:
  704.     conoll("*** screen() called with bad object ***"); p = 0; return;
  705.     }
  706. }
  707.  
  708. /*  I N T M S G  --  Issue message about terminal interrupts  */
  709.  
  710. #ifdef ANSI
  711. void
  712. #endif
  713. intmsg(n) long n; {
  714. #ifndef ANSI
  715.     extern char *chstr();
  716. #endif
  717.     char buf[80];
  718.  
  719.     if ((!displa) || (quiet)) return;
  720.     if (n == 1) {
  721.  screen(SCR_TN,0,0l,"CTRL-F to cancel file,  CTRL-R to resend current packet");
  722.  screen(SCR_TZ,0,0l,"CTRL-B to cancel batch, CTRL-A for status report...");
  723.     }
  724.     else screen(SCR_TU,0,0l," ");
  725. }
  726.  
  727.  
  728. /*  C H K I N T  --  Check for console interrupts  */
  729.  
  730. /*** should rework not to destroy typeahead ***/
  731.  
  732. #ifdef ANSI
  733. int
  734. #endif
  735. chkint() {
  736.     int ch, cn;
  737.  
  738.     if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
  739.     cn = conchk();          /* Any input waiting? */
  740.     debug(F101,"conchk","",cn);
  741.  
  742.     while (cn > 0) {            /* Yes, read it. */
  743.     cn--;
  744.             /* give read 5 seconds for interrupt character */
  745.     if ((ch = coninc(5)) < 0) return(0);
  746.     switch (ch & 0177) {
  747.         case 0001:          /* CTRL-A */
  748.         screen(SCR_TN,0,0l,"^A  Status report:");
  749.         screen(SCR_TN,0,0l," file type: ");
  750.         if (binary) screen(SCR_TZ,0,0l,"binary");
  751.             else    screen(SCR_TZ,0,0l,"text");
  752.         screen(SCR_QE,0,(long)filcnt," file number");
  753.         screen(SCR_QE,0,(long)ffc,   " characters ");
  754.         screen(SCR_QE,0,(long)bctu,  " block check");
  755.         screen(SCR_QE,0,(long)rptflg," compression");
  756.         screen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
  757.         continue;
  758.         case 0033:                  /* ESCAPE */
  759.         case 0002:          /* CTRL-B */
  760.             screen(SCR_TN,0,0l,"^B - Cancelling Batch ");
  761.             czseen = 1;
  762.         continue;
  763.         case 0006:          /* CTRL-F */
  764.             screen(SCR_TN,0,0l,"^F - Cancelling File ");
  765.             cxseen = 1;
  766.         continue;
  767.         case 0022:                  /* CTRL-R */
  768.             screen(SCR_TN,0,0l,"^R - Resending ");
  769.             resend();
  770.         return(1);
  771.         default:            /* Anything else, just ignore */
  772.             screen(SCR_TU,0,0l," [Ignored] ");
  773.         continue;
  774.         }
  775.     }
  776.     return(0);
  777. }
  778.  
  779. /*  D E B U G  --  Enter a record in the debugging log  */
  780.  
  781. /*
  782.  Call with a format, two strings, and a number:
  783.    f  - Format, a bit string in range 0-7.
  784.         If bit x is on, then argument number x is printed.
  785.    s1 - String, argument number 1.  If selected, printed as is.
  786.    s2 - String, argument number 2.  If selected, printed in brackets.
  787.    n  - Int, argument 3.  If selected, printed preceded by equals sign.
  788.  
  789.    f=0 is special: print s1,s2, and interpret n as a char.
  790. */
  791. #ifdef DEBUG
  792. #ifdef ANSI
  793. void
  794. #endif
  795. debug(f,s1,s2,n) int f, n; char *s1, *s2; {
  796.     static char s[200];
  797.     char *sp = s;
  798.  
  799.     if (!deblog) return;        /* If no debug log, don't */
  800.     switch (f) {
  801.         case F000:          /* 0, print both strings, */
  802.         sprintf(sp,"%s%s%c\n",s1,s2,n); /*  and interpret n as a char */
  803.         zsout(ZDFILE,s);
  804.         break;
  805.         case F001:          /* 1, "=n" */
  806.         sprintf(sp,"=%d\n",n);
  807.         zsout(ZDFILE,s);
  808.         break;
  809.         case F010:          /* 2, "[s2]" */
  810.         sprintf(sp,"[%s]\n",s2);
  811.         zsout(ZDFILE,"");
  812.         break;
  813.         case F011:          /* 3, "[s2]=n" */
  814.         sprintf(sp,"[%s]=%d\n",s2,n);
  815.         zsout(ZDFILE,s);
  816.         break;
  817.         case F100:          /* 4, "s1" */
  818.         zsoutl(ZDFILE,s1);
  819.         break;
  820.         case F101:          /* 5, "s1=n" */
  821.         sprintf(sp,"%s=%d\n",s1,n);
  822.         zsout(ZDFILE,s);
  823.         break;
  824.         case F110:          /* 6, "s1[s2]" */
  825.         sprintf(sp,"%s[%s]\n",s1,s2);
  826.         zsout(ZDFILE,s);
  827.         break;
  828.         case F111:          /* 7, "s1[s2]=n" */
  829.         sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
  830.         zsout(ZDFILE,s);
  831.         break;
  832.     default:
  833.         sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
  834.         zsout(ZDFILE,s);
  835.     }
  836. }
  837. #endif
  838.  
  839.  
  840. #ifdef TLOG
  841. /*  T L O G  --  Log a record in the transaction file  */
  842. /*
  843.  Call with a format and 3 arguments: two strings and a number:
  844.    f  - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
  845.    s1,s2 - String arguments 1 and 2.
  846.    n  - Int, argument 3.
  847. */
  848.  
  849. #ifdef ANSI
  850. void
  851. #endif
  852. tlog(f,s1,s2,n) int f; long n; char *s1, *s2; {
  853.     static char s[200];
  854.     char *sp = s; int x;
  855.     
  856.     if (!tralog) return;        /* If no transaction log, don't */
  857.     switch (f) {
  858.         case F000:          /* 0 (special) "s1 n s2"  */
  859.         sprintf(sp,"%s %ld %s\n",s1,n,s2);
  860.         zsout(ZTFILE,s);
  861.         break;
  862.         case F001:          /* 1, " n" */
  863.         sprintf(sp," %ld\n",n);
  864.         zsout(ZTFILE,s);
  865.         break;
  866.         case F010:          /* 2, "[s2]" */
  867.         x = strlen(s2);
  868.         if (s2[x] == '\n') s2[x] = '\0';
  869.         sprintf(sp,"[%s]\n",s2);
  870.         zsout(ZTFILE,"");
  871.         break;
  872.         case F011:          /* 3, "[s2] n" */
  873.         x = strlen(s2);
  874.         if (s2[x] == '\n') s2[x] = '\0';
  875.         sprintf(sp,"[%s] %ld\n",s2,n);
  876.         zsout(ZTFILE,s);
  877.         break;
  878.         case F100:          /* 4, "s1" */
  879.         zsoutl(ZTFILE,s1);
  880.         break;
  881.         case F101:          /* 5, "s1: n" */
  882.         sprintf(sp,"%s: %ld\n",s1,n);
  883.         zsout(ZTFILE,s);
  884.         break;
  885.         case F110:          /* 6, "s1 s2" */
  886.         x = strlen(s2);
  887.         if (s2[x] == '\n') s2[x] = '\0';
  888.         sprintf(sp,"%s %s\n",s1,s2);
  889.         zsout(ZTFILE,s);
  890.         break;
  891.         case F111:          /* 7, "s1 s2: n" */
  892.         x = strlen(s2);
  893.         if (s2[x] == '\n') s2[x] = '\0';
  894.         sprintf(sp,"%s %s: %ld\n",s1,s2,n);
  895.         zsout(ZTFILE,s);
  896.         break;
  897.     default:
  898.         sprintf(sp,"\n?Invalid format for tlog() - %ld\n",n);
  899.         zsout(ZTFILE,s);
  900.     }
  901. }
  902. #endif
  903.