home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / CKPM5X_S.ZIP / CKUUS3.C < prev    next >
C/C++ Source or Header  |  1990-03-04  |  45KB  |  1,487 lines

  1. /*  C K U U S 3 --  "User Interface" for Unix Kermit, part 3  */
  2.  
  3. /*
  4.  Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  5.  Columbia University Center for Computing Activities.
  6.  First released January 1985.
  7.  Copyright (C) 1985, 1990, 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. /*  SET and REMOTE commands; screen, debug, interrupt, and logging functions */
  14.  
  15. /* Includes */
  16. #ifdef OS2
  17. #include <string.h>
  18. #endif
  19.  
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include "ckcdeb.h"
  23. #include "ckcasc.h"
  24. #include "ckcker.h"
  25. #include "ckucmd.h"
  26. #include "ckuusr.h"
  27. #include "ckcxla.h"
  28. #ifdef UXIII
  29. #include <termio.h>
  30. #endif
  31.  
  32. #ifdef datageneral
  33. extern int con_reads_mt,            /* Flag if console read asynch is active */
  34.            conint_ch,               /* The character read by asynch read */
  35.            conint_avl;              /* Flag that char available */
  36. #endif
  37.  
  38. /* Variables */
  39.  
  40. extern int size, spsiz, rpsiz, urpsiz, npad, timint, srvtim, rtimo, speed,
  41.   local, server, lpcapr, fmask, cmask, backgrd, atcapr, success,
  42.   flow, displa, binary, fncnv, delay, parity, deblog, escape, xargc,
  43.   turn, duplex, cxseen, czseen, nfils, ckxech, pktlog, seslog, tralog, stdouf,
  44.   turnch, bctr, bctu, dfloc, mdmtyp, keep, maxtry, unkcs, network, tvtflg,
  45.   rptflg, ebqflg, warn, quiet, cnflg, timef, spsizf, mypadn, swcapr,
  46.   wslots, wslotsr, wslotsn, fcharset, tcharset, tslevel, nfilc, language;
  47. extern int xxstring();
  48. extern int count[];
  49. extern int maclvl, macargc[];
  50. extern int techo, mecho, terror, merror, rprintf;
  51. extern int indef, intime, incase, inecho;
  52.  
  53. #ifdef OS2
  54. extern int Term_mode;
  55. #endif
  56.  
  57. extern long filcnt, tlci, tlco, ffc, tfc, fsize;
  58.  
  59. extern char *versio, *protv, *ckxv, *ckzv, *fnsv, *connv, *dftty, *cmdv;
  60. extern char *cmarg, *cmarg2, **xargv, **cmlist;
  61. extern CHAR stchr, mystch, sstate, padch, mypadc, eol, seol, ctlq;
  62. extern CHAR filnam[], ttname[];
  63.  
  64. #ifndef OS2
  65. char *strcpy();
  66. #endif
  67.  
  68. /* system-dependent character sets, defined in ckcxla.[ch] */
  69. extern struct keytab fcstab[];      /* For 'set file character-set' */
  70. extern struct csinfo fcsinfo[];     /* For 'show', etc. */
  71. extern struct csinfo tcsinfo[];
  72. extern struct langinfo langs[];
  73.  
  74. /* Declarations from cmd package */
  75.  
  76. extern char cmdbuf[],           /* Command buffer */
  77.  optbuf[];              /* Buffer for MAIL or PRINT options */
  78.  
  79. /* From main ckuser module... */
  80.  
  81. extern char line[], *lp;        /* Character buffer for anything */
  82. extern char debfil[],           /* Debugging log file name */
  83.  pktfil[],              /* Packet log file name */
  84.  sesfil[],              /* Session log file name */
  85.  trafil[],              /* Transaction log file name */
  86.  tmpbuf[];              /* Temporary buffer */
  87. extern char *tp;            /* Temp buf pointer */
  88. extern int tlevel;          /* Take Command file level */
  89. extern int cmdlvl;          /* Overall command level */
  90. extern FILE *tfile[];           /* Array of take command fd's */
  91.  
  92.  
  93. /* Keyword tables for SET commands */
  94.  
  95.  
  96. /* Block checks */
  97.  
  98. struct keytab blktab[] = {
  99.     "1", 1, 0,
  100.     "2", 2, 0,
  101.     "3", 3, 0
  102. };
  103.  
  104. /* Speeds */
  105.  
  106. struct keytab spdtab[] = {
  107.     "0",      0,  CM_INV,
  108.     "50",    50,  0,
  109.     "110",  110,  0,
  110.     "150",  150,  0,
  111.     "300",  300,  0,
  112.     "600",  600,  0,
  113.    "1200", 1200,  0,
  114.    "2400", 2400,  0,
  115.    "3600", 3600,  0,
  116.    "4800", 4800,  0,
  117.    "9600", 9600,  0,
  118.   "19200",19200,  0
  119. };
  120. int nspd = (sizeof(spdtab) / sizeof(struct keytab)); /* how many speeds */
  121.  
  122. struct keytab lngtab[] = {
  123.     "ascii",            L_USASCII, 0,
  124.     "british",          L_BRITISH, 0,
  125.     "danish",           L_DANISH, 0,
  126.     "dutch",            L_DUTCH, 0,
  127.     "english",          L_USASCII, 0,
  128.     "finnish",          L_FINNISH, 0,
  129.     "french",           L_FRENCH, 0,
  130.     "fr-canadian",      L_FR_CANADIAN, 0,
  131.     "german",           L_GERMAN, 0,
  132.     "hungarian",        L_HUNGARIAN, 0,
  133.     "italian",          L_ITALIAN, 0,
  134.     "norwegian",        L_NORWEGIAN, 0,
  135.     "portuguese",       L_PORTUGUESE, 0,
  136.     "spanish",          L_SPANISH, 0,
  137.     "swedish",          L_SWEDISH, 0,
  138.     "swiss",            L_SWISS, 0
  139. };
  140. int nlng = (sizeof(lngtab) / sizeof(struct keytab)); /* how many languages */
  141.  
  142. /* Duplex keyword table */
  143.  
  144. struct keytab dpxtab[] = {
  145.     "full",      0, 0,
  146.     "half",      1, 0
  147. };
  148.  
  149. struct keytab filtab[] = {
  150.     "character-set", XYFILC, 0,
  151.     "display",       XYFILD, 0,
  152.     "names",         XYFILN, 0,
  153.     "type",          XYFILT, 0,
  154.     "warning",       XYFILW, 0
  155. };
  156. int nfilp = (sizeof(filtab) / sizeof(struct keytab));
  157.  
  158. struct keytab rfiltab[] = {     /* for REMOTE SET FILE */
  159.     "type",          XYFILT, 0
  160. };
  161. int nrfilp = (sizeof(rfiltab) / sizeof(struct keytab));
  162.  
  163. /* Send/Receive Parameters */
  164.  
  165. struct keytab srtab[] = {
  166.     "end-of-packet", XYEOL, 0,
  167.     "packet-length", XYLEN, 0,
  168.     "pad-character", XYPADC, 0,
  169.     "padding", XYNPAD, 0,
  170.     "start-of-packet", XYMARK, 0,
  171.     "timeout", XYTIMO, 0
  172. };
  173. int nsrtab = (sizeof(srtab) / sizeof(struct keytab));
  174.  
  175. struct keytab rsrtab[] = {      /* For REMOTE SET RECEIVE */
  176.     "packet-length", XYLEN, 0,
  177.     "timeout", XYTIMO, 0
  178. };
  179. int nrsrtab = (sizeof(rsrtab) / sizeof(struct keytab));
  180.  
  181. /* REMOTE SET */
  182.  
  183. struct keytab rmstab[] = {
  184.     "attributes",  XYATTR, 0,
  185.     "block-check", XYCHKT, 0,
  186.     "file",        XYFILE, 0,
  187.     "incomplete",  XYIFD,  0,
  188.     "receive",     XYRECV, 0,
  189.     "retry",       XYRETR, 0,
  190.     "server",      XYSERV, 0,
  191.     "transfer",    XYXFER, 0,
  192.     "window",      XYWIND, 0
  193. };
  194. int nrms = (sizeof(rmstab) / sizeof(struct keytab));
  195.  
  196. /* Flow Control */
  197. #ifdef OS2
  198.  
  199. extern int odsr;    /* In ckotio.c */
  200. extern int idsr;
  201. extern int octs;
  202.  
  203. struct keytab flotab[] = {
  204.     "none", 0, 0,
  205.     "xon/xoff", 1, 0,
  206.     "odsr",ODSR,0,
  207.     "idsr",IDSR,0,
  208.     "octs",OCTS,0
  209. };
  210. #else
  211.  
  212. struct keytab flotab[] = {
  213.     "none",     0, 0,
  214.     "xon/xoff", 1, 0
  215. };
  216. #endif
  217.  
  218. int nflo = (sizeof(flotab) / sizeof(struct keytab));
  219.  
  220. /*  Handshake characters  */
  221.  
  222. struct keytab hshtab[] = {
  223.     "bell", 007, 0,
  224.     "cr",   015, 0,
  225.     "esc",  033, 0,
  226.     "lf",   012, 0,
  227.     "none", 999, 0,         /* (can't use negative numbers) */
  228.     "xoff", 023, 0,
  229.     "xon",  021, 0
  230. };
  231. int nhsh = (sizeof(hshtab) / sizeof(struct keytab));
  232.  
  233. struct keytab fntab[] = {           /* File naming */
  234.     "converted", 1, 0,
  235.     "literal",   0, 0
  236. };
  237.  
  238. struct keytab fttab[] = {       /* File types */
  239.     "binary",    1, 0,
  240.     "text",      0, 0
  241. };
  242.  
  243. extern struct keytab mdmtab[] ;     /* Modem types (in module ckudia.c) */
  244. extern int nmdm;
  245.  
  246. extern struct keytab netcmd[];
  247. extern int nnets;
  248.  
  249. /* Parity keyword table */
  250.  
  251. struct keytab partab[] = {
  252.     "even",    'e', 0,
  253.     "mark",    'm', 0,
  254.     "none",      0, 0,
  255.     "odd",     'o', 0,
  256.     "space",   's', 0
  257. };
  258. int npar = (sizeof(partab) / sizeof(struct keytab));
  259.  
  260. struct keytab inptab [] = {     /* SET INPUT parameters */
  261.     "case",            IN_CAS, 0,
  262.     "default-timeout", IN_DEF, 0,
  263.     "echo",            IN_ECH, 0,
  264.     "timeout-action",  IN_TIM, 0
  265. };
  266. int ninp = (sizeof(inptab) / sizeof(struct keytab));
  267.  
  268. struct keytab intimt[] = {      /* SET INPUT TIMEOUT parameters */
  269.     "proceed", 0, 0,            /* 0 = proceed */
  270.     "quit",    1, 0         /* 1 = quit */
  271. };
  272.  
  273. struct keytab incast[] = {      /* SET INPUT CASE parameters */
  274.     "ignore",  0, 0,            /* 0 = ignore */
  275.     "observe", 1, 0         /* 1 = observe */
  276. };
  277.  
  278. /* On/Off table */
  279.  
  280. struct keytab onoff[] = {
  281.     "off",       0, 0,
  282.     "on",        1, 0
  283. };
  284.  
  285. /* Incomplete File Disposition table */
  286.  
  287. struct keytab ifdtab[] = {
  288.     "discard",   0, 0,
  289.     "keep",      1, 0
  290. };
  291.  
  292. /* Take parameters table */
  293. struct keytab taktab[] = {
  294.     "echo",  0, 0,
  295.     "error", 1, 0
  296. };
  297.  
  298.  
  299. #ifdef OS2
  300. /* Terminal parameters table */
  301. struct keytab trmtab[] = {
  302.     "bytesize",  0, 0,
  303.     "type",      1, 0
  304. };
  305. int ntrm = 2;
  306. #else
  307. /* Terminal parameters table */
  308. struct keytab trmtab[] = {
  309.     "bytesize",  0, 0
  310. };
  311. int ntrm = 1;
  312. #endif /* OS2 */
  313. struct keytab ttyptab[] = {
  314.     "tek4014",2,0,
  315.     "vt100", 1, 0
  316. };
  317. int nttyp = 2;
  318.  
  319. /* Server parameters table */
  320. struct keytab srvtab[] = {
  321.     "timeout",   0, 0
  322. };
  323.  
  324. /* 'set transfer' table */
  325. struct keytab tstab[] = {
  326.     "character-set", 1,   0  /*, */
  327. /*  "international", 2,   0, */  /* (not yet!) */
  328. /*  "normal",        0,   0  */  /* (what's this doing here?) */
  329. };
  330. int nts = (sizeof(tstab) / sizeof(struct keytab));
  331.  
  332. /* 'set transfer character-set' table */
  333. struct keytab tcstab[] = {
  334.     "ascii",   TC_NORMAL, 0,
  335.     "latin1",  TC_1LATIN, 0
  336. };
  337. int ntcs = (sizeof(tcstab) / sizeof(struct keytab));
  338.  
  339. /*  D O P R M  --  Set a parameter.  */
  340. /*
  341.  Returns:
  342.   -2: illegal input
  343.   -1: reparse needed
  344.    0: success
  345. */
  346. doprm(xx,rmsflg) int xx, rmsflg; {
  347.     int i, j, x, y, z;
  348.     char *s;
  349.  
  350. switch (xx) {
  351.  
  352.  
  353. case XYEOL: /* These have all been moved to set send/receive... */
  354. case XYLEN:     /* Let the user know what to do. */
  355. case XYMARK:
  356. case XYNPAD:
  357. case XYPADC:
  358. case XYTIMO:
  359.     printf("...Use 'set send' or 'set receive' instead.\n");
  360.     printf("Type 'help set send' or 'help set receive' for more info.\n");
  361.     return(success = 0);
  362.  
  363.  
  364.  
  365. case XYATTR:                /* File Attribute packets */
  366.     if ((y = seton(&z)) < 0) return(y);
  367.     if (y < 0) return(y);
  368.     if (rmsflg) {
  369.     return(sstate = setgen('S', "132", z ? "1" : "0", "")); 
  370.     } else {
  371.     atcapr = z;
  372.     return(success = y);
  373.     }
  374.  
  375. case XYIFD:             /* Incomplete file disposition */
  376.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  377.     if ((x = cmcfm()) < 0) return(x);
  378.     if (rmsflg) {
  379.     return(sstate = setgen('S', "310", y ? "1" : "0", "")); 
  380.     } else {
  381.     keep = y;
  382.     return(success = 1);
  383.     }
  384.  
  385. case XYINPU:                /* SET INPUT */
  386.     if ((y = cmkey(inptab,ninp,"","",xxstring)) < 0) return(y);
  387.     switch (y) {
  388.       case IN_DEF:          /* SET INPUT DEFAULT-TIMEOUT */
  389.     z = cmnum("Positive number","",10,&x,xxstring);
  390.     return(success = setnum(&indef,x,z,94));
  391.       case IN_TIM:          /* SET INPUT TIMEOUT-ACTION */
  392.     if ((z = cmkey(intimt,2,"","",xxstring)) < 0) return(z);
  393.     if ((x = cmcfm()) < 0) return(x);
  394.     intime = z;
  395.     return(success = 1);
  396.       case IN_CAS:          /* SET INPUT CASE */
  397.     if ((z = cmkey(incast,2,"","",xxstring)) < 0) return(z);
  398.     if ((x = cmcfm()) < 0) return(x);
  399.     incase = z;
  400.     return(success = 1);
  401.       case IN_ECH:          /* SET INPUT ECHO */
  402.     return(success = seton(&inecho));
  403.     break;
  404.     }
  405.     return(0);
  406.  
  407. #ifdef NETCONN
  408. case XYNET:
  409.     if ((z = cmkey(netcmd,nnets,"","tcp-ip-socket",xxstring)) < 0) return(z);
  410.     /* Currently this command does nothing */
  411.     if ((x = cmcfm()) < 0) return(x);   /* And confirmation of command */
  412.     return(success = 1);
  413. #endif /* NETCONN */
  414.  
  415. case XYNETW:                /* SET HOST or SET LINE */
  416. case XYLINE:
  417.     if (xx == XYNETW) {         /* SET HOST <hostname> */
  418.     if ((x = cmtxt("Network host name","",&s,xxstring)) < 0) return(x);
  419.     if (*s) {           /* They gave a hostname */
  420.         x = 1;          /* Network connection always local */
  421.         y = -1;         /* Special code for network */
  422.     } else {            /* They just said "set host" */
  423.         s = dftty;          /* So go back to normal */
  424.         x = dfloc;          /* default tty, location, */
  425.         y = mdmtyp;         /* previous modem type. */
  426.     }
  427.     }
  428.     if (xx == XYLINE) {         /* SET LINE */
  429.     if ((x = cmtxt("Device name",dftty,&s,xxstring)) < 0) return(x);
  430.     x = strcmp(s,dftty) ? -1 : dfloc; /* Maybe let ttopen figure it out */
  431.     y = mdmtyp;
  432.     }
  433.     ttclos();               /* close old line, if any was open */
  434.     tvtflg = 0;
  435.     if (ttopen(s,&x,y) < 0 ) {      /* Can we open the new line? */
  436.     perror("Sorry, can't open connection"); /* Can't. */
  437.     local = dfloc;          /* Go back to normal */
  438.     network = 0;
  439.     return(success = 0);        /* and return */
  440.     }
  441.     if (x > -1) local = x;      /* Opened ok, set local/remote. */
  442.     network = (y < 0);          /* Remember connection type. */
  443.     strcpy(ttname,s);           /* Copy name into real place. */
  444. /** if (!local) speed = -1;     /* If remote, say speed unknown. */
  445.     debug(F111,"set line ",ttname,local);
  446.     return(success = 1);
  447.  
  448. case XYLANG:                /* Language */
  449.     if ((y = cmkey(lngtab,nlng,"","ascii",xxstring)) < 0) /* language code */
  450.       return(y);
  451.     if ((x = cmcfm()) < 0) return(x);   /* And confirmation of command */
  452.  
  453.     /* Look up language and get associated character sets */
  454.     for (i = 0; (i < MAXLANG) && (langs[i].id != y); i++) ;
  455.     if (i >= MAXLANG) {
  456.     printf("internal error, sorry\n");
  457.     return(success = 0);
  458.     }
  459.     language = i;           /* All good, set the language, */
  460.     fcharset = langs[i].fc;     /* the file character set, */
  461.     tcharset = langs[i].tc;     /* and the transfer character set, */
  462.     tslevel = (tcharset == TC_USASCII) ? TS_L0 : TS_L1; /* Kermit's "Level" */
  463.     return(success = 1);
  464.  
  465. case XYCHKT:                /* Block check type */
  466.     if ((y = cmkey(blktab,3,"","1",xxstring)) < 0) return(y);
  467.     if ((x = cmcfm()) < 0) return(x);
  468.     bctr = y;
  469.     return(success = 1);
  470.  
  471. case XYCOUN:                /* SET COUNT */
  472.     if ((x = cmfld("Positive number, numeric variable, or 'argc'","",&s,
  473.            xxstring)) < 0)
  474.       return(x);
  475.     if ((y = cmcfm()) < 0) return(y);
  476.     lp = line;              /* Expand its value  */
  477.     xxstring(s,&lp);
  478.     s = line;
  479.     if (!xxstrcmp(s,"argc")) {
  480.     y = macargc[maclvl];
  481.     } else {
  482.     if (!chknum(s)) return(-2);
  483.     y = atoi(s);
  484.     }
  485.     if (y < 0) return(-2);
  486.     debug(F101,"XYCOUN: y","",y);
  487.     return(success = setnum(&count[cmdlvl],y,0,10000));
  488.  
  489. case XYDEBU:
  490.     return(success = seton(&deblog));
  491.  
  492. case XYDELA:
  493.     y = cmnum("Number of seconds before starting to send","5",10,&x,xxstring);
  494.     debug(F101,"XYDELA: y","",y);
  495.     return(success = setnum(&delay,x,y,94));
  496.  
  497. case XYDUPL:
  498.     if ((y = cmkey(dpxtab,2,"","full",xxstring)) < 0) return(y);
  499.     if ((x = cmcfm()) < 0) return(x);
  500.     duplex = y;
  501.     return(success = 1);
  502.  
  503. case XYESC:
  504.     y = cmnum("Decimal ASCII code for escape character","",10,&x,xxstring);
  505.     return(success = setcc(&escape,x,y));
  506.  
  507. case XYFILE:
  508.     if (rmsflg) {
  509.     if ((y = cmkey(rfiltab,nrfilp,"File parameter","",xxstring)) < 0)
  510.       return(y);
  511.     } else {
  512.     if ((y = cmkey(filtab,nfilp,"File parameter","",xxstring)) < 0)
  513.       return(y);
  514.     }
  515.     switch (y) {
  516.     /* int z; */                    /* Tickles bug in OS-9 compiler... */
  517.     case XYFILC:            /* Character set */
  518.         if ((x = cmkey(fcstab,nfilc,"local file code","ascii",
  519.                xxstring)) < 0)
  520.             return(x);
  521.         if ((z = cmcfm()) < 0) return(z);
  522.         fcharset = x;
  523.         return(success = 1);
  524.  
  525.     case XYFILD:            /* Display */
  526.         y = seton(&z);
  527.         if (y < 0) return(y);
  528.         quiet = !z;
  529.         return(success = 1);
  530.  
  531.     case XYFILN:            /* Names */
  532.         if ((x = cmkey(fntab,2,"how to handle filenames","converted",
  533.                xxstring)) < 0)
  534.             return(x);
  535.         if ((z = cmcfm()) < 0) return(z);
  536.         fncnv = x;
  537.         return(success = 1);
  538.  
  539.     case XYFILT:            /* Type */
  540.         if ((x = cmkey(fttab,2,"type of file","text",xxstring)) < 0)
  541.             return(x);
  542.         if ((y = cmnum("file byte size (7 or 8)","8",10,&z,xxstring)) < 0)
  543.             return(y);
  544.         if (z != 7 && z != 8) {
  545.         printf("\n?The choices are 7 and 8\n");
  546.         return(-2);
  547.         }
  548.         if ((y = cmcfm()) < 0) return(y);
  549.         if (rmsflg) {
  550.         return(sstate = setgen('S', "300", x ? "1" : "0", "")); 
  551.         } else {
  552.         binary = x;
  553.         if (z == 7) fmask = 0177;
  554.         else if (z == 8) fmask = 0377;
  555.         return(success = 1);
  556.         }
  557.  
  558.     case XYFILW:            /* Warning/Write-Protect */
  559.         return(success = seton(&warn));
  560.  
  561.     default:
  562.         printf("?unexpected file parameter\n");
  563.         return(-2);
  564.     }
  565.  
  566. case XYFLOW:                /* Flow control */
  567.     if ((y = cmkey(flotab,nflo,"","xon/xoff",xxstring)) < 0) return(y);
  568.  
  569. #ifdef OS2
  570.     if(y<ODSR)
  571.         {
  572.         if ((x = cmcfm()) < 0) return(x);
  573.         flow = y;
  574.         return(success=1);
  575.         }
  576.     else    /* This deals with setting the hardware handshake control */
  577.         {
  578.         return(os2_set_hand(y));
  579.         }
  580. #else
  581.     if ((x = cmcfm()) < 0) return(x);
  582.     flow = y;
  583.     return(success = 1);
  584. #endif 
  585.  
  586. case XYHAND:                /* Handshake */
  587.     if ((y = cmkey(hshtab,nhsh,"","none",xxstring)) < 0) return(y);
  588.     if ((x = cmcfm()) < 0) return(x);
  589.     turn = (y > 0127) ? 0 : 1 ;
  590.     turnch = y;
  591.     return(success = 1);
  592.  
  593. case XYMACR:
  594.     /* Note, if TAKE and MACRO options become different, make a new table */
  595.     if ((y = cmkey(taktab,2,"","",xxstring)) < 0) return(y);
  596.     switch (y) {
  597.       case 0: return(success = seton(&mecho));
  598.       case 1: return(success = seton(&merror));
  599.       default: return(-2);
  600.     }
  601.  
  602. case XYMODM:
  603.     if ((x=cmkey(mdmtab,nmdm,"type of modem, direct means none","direct",
  604.          xxstring)) < 0)
  605.     return(x);
  606.     if ((z = cmcfm()) < 0) return(z);
  607.     mdmtyp = x;
  608.     return(success = 1);
  609.     
  610. case XYPARI:                /* Parity */
  611.     if ((y = cmkey(partab,npar,"","none",xxstring)) < 0) return(y);
  612.     if ((x = cmcfm()) < 0) return(x);
  613.  
  614. /* If parity not none, then we also want 8th-bit prefixing */
  615.  
  616.     if (parity = y) ebqflg = 1; else ebqflg = 0;
  617.     return(success = 1);
  618.  
  619. case XYPROM:
  620.     if ((x = cmtxt("Program's command prompt","C-Kermit>",&s,xxstring)) < 0)
  621.       return(x);
  622.     cmsetp(s);
  623.     return(success = 1);
  624.  
  625. case XYRETR:                /* Per-packet retry limit */
  626.     y = cmnum("Maximum retries per packet","10",10,&x,xxstring);
  627.     if ((x = setnum(&maxtry,x,y,94)) < 0) return(x);
  628.     sprintf(tmpbuf,"%d",maxtry);
  629.     if (rmsflg) {
  630.     return(sstate = setgen('S', "403", tmpbuf, ""));
  631.     } else return(success = x);
  632.  
  633. case XYSERV:                /* Server timeout */
  634.     if ((y = cmkey(srvtab,1,"","timeout",xxstring)) < 0) return(y);
  635.     switch (y) {
  636.       case XYSERT:
  637.     tp = tmpbuf;
  638.         sprintf(tp,"%d",DSRVTIM);
  639.     if ((y = cmnum("interval for server NAKs, 0 = none",tp,10,&x,
  640.                xxstring)) < 0)
  641.       return(y);
  642.     if (x < 0) {
  643.         printf("\n?Specify a positive number, or 0 for no server NAKs\n");
  644.         return(-2);
  645.     }
  646.     if ((y = cmcfm()) < 0) return(y);
  647.     sprintf(tp,"%d",x);
  648.     if (rmsflg) {
  649.         return(sstate = setgen('S', "404", tp, ""));
  650.     } else {
  651.         srvtim = x;         /* Set the server timeout variable */
  652.         return(success = 1);
  653.     }
  654.       default:
  655.     return(-2);
  656.     }
  657.  
  658. case XYTAKE:                /* SET TAKE */
  659.     if ((y = cmkey(taktab,2,"","",xxstring)) < 0) return(y);
  660.     switch (y) {
  661.       case 0: return(success = seton(&techo));
  662.       case 1: return(success = seton(&terror));
  663.       default: return(-2);
  664.     }
  665.  
  666. case XYTERM:                /* Terminal parameters */
  667.     if ((y = cmkey(trmtab,ntrm,"","bytesize",xxstring)) < 0) return(y);
  668.     switch (y) {
  669.       case 0:
  670.     if ((y = cmnum("bytesize for terminal connection","8",10,&x,
  671.                xxstring)) < 0)
  672.       return(y);
  673.     if (x != 7 && x != 8) {
  674.         printf("\n?The choices are 7 and 8\n");
  675.         return(-2);
  676.     }
  677.     if ((y = cmcfm()) < 0) return(y);
  678.     if (x == 7) cmask = 0177;
  679.     else if (x == 8) cmask = 0377;
  680.         return(success = 1);
  681. #ifdef OS2
  682.       case 1:               /* Select terminal emulation */
  683.     if ((x = cmkey(ttyptab,nttyp,"","vt100",xxstring)) < 0) return(x);
  684.     if ((y = cmcfm()) < 0) return(y);
  685.     if (x == 1) {
  686.         Term_mode = VT100;
  687.         return(success = 1);
  688.     } else if (x == 2) {
  689.         Term_mode = TEKTRONIX;
  690.         Tek_scrinit(0);     /* Initialise Tektronix emulation */
  691.         return(success = 1);
  692.     } else return(-2);
  693. #endif /* OS2 */
  694.       default:       /* Add more cases when we think of more parameters */
  695.     return(-2);
  696.     }    
  697.  
  698. /* SET SEND/RECEIVE... */
  699.  
  700. case XYRECV:
  701. case XYSEND:
  702.     if (xx == XYRECV)
  703.         strcpy(line,"Parameter for inbound packets");
  704.     else
  705.         strcpy(line,"Parameter for outbound packets");
  706.  
  707.     if (rmsflg) {
  708.     if ((y = cmkey(rsrtab,nrsrtab,line,"",xxstring)) < 0) return(y);
  709.     } else {
  710.     if ((y = cmkey(srtab,nsrtab,line,"",xxstring)) < 0) return(y);
  711.     }
  712.     switch (y) {
  713.  
  714. case XYEOL:
  715.     y = cmnum("Decimal ASCII code for packet terminator","13",10,&x,xxstring);
  716.     if ((y = setcc(&z,x,y)) < 0) return(y);
  717.     if (xx == XYRECV) eol = z; else seol = z;
  718.     return(success = y);
  719.  
  720. case XYLEN:
  721.     y = cmnum("Maximum number of characters in a packet","90",10,&x,xxstring);
  722.     if (xx == XYRECV) {         /* Receive... */
  723.     if ((y = setnum(&z,x,y,MAXRP)) < 0)
  724.       return(y);
  725.     if (rmsflg) {
  726.         tp = tmpbuf;
  727.         sprintf(tp,"%d",z);
  728.         return(sstate = setgen('S', "401", tp, ""));
  729.     } else {
  730.         urpsiz = z;
  731.         if ((urpsiz * wslotsr) > BIGRBUFSIZ) {
  732.         urpsiz = BIGRBUFSIZ / wslotsr - 1;
  733.         if (cmdlvl == 0)
  734.          printf("adjusted to %d for %d window slots\n",urpsiz,wslotsr);
  735.         }
  736.         rpsiz =  (z > 94) ? 94 : z;
  737.     }
  738.     } else {                /* Send... */
  739.     if ((y = setnum(&z,x,y,MAXSP)) < 0)
  740.       return(y);
  741.     if ((z * wslotsr) > BIGRBUFSIZ) {
  742.         z = BIGRBUFSIZ / wslotsr - 1;
  743.         printf("adjusted to %d for %d window slots\n",z,wslotsr);
  744.     }
  745.     spsiz = z;          /*   Set it and flag that it was set */
  746.     spsizf = 1;         /*   to allow overriding Send-Init. */
  747.     }
  748.     if (!backgrd && cmdlvl == 0) {
  749.     if (z > 94) printf("Extended-length packets requested.\n");
  750.     if (network == 0 && z > 999 && speed <= 0)
  751.       printf("\
  752. Make sure your timeout interval is long enough for %d-byte packets.\n",z);
  753.     if (bctr < 2) printf("\
  754. Remember to SET BLOCK 2 or 3 for long packets.\n");
  755.     }
  756.     return(success = y);
  757.  
  758. case XYMARK:
  759.     y = cmnum("Code for packet-start character","1",10,&x,xxstring);
  760.     if ((y = setcc(&z,x,y)) < 0) return(y);
  761.     if (xx == XYRECV) stchr = z; else mystch = z;
  762.     return(success = y);
  763.  
  764. case XYNPAD:                /* Padding */
  765.     y = cmnum("How many padding characters for inbound packets","0",10,&x,
  766.           xxstring);
  767.     if ((y = setnum(&z,x,y,94)) < 0) return(y);
  768.     if (xx == XYRECV) mypadn = z; else npad = z;
  769.     return(success = y);
  770.  
  771. case XYPADC:                /* Pad character */
  772.     y = cmnum("Decimal ASCII code for inbound pad character","0",10,&x,
  773.           xxstring);
  774.     if ((y = setcc(&z,x,y)) < 0) return(y);
  775.     if (xx == XYRECV) mypadc = z; else padch = z;
  776.     return(success = y);
  777.  
  778. case XYTIMO:
  779.     y = cmnum("Interpacket timeout interval","5",10,&x,xxstring);
  780.     if ((y = setnum(&z,x,y,94)) < 0) return(y);
  781.     if (xx == XYRECV) {
  782.     if (rmsflg) {
  783.         tp = tmpbuf;
  784.         sprintf(tp,"%d",z);
  785.         return(sstate = setgen('S', "402", tp, ""));
  786.     } else {
  787.         timef = 1;
  788.         timint = z;
  789.     }
  790.     } else rtimo = z;
  791.     return(success = y);
  792.  
  793.   }                 /* End of SET SEND/RECEIVE... */
  794.  
  795. case XYSPEE:
  796.     if (network) {
  797.     printf("\n?Speed cannot be set for network connections\n");
  798.     return(success = 0);
  799.     }
  800.     lp = line;
  801.     sprintf(lp,"Baud rate for %s",ttname);
  802.  
  803.     if ((x = cmkey(spdtab,nspd,line,"",xxstring)) < 0) return(x);
  804.     if ((y = cmcfm()) < 0) return(y);
  805.     y = chkspd(x);
  806.     if (y < 0)  {
  807.         printf("?Unsupported line speed - %d\n",x);
  808.         return(success = 0);
  809.     } else {
  810.         speed = y;
  811.     if (!backgrd && cmdlvl == 0) {
  812.         printf("%s, %d bps",ttname,speed);
  813.         if (!local)
  814.           printf(" (speed not changed, used for information only)\n");
  815.         printf("\n");
  816.     }
  817.     }
  818.     return(success = 1);
  819.  
  820.   case XYXFER:
  821.     if ((y = cmkey(tstab,nts,"","normal",xxstring)) < 0) return(y);
  822.     if (y == 1) {           /* character-set */
  823.     if ((y = cmkey(tcstab,ntcs,"","ascii",xxstring)) < 0) return(y);
  824.     if ((x = cmcfm()) < 0) return(x);
  825.     if (rmsflg) {
  826.         return(sstate = setgen('S', "405", tcsinfo[y].designator, ""));
  827.     } else {
  828.         tslevel = 1;
  829.         tcharset = y;
  830.         return(success = 1);
  831.     }
  832.     }
  833.     if ((x = cmcfm()) < 0) return(x);
  834.     if (y > 1) {            /* International syntax */
  835.     printf("(not implemented yet)\n");
  836.     return(success = 0);
  837.     }
  838.     if (y == 0) {           /* Normal syntax */
  839.     tslevel = 0;
  840.     tcharset = y;
  841.     return(success = 1);
  842.     }
  843.     return(0);              /* ??? */
  844.  
  845.   case XYUNCS:              /* Unknown character set */
  846.     if ((y = cmkey(ifdtab,2,"","discard",xxstring)) < 0) return(y);
  847.     if ((x = cmcfm()) < 0) return(x);
  848.     unkcs = y;
  849.     return(success = 1);
  850.  
  851.   case XYWIND:              /* Window slots */
  852.     y = cmnum("Number of sliding-window slots, 1 to 31","1",10,&x,xxstring);
  853.     y = setnum(&wslotsr,x,y,31);
  854.     if (y < 0) return(y);
  855.     if (wslotsr < 1) wslotsr = 1;
  856.     if (rmsflg) {
  857.     tp = tmpbuf;
  858.     sprintf(tp,"%d",wslotsr);
  859.     return(sstate = setgen('S', "406", tp, ""));
  860.     }
  861.     swcapr = (wslotsr > 1) ? 1 : 0;
  862.     if (wslotsr > 1) {
  863.     swcapr = 1;
  864.     if ((urpsiz * wslotsr) > BIGRBUFSIZ) {
  865.         urpsiz = BIGRBUFSIZ / wslotsr - 1;
  866.         printf("Adjusting receive packet size to %d for %d window slots\n",
  867.            urpsiz, wslotsr);
  868.     }
  869.     } else swcapr = 0;
  870.     return(success = 1);
  871.  
  872. default:
  873.     if ((x = cmcfm()) < 0) return(x);
  874.     printf("Not working yet - %s\n",cmdbuf);
  875.     return(success = 0);
  876.     }
  877. }
  878.  
  879. /*  C H K S P D  --  Check if argument is a valid baud rate  */
  880.  
  881. chkspd(x) int x; {
  882.     switch (x) {
  883. #ifndef AMIGA
  884.     case 0:
  885. #endif
  886. #ifndef datageneral
  887.     case 110:
  888.     case 150:
  889.     case 300:
  890.     case 600:
  891.     case 1200:
  892. #ifndef OS2
  893.     case 1800:
  894. #endif
  895.     case 2400:
  896.     case 4800:
  897.     case 9600:
  898.         case 19200:
  899. #ifdef AMIGA
  900.     case 38400:
  901.     case 57600:
  902. #endif
  903. #endif
  904.  
  905. #ifdef datageneral
  906.     case 50:
  907.     case 75:
  908.     case 134:
  909.     case 3600:
  910.     case 7200:
  911.     case 19200:
  912.     case 38400:
  913. #endif
  914.         return(x);
  915.     default: 
  916. #ifdef AMIGA
  917.         if (ttsspd(x) > 0) {
  918.             printf("Warning: non-standard baud rate - %d\n", x);
  919.         return(x);
  920.         }
  921. #endif
  922. #ifdef VMS
  923.         if (ttsspd(x) > 0) {
  924.         printf("Warning: non-standard baud rate - %d\n", x);
  925.         return(x);
  926.         }
  927. #endif
  928.         return(-1);
  929.       }
  930. }
  931.  
  932. /*  S E T O N  --  Parse on/off (default on), set parameter to result  */
  933.  
  934. seton(prm) int *prm; {
  935.     int x, y;
  936.     if ((y = cmkey(onoff,2,"","on",xxstring)) < 0) return(y);
  937.     if ((x = cmcfm()) < 0) return(x);
  938.     *prm = y;
  939.     return(1);
  940. }
  941.  
  942. /*  S E T N U M  --  Set parameter to result of cmnum() parse.  */
  943. /*
  944.  Call with x - number from cnum parse, y - return code from cmnum
  945. */
  946. setnum(prm,x,y,max) int x, y, *prm, max; {
  947.     debug(F101,"setnum","",y);
  948.     if (y < 0) return(y);
  949.     if (x > max) {
  950.     printf("\n?Sorry, %d is the maximum\n",max);
  951.     return(-2);
  952.     }
  953.     if ((y = cmcfm()) < 0) return(y);
  954.     *prm = x;
  955.     return(1);
  956. }
  957.  
  958. /*  S E T C C  --  Set parameter to an ASCII control character value.  */
  959.  
  960. setcc(prm,x,y) int x, y, *prm; {
  961.     if (y < 0) return(y);
  962.     if ((x > 037) && (x != 0177)) {
  963.     printf("\n?Not in ASCII control range - %d\n",x);
  964.     return(-2);
  965.     }
  966.     if ((y = cmcfm()) < 0) return(y);
  967.     *prm = x;
  968.     return(1);
  969. }
  970.  
  971. /*  D O R M T  --  Do a remote command  */
  972.  
  973. dormt(xx) int xx; {
  974.     int x, y;
  975.     char *s, sbuf[50], *s2;
  976.  
  977.     if (xx < 0) return(xx);
  978.     switch (xx) {
  979.  
  980. case XZCWD:             /* CWD */
  981.     if ((x = cmtxt("Remote directory name","",&s,xxstring)) < 0) return(x);
  982.     debug(F111,"XZCWD: ",s,x);
  983.     *sbuf = NUL;
  984.     s2 = sbuf;
  985.     if (*s != NUL) {            /* If directory name given, */
  986.                     /* get password on separate line. */
  987.         if (tlevel > -1) {      /* From take file... */
  988.  
  989.         if (fgets(sbuf,50,tfile[tlevel]) == NULL)
  990.             fatal("take file ends prematurely in 'remote cwd'");
  991.         debug(F110," pswd from take file",s2,0);
  992.         for (x = strlen(sbuf);
  993.              x > 0 && (sbuf[x-1] == NL || sbuf[x-1] == CR);
  994.          x--)
  995.         sbuf[x-1] = '\0';
  996.  
  997.         } else {            /* From terminal... */
  998.  
  999.         printf(" Password: ");      /* get a password */
  1000. #ifdef OS2
  1001.         while (((x = isatty(0) ? coninc(0) :
  1002.              getchar()) != NL) && (x != CR)) {     /* with no echo */
  1003. #else
  1004.         while (((x = getchar()) != NL) && (x != CR)) { /* with no echo */
  1005. #endif
  1006.             if ((x &= 0177) == '?') {
  1007.                 printf("? Password of remote directory\n Password: ");
  1008.             s2 = sbuf;
  1009.             *sbuf = NUL;
  1010.             }
  1011.             else if (x == ESC)  /* Mini command line editor... */
  1012.                 putchar(BEL);
  1013.         else if (x == BS || x == 0177)
  1014.             s2--;
  1015.         else if (x == 025) {    /* Ctrl-U */
  1016.             s2 = sbuf;
  1017.             *sbuf = NUL;
  1018.         }
  1019.             else
  1020.             *s2++ = x;
  1021.             }
  1022.         *s2 = NUL;
  1023.         putchar('\n');
  1024.         }
  1025.         s2 = sbuf;
  1026.     } else s2 = "";
  1027.     debug(F110," password",s2,0);
  1028.     sstate = setgen('C',s,s2,"");
  1029.     return(0);
  1030.  
  1031. case XZDEL:             /* Delete */
  1032.     if ((x = cmtxt("Name of remote file(s) to delete","",&s,xxstring)) < 0)
  1033.       return(x);
  1034.     return(sstate = rfilop(s,'E'));
  1035.  
  1036. case XZDIR:             /* Directory */
  1037.     if ((x = cmtxt("Remote directory or file specification","",&s,
  1038.            xxstring)) < 0)
  1039.         return(x);
  1040.     return(sstate = setgen('D',s,"",""));
  1041.  
  1042. case XZHLP:             /* Help */
  1043.     if ((x = cmcfm()) < 0) return(x);
  1044.     sstate = setgen('H',"","","");
  1045.     return(0);
  1046.  
  1047. case XZHOS:             /* Host */
  1048.     if ((x = cmtxt("Command for remote system","",&cmarg,xxstring)) < 0)
  1049.       return(x);
  1050.     return(sstate = 'c');
  1051.  
  1052. case XZPRI:             /* Print */
  1053.     cmarg = "";
  1054.     cmarg2 = "";
  1055.     if ((x = cmifi("Local file(s) to print on remote printer","",&s,&y,
  1056.            xxstring)) < 0) {
  1057.     if (x == -3) {
  1058.         printf("?A file specification is required\n");
  1059.         return(-2);
  1060.     }
  1061.     return(x);
  1062.     }
  1063.     strcpy(line,s);         /* Make a safe copy of filename */
  1064.     *optbuf = NUL;          /* Wipe out any old options */
  1065.     if ((x = cmtxt("Options for remote print command","",&s,xxstring)) < 0)
  1066.       return(x);
  1067.     strcpy(optbuf,s);           /* Make a safe copy of options */
  1068.     if (strlen(optbuf) > 94) {      /* Make sure this is legal */
  1069.     printf("?Option string too long\n");
  1070.     return(-2);
  1071.     }
  1072.     nfils = -1;             /* Expand file list internally */
  1073.     cmarg = line;           /* Point to file list. */
  1074.     rprintf = 1;            /* REMOTE PRINT modifier for SEND */
  1075.     sstate = 's';           /* Set start state to SEND */
  1076.     if (local) displa = 1;
  1077.     return(0);
  1078.     
  1079. case XZSET:             /* Set */
  1080.     if ((y = cmkey(rmstab,nrms,"","",xxstring)) < 0) return(y);
  1081.     return(doprm(y,1));
  1082.  
  1083. case XZSPA:             /* Space */
  1084.     if ((x = cmtxt("Confirm, or remote directory name","",&s,xxstring)) < 0)
  1085.       return(x);
  1086.     return(sstate = setgen('U',s,"",""));
  1087.     
  1088. case XZTYP:             /* Type */
  1089.     if ((x = cmtxt("Remote file specification","",&s,xxstring)) < 0) return(x);
  1090.     return(sstate = rfilop(s,'T'));
  1091.  
  1092. case XZWHO:
  1093.     if ((x = cmtxt("Remote user name, or carriage return","",&s,xxstring)) < 0)
  1094.         return(x);
  1095.     return(sstate = setgen('W',s,"",""));
  1096.  
  1097. default:
  1098.     if ((x = cmcfm()) < 0) return(x);
  1099.     printf("not working yet - %s\n",cmdbuf);
  1100.     return(-2);
  1101.     }
  1102. }
  1103.  
  1104.  
  1105.  
  1106. /*  R F I L O P  --  Remote File Operation  */
  1107.  
  1108. rfilop(s,t) char *s, t; {
  1109.     if (*s == NUL) {
  1110.     printf("?File specification required\n");
  1111.     return(-2);
  1112.     }
  1113.     debug(F111,"rfilop",s,t);
  1114.     return(setgen(t,s,"",""));
  1115. }
  1116.  
  1117. /*  S C R E E N  --  Screen display function  */
  1118.  
  1119. /*  screen(f,c,n,s)
  1120.       f - argument descriptor
  1121.       c - a character or small integer
  1122.       n - a long integer
  1123.       s - a string.
  1124.  Fill in this routine with the appropriate display update for the system.
  1125.  This version is for a dumb tty.
  1126. */
  1127. screen(f,c,n,s) int f; char c; long n; char *s; {
  1128.     static int p = 0;           /* Screen position */
  1129.     int len;                /* Length of string */
  1130.     char buf[80];           /* Output buffer */
  1131.     len = strlen(s);            /* Length of string */
  1132.     if ((f != SCR_WM) && (f != SCR_EM)) /* Always update warning & errors */
  1133.       if (!displa || quiet) return; /* No update if display flag off */
  1134.  
  1135.     switch (f) {
  1136.  
  1137. case SCR_FN:                /* filename */
  1138.     conoll(""); conol(s); conoc(SP); p = len + 1; return;
  1139.  
  1140. case SCR_AN:                /* as-name */
  1141.     if (p + len > 75) { conoll(""); p = 0; }
  1142.     conol("=> "); conol(s); if ((p += (len + 3)) > 78) { conoll(""); p = 0; }
  1143.     return;
  1144.  
  1145. case SCR_FS:                /* file-size */
  1146.     sprintf(buf,", Size: %ld",n);  conoll(buf);  p = 0; return;
  1147.  
  1148. case SCR_XD:                /* x-packet data */
  1149.     conoll(""); conoll(s); p = 0; return;
  1150.     
  1151. case SCR_ST:                /* File status */
  1152.     switch (c) {
  1153.     case ST_OK:             /*  Transferred OK */
  1154.         if ((p += 5) > 78) { conoll(""); p = 0; }
  1155.         conoll(" [OK]"); p += 5; return;
  1156.  
  1157.     case ST_DISC:           /*  Discarded */
  1158.         if ((p += 12) > 78) { conoll(""); p = 0; }
  1159.         conoll(" [discarded]"); p += 12; return;
  1160.  
  1161.     case ST_INT:            /*  Interrupted */
  1162.         if ((p += 14) > 78) { conoll(""); p = 0; }
  1163.         conoll(" [interrupted]"); p += 14; return;
  1164.  
  1165.     case ST_SKIP:           /*  Skipped */
  1166.         conoll("");
  1167.         conol("Skipping "); conoll(s); p = 0;
  1168.         return;
  1169.  
  1170.         case ST_ERR:
  1171.         conoll("");
  1172.         conol("Error "); conoll(s); p = 0;
  1173.         return;
  1174.  
  1175.         default:
  1176.         conoll("*** screen() called with bad status ***"); p = 0; return;
  1177.     }
  1178.  
  1179. case SCR_PN:                /* Packet number */
  1180.     sprintf(buf,"%s: %ld",s,n); conol(buf); p += strlen(buf); return;
  1181.  
  1182. case SCR_PT:                /* Packet type or pseudotype */
  1183.     if (c == 'Y') return;       /* Don't bother with ACKs */
  1184.     if (c == 'D') {         /* Only show every 4th data packet */
  1185.     if (n % 4) return;
  1186.     c = '.';
  1187.     }
  1188. #ifndef AMIGA
  1189.     if (p++ > 78) {         /* If near right margin, */
  1190.     conoll("");         /* Start new line */
  1191.     p = 0;              /* and reset counter. */
  1192.     }
  1193. #endif
  1194.     conoc(c);               /* Display the character. */
  1195. #ifdef AMIGA
  1196.     if (c == 'G') conoll("");           /* new line after G packets */
  1197. #endif
  1198.     return;
  1199.  
  1200. case SCR_TC:                /* transaction complete */
  1201.     conoc(BEL); return;
  1202.  
  1203. case SCR_EM:                /* Error message */
  1204.     conoll(""); conoc('?'); conoll(s); p = 0; return;       /* +1   */
  1205.  
  1206. case SCR_WM:                /* Warning message */
  1207.     conoll(""); conoll(s); p = 0; return;
  1208.  
  1209. case SCR_TU:                /* Undelimited text */
  1210.     if ((p += len) > 78) { conoll(""); p = len; }
  1211.     conol(s); return;
  1212.  
  1213. case SCR_TN:                /* Text delimited at beginning */
  1214.     conoll(""); conol(s); p = len; return;
  1215.  
  1216. case SCR_TZ:                /* Text delimited at end */
  1217.     if ((p += len) > 78) { conoll(""); p = len; }
  1218.     conoll(s); return;
  1219.     
  1220. case SCR_QE:                /* Quantity equals */
  1221.     sprintf(buf,"%s: %ld",s,n);
  1222.     conoll(buf); p = 0; return;
  1223.  
  1224. default:
  1225.     conoll("*** screen() called with bad object ***"); p = 0; return;
  1226.     }
  1227. }
  1228.  
  1229. /*  I N T M S G  --  Issue message about terminal interrupts  */
  1230.  
  1231. intmsg(n) long n; {
  1232.     extern char *chstr();
  1233.     char buf[80];
  1234.  
  1235.     if ((!displa) || (quiet)) return;
  1236. #ifdef UXIII
  1237.     (void) conchk();    /* clear out pending escape-signals in ckxbsd.c */
  1238. #endif
  1239.     if (n == 1) {
  1240. #ifdef UXIII
  1241.  
  1242. #ifndef aegis
  1243. #ifndef datageneral
  1244.                 /* we need to signal before kb input */
  1245.     sprintf(buf,"Type escape (%s) followed by:",chstr(escape));
  1246.     screen(SCR_TN,0,0l,buf);
  1247. #endif
  1248. #endif
  1249. #endif
  1250.  screen(SCR_TN,0,0l,"CTRL-F to cancel file,  CTRL-R to resend current packet");
  1251.  screen(SCR_TN,0,0l,"CTRL-B to cancel batch, CTRL-A for status report: ");
  1252.     }
  1253.     else screen(SCR_TU,0,0l," ");
  1254. }
  1255.  
  1256. /*  C H K I N T  --  Check for console interrupts  */
  1257.  
  1258. /*** should rework not to destroy typeahead ***/
  1259.  
  1260. chkint() {
  1261.     int ch, cn;
  1262.  
  1263.     if ((!local) || (quiet)) return(0); /* Only do this if local & not quiet */
  1264. #ifdef datageneral
  1265.     cn = (con_reads_mt) ? 1 : conchk(); /* Any input waiting? */
  1266. #else
  1267.     cn = conchk();          /* Any input waiting? */
  1268. #endif
  1269.     debug(F101,"conchk","",cn);
  1270.  
  1271.     while (cn > 0) {            /* Yes, read it. */
  1272.     cn--;
  1273.             /* give read 5 seconds for interrupt character */
  1274. #ifdef datageneral
  1275.         /* We must be careful to just print out one result for each character
  1276.          * read.  The flag, conint_avl, controls duplication of characters.
  1277.          * Only one character is handled at a time, which is a reasonable
  1278.          * limit.  More complicated schemes could handle a buffer.
  1279.          */
  1280.         if (con_reads_mt) {
  1281.             if ((ch = conint_ch) <= 0) return(0);   /* I/O error, or no data */
  1282.             else if (conint_avl == 0) return(0);    /* Char already read */
  1283.             else conint_avl = 0;                    /* Flag char as read */
  1284.         }
  1285.         else { if ((ch = coninc(5)) < 0) return(0);  }
  1286. #else
  1287.     if ((ch = coninc(5)) < 0) return(0);
  1288. #endif
  1289.     switch (ch & 0177) {
  1290.         case 'A':
  1291.         case 0001:          /* CTRL-A */
  1292.         screen(SCR_TN,0,0l,"^A  Status report:");
  1293.         screen(SCR_TN,0,0l," file type: ");
  1294.         if (binary) screen(SCR_TZ,0,0l,"binary");
  1295.             else    screen(SCR_TZ,0,0l,"text");
  1296.         screen(SCR_QE,0,(long)filcnt," file number");
  1297.         screen(SCR_QE,0,(long)ffc,   " characters ");
  1298.         screen(SCR_QE,0,(long)bctu,  " block check");
  1299.         screen(SCR_QE,0,(long)rptflg," compression");
  1300.         screen(SCR_QE,0,(long)ebqflg," 8th-bit prefixing");
  1301.         continue;
  1302.         case 'B':
  1303.         case 'Z':
  1304.         case 'z':
  1305.         case 0002:          /* CTRL-B */
  1306.             screen(SCR_TN,0,0l,"^B - Cancelling Batch ");
  1307.             czseen = 1;
  1308.         continue;
  1309.         case 'F':
  1310.         case 'X':
  1311.         case 'x':
  1312.         case 0006:          /* CTRL-F */
  1313.             screen(SCR_TN,0,0l,"^F - Cancelling File ");
  1314.             cxseen = 1;
  1315.         continue;
  1316.         case 'R':
  1317.         case 0022:                  /* CTRL-R */
  1318.             screen(SCR_TN,0,0l,"^R - Resending ");
  1319.             resend();
  1320.         return(1);
  1321.  
  1322.         case 'C':           /* Exit abruptly */
  1323.         case 'E':           /* Send error packet */
  1324.             screen(SCR_TU,0,0l," [not implemented yet] ");
  1325.         continue;
  1326.  
  1327.         default:            /* Anything else, just ignore */
  1328.             screen(SCR_TU,0,0l," [Ignored] ");
  1329.         continue;
  1330.         }
  1331.     }
  1332.     return(0);
  1333. }
  1334.  
  1335. /*  D E B U G  --  Enter a record in the debugging log  */
  1336.  
  1337. /*
  1338.  Call with a format, two strings, and a number:
  1339.    f  - Format, a bit string in range 0-7.
  1340.         If bit x is on, then argument number x is printed.
  1341.    s1 - String, argument number 1.  If selected, printed as is.
  1342.    s2 - String, argument number 2.  If selected, printed in brackets.
  1343.    n  - Int, argument 3.  If selected, printed preceded by equals sign.
  1344.  
  1345.    f=0 is special: print s1,s2, and interpret n as a char.
  1346. */
  1347. #ifdef DEBUG
  1348. #define DBUFL 2300
  1349. debug(f,s1,s2,n) int f, n; char *s1, *s2; {
  1350.     static char s[DBUFL];
  1351.     char *sp = s;
  1352.  
  1353.     if (!deblog) return;        /* If no debug log, don't */
  1354.     switch (f) {
  1355.         case F000:          /* 0, print both strings, */
  1356.         if (strlen(s1) + strlen(s2) + 5 > DBUFL) { /* and n as a char */
  1357.         sprintf(sp,"DEBUG string too long\n");
  1358.         } else {
  1359.         if (n > 31 && n < 127)
  1360.           sprintf(sp,"%s%s:%c\n",s1,s2,n);
  1361.         else if (n < 32 || n == 127)
  1362.           sprintf(sp,"%s%s:^%c\n",s1,s2,(n+64) & 0x7F);
  1363.         else if (n > 127 && n < 160)
  1364.           sprintf(sp,"%s%s:~^%c\n",s1,s2,(n-64) & 0x7F);
  1365.         else if (n > 159 && n < 256)
  1366.           sprintf(sp,"%s%s:~%c\n",s1,s2,n & 0x7F);
  1367.         else sprintf(sp,"%s%s:%d\n",s1,s2,n);
  1368.         }
  1369.         zsout(ZDFILE,s);
  1370.         break;
  1371.         case F001:          /* 1, "=n" */
  1372.         sprintf(sp,"=%d\n",n);
  1373.         zsout(ZDFILE,s);
  1374.         break;
  1375.         case F010:          /* 2, "[s2]" */
  1376.         if (strlen(s2) + 4 > DBUFL)
  1377.           sprintf(sp,"DEBUG string too long\n");
  1378.         else sprintf(sp,"[%s]\n",s2);
  1379.         zsout(ZDFILE,"");
  1380.         break;
  1381.         case F011:          /* 3, "[s2]=n" */
  1382.         if (strlen(s2) + 15 > DBUFL)
  1383.           sprintf(sp,"DEBUG string too long\n");
  1384.         else sprintf(sp,"[%s]=%d\n",s2,n);
  1385.         zsout(ZDFILE,s);
  1386.         break;
  1387.         case F100:          /* 4, "s1" */
  1388.         zsoutl(ZDFILE,s1);
  1389.         break;
  1390.         case F101:          /* 5, "s1=n" */
  1391.         if (strlen(s1) + 15 > DBUFL)
  1392.           sprintf(sp,"DEBUG string too long\n");
  1393.         else sprintf(sp,"%s=%d\n",s1,n);
  1394.         zsout(ZDFILE,s);
  1395.         break;
  1396.         case F110:          /* 6, "s1[s2]" */
  1397.         if (strlen(s1) + strlen(s2) + 4 > DBUFL)
  1398.           sprintf(sp,"DEBUG string too long\n");
  1399.         else sprintf(sp,"%s[%s]\n",s1,s2);
  1400.         zsout(ZDFILE,s);
  1401.         break;
  1402.         case F111:          /* 7, "s1[s2]=n" */
  1403.         if (strlen(s1) + strlen(s2) + 15 > DBUFL)
  1404.           sprintf(sp,"DEBUG string too long\n");
  1405.         else sprintf(sp,"%s[%s]=%d\n",s1,s2,n);
  1406.         zsout(ZDFILE,s);
  1407.         break;
  1408.     default:
  1409.         sprintf(sp,"\n?Invalid format for debug() - %d\n",n);
  1410.         zsout(ZDFILE,s);
  1411.     }
  1412. }
  1413. #endif
  1414.  
  1415. #ifdef TLOG
  1416. #define TBUFL 300
  1417. /*  T L O G  --  Log a record in the transaction file  */
  1418. /*
  1419.  Call with a format and 3 arguments: two strings and a number:
  1420.    f  - Format, a bit string in range 0-7, bit x is on, arg #x is printed.
  1421.    s1,s2 - String arguments 1 and 2.
  1422.    n  - Int, argument 3.
  1423. */
  1424. tlog(f,s1,s2,n) int f; long n; char *s1, *s2; {
  1425.     static char s[TBUFL];
  1426.     char *sp = s; int x;
  1427.     
  1428.     if (!tralog) return;        /* If no transaction log, don't */
  1429.     switch (f) {
  1430.         case F000:          /* 0 (special) "s1 n s2"  */
  1431.         if (strlen(s1) + strlen(s2) + 15 > TBUFL)
  1432.           sprintf(sp,"?T-Log string too long\n");
  1433.         else sprintf(sp,"%s %ld %s\n",s1,n,s2);
  1434.         zsout(ZTFILE,s);
  1435.         break;
  1436.         case F001:          /* 1, " n" */
  1437.         sprintf(sp," %ld\n",n);
  1438.         zsout(ZTFILE,s);
  1439.         break;
  1440.         case F010:          /* 2, "[s2]" */
  1441.         x = strlen(s2);
  1442.         if (s2[x] == '\n') s2[x] = '\0';
  1443.         if (x + 6 > TBUFL)
  1444.           sprintf(sp,"?T-Log string too long\n");
  1445.         else sprintf(sp,"[%s]\n",s2);
  1446.         zsout(ZTFILE,"");
  1447.         break;
  1448.         case F011:          /* 3, "[s2] n" */
  1449.         x = strlen(s2);
  1450.         if (s2[x] == '\n') s2[x] = '\0';
  1451.         if (x + 6 > TBUFL)
  1452.           sprintf(sp,"?T-Log string too long\n");
  1453.         else sprintf(sp,"[%s] %ld\n",s2,n);
  1454.         zsout(ZTFILE,s);
  1455.         break;
  1456.         case F100:          /* 4, "s1" */
  1457.         zsoutl(ZTFILE,s1);
  1458.         break;
  1459.         case F101:          /* 5, "s1: n" */
  1460.         if (strlen(s1) + 15 > TBUFL)
  1461.           sprintf(sp,"?T-Log string too long\n");
  1462.         else sprintf(sp,"%s: %ld\n",s1,n);
  1463.         zsout(ZTFILE,s);
  1464.         break;
  1465.         case F110:          /* 6, "s1 s2" */
  1466.         x = strlen(s2);
  1467.         if (s2[x] == '\n') s2[x] = '\0';
  1468.         if (strlen(s1) + x + 4 > TBUFL)
  1469.           sprintf(sp,"?T-Log string too long\n");
  1470.         else sprintf(sp,"%s %s\n",s1,s2);
  1471.         zsout(ZTFILE,s);
  1472.         break;
  1473.         case F111:          /* 7, "s1 s2: n" */
  1474.         x = strlen(s2);
  1475.         if (s2[x] == '\n') s2[x] = '\0';
  1476.         if (strlen(s1) + x + 15 > TBUFL)
  1477.           sprintf(sp,"?T-Log string too long\n");
  1478.         else sprintf(sp,"%s %s: %ld\n",s1,s2,n);
  1479.         zsout(ZTFILE,s);
  1480.         break;
  1481.     default:
  1482.         sprintf(sp,"\n?Invalid format for tlog() - %ld\n",n);
  1483.         zsout(ZTFILE,s);
  1484.     }
  1485. }
  1486. #endif
  1487.