home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / cklpro.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  58KB  |  1,926 lines

  1.  
  2. /* WARNING -- This C source program generated by Wart preprocessor. */
  3. /* Do not edit this file; edit the Wart-format source file instead, */
  4. /* and then run it through Wart to produce a new C source file.     */
  5.  
  6. /* Wart Version Info: */
  7. char *wartv = "Wart Version 2A(010) 4 Apr 95";
  8.  
  9. char *protv = "C-Kermit Protocol Module 6.0.095, 6 Sep 96"; /* -*-C-*- */
  10.  
  11. /* C K C P R O  -- C-Kermit Protocol Module, in Wart preprocessor notation. */
  12. /*
  13.   Author: Frank da Cruz <fdc@columbia.edu>,
  14.   Columbia University Academic Information Systems, New York City.
  15.  
  16.   Copyright (C) 1985, 1996, Trustees of Columbia University in the City of New
  17.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  18.   sold for profit as a software product itself, nor may it be included in or
  19.   distributed with commercial products or otherwise distributed by commercial
  20.   concerns to their clients or customers without written permission of the
  21.   Office of Kermit Development and Distribution, Columbia University.  This
  22.   copyright notice must not be removed, altered, or obscured.
  23. */
  24. #include "ckcsym.h"
  25. #include "ckcdeb.h"
  26. #include "ckcasc.h"
  27. #include "ckcker.h"
  28. #ifdef OS2
  29. #ifndef NT
  30. #define INCL_NOPM
  31. #define INCL_VIO            /* Needed for ckocon.h */
  32. #include <os2.h> 
  33. #undef COMMENT
  34. #endif /* NT */
  35. #include "ckocon.h"
  36. #endif /* OS2 */
  37.  
  38. /*
  39.  Note -- This file may also be preprocessed by the UNIX Lex program, but 
  40.  you must indent the above #include statements before using Lex, and then
  41.  restore them to the left margin in the resulting C program before compilation.
  42.  Also, the invocation of the "wart()" function below must be replaced by an
  43.  invocation  of the "yylex()" function.  It might also be necessary to remove
  44.  comments in the %%...%% section.
  45. */
  46.  
  47. /* State definitions for Wart (or Lex) */
  48. #define ipkt 1
  49. #define rfile 2
  50. #define rattr 3
  51. #define rdata 4
  52. #define ssinit 5
  53. #define ssfile 6
  54. #define ssattr 7
  55. #define ssdata 8
  56. #define sseof 9
  57. #define sseot 10
  58. #define serve 11
  59. #define generic 12
  60. #define get 13
  61. #define rgen 14
  62.  
  63. /* External C-Kermit variable declarations */
  64.   extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err;
  65.   extern char filnam[], fspec[], ttname[];
  66.   extern CHAR sstate, *rpar(), *srvptr, *data;
  67.   extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network;
  68.   extern int rejection, moving, fncact, bye_active;
  69.   extern int protocol, prefixing, filcnt;
  70.   extern struct ck_p ptab[];
  71.   extern int remfile, rempipe;
  72.   extern char * remdest;
  73.  
  74. #ifndef NOSERVER
  75.   extern char * x_user, * x_passwd, * x_acct;
  76.   extern int x_login, x_logged;
  77. #endif /* NOSERVER */
  78.  
  79. #ifdef NETCONN
  80. #ifdef CK_SPEED
  81.   extern int ttnproto;            /* Network protocol */
  82.   extern short ctlp[];            /* Control-character prefix table */
  83. #endif /* CK_SPEED */
  84. #ifdef TCPSOCKET
  85. #include "ckcnet.h"
  86.   extern int me_binary, tn_b_nlm, tn_nlm;
  87. #endif /* TCPSOCKET */
  88. #endif /* NETCONN */
  89.  
  90. #ifdef TCPSOCKET
  91. #ifndef NOLISTEN
  92.   extern int tcpsrfd;
  93. #endif /* NOLISTEN */
  94. #endif /* TCPSOCKET */
  95.  
  96.   extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl;
  97.   extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo;
  98.   extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla;
  99.   extern int timef, stdinf, rscapu, sendmode, epktflg;
  100.   extern int binary, fncnv;
  101.   extern long speed, ffc, crc16;
  102.   extern char *DIRCMD, *DIRCM2, *DELCMD, *TYPCMD, *SPACMD, *SPACM2, *WHOCMD;
  103.   extern CHAR *rdatap;
  104.   extern struct zattr iattr;
  105.  
  106. #ifdef pdp11
  107.   extern CHAR srvcmd[];
  108.   extern CHAR *pktmsg;
  109. #else
  110. #ifdef DYNAMIC
  111.   extern CHAR *srvcmd;
  112.   extern CHAR *pktmsg;
  113. #else
  114.   extern CHAR srvcmd[];
  115.   extern CHAR pktmsg[];
  116. #endif /* DYNAMIC */
  117. #endif /* pdp11 */
  118.  
  119. #ifdef CK_TMPDIR
  120. extern int f_tmpdir;            /* Directory changed temporarily */
  121. extern char savdir[];            /* For saving current directory */
  122. extern char * dldir;
  123. #endif /* CK_TMPDIR */
  124.  
  125. #ifndef NOSPL
  126.   extern int cmdlvl;
  127.   char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */
  128.   char *qbufp = querybuf;        /* Pointer to it */
  129.   int qbufn = 0;            /* Length of data in it */
  130.   extern int query;            /* Query-active flag */
  131. #else
  132.   extern int tlevel;
  133. #endif /* NOSPL */
  134.  
  135. #ifdef NT
  136.   extern int escape;
  137. #endif /* NT */
  138. /*
  139.   If the following flag is nonzero when the protocol module is entered,
  140.   then server mode persists for exactly one transaction, rather than
  141.   looping until BYE or FINISH is received.
  142. */
  143. int justone = 0;
  144.  
  145. _PROTOTYP(static VOID xxproto,(void));
  146. _PROTOTYP(static int sgetinit,(int));
  147. _PROTOTYP(int sndspace,(int));
  148. _PROTOTYP(int wart,(void));
  149.  
  150. /* Flags for the ENABLE and DISABLE commands */
  151. extern int
  152.   en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
  153.   en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret;
  154. #ifndef NOSPL
  155. extern int en_asg, en_que;
  156. #endif /* NOSPL */
  157.  
  158. /* Global variables declared here */
  159.  
  160.   int what = W_NOTHING;            /* What I am doing */
  161.   int whatru = 0;            /* What are you */
  162.  
  163. /* Local variables */
  164.  
  165.   static char vstate = 0;          /* Saved State   */
  166.   static char vcmd = 0;            /* Saved Command */
  167.   static int reget = 0;
  168.   static int retrieve = 0;
  169.  
  170.   static int x;                /* General-purpose integer */
  171.   static char *s;            /* General-purpose string pointer */
  172.  
  173. /* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */
  174. /* BEGIN is NOT a GOTO! */
  175. #define BEGIN state = 
  176. #define ENABLED(x) ((local && (x & 1)) || (!local && (x & 2)))
  177. #define TINIT if (tinit() < 0) return(-9)
  178. #define SERVE TINIT; nakstate=1; what=W_NOTHING; cmarg2=""; sendmode=SM_SEND; BEGIN serve;
  179. #define RESUME if (!server) { return(0); } else if (justone) { justone=0; return(0); } else { SERVE; }
  180. #define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x;  return(1)
  181.  
  182. int state = 0;
  183.  
  184. int
  185. wart()
  186. {
  187.     int c,actno;
  188.     extern char tbl[];
  189.     while (1) {
  190.     c = input() - 32;
  191.         if (c < 0 || c > 95) c = 0;
  192.     if ((actno = tbl[c + state*96]) != -1)
  193.         switch(actno) {
  194. case 1:
  195.     { TINIT;                /* Do Send command */
  196.     if (sinit() > 0) BEGIN ssinit;
  197.        else RESUME; }
  198.     break;
  199. case 2:
  200.     { TINIT; nakstate = 1; BEGIN get; }
  201.     break;
  202. case 3:
  203.     {                    /* Get */
  204.     TINIT;
  205.     vstate = get;
  206.     reget = 0;
  207.     retrieve = 0;
  208.     vcmd = 0;
  209.     if (sipkt('I') >= 0)
  210.       BEGIN ipkt;
  211.     else
  212.       RESUME;
  213. }
  214.     break;
  215. case 4:
  216.     {                    /* RETRIEVE */
  217.     TINIT;
  218.     vstate = get;
  219.     reget = 0;
  220.     retrieve = 1;
  221.     vcmd = 0;
  222.     if (sipkt('I') >= 0)
  223.       BEGIN ipkt;
  224.     else
  225.       RESUME;
  226. }
  227.     break;
  228. case 5:
  229.     {                    /* REGET */
  230.     TINIT;
  231.     vstate = get;
  232.     reget = 1;
  233.     retrieve = 0;
  234.     vcmd = 0;
  235.     if (sipkt('I') >= 0)
  236.       BEGIN ipkt;
  237.     else
  238.       RESUME;
  239. }
  240.     break;
  241. case 6:
  242.     {                    /* Host */
  243.     TINIT;
  244.     vstate = rgen;
  245.     vcmd = 'C';
  246.     if (sipkt('I') >= 0)
  247.       BEGIN ipkt;
  248.     else
  249.       RESUME;
  250. }
  251.     break;
  252. case 7:
  253.     { TINIT;                /* Kermit */
  254.     vstate = rgen;
  255.     vcmd = 'K';
  256.     if (sipkt('I') >= 0)
  257.       BEGIN ipkt;
  258.     else
  259.       RESUME;
  260. }
  261.     break;
  262. case 8:
  263.     {                    /* Generic */
  264.     TINIT;
  265.     vstate = rgen;
  266.     vcmd = 'G';
  267.     if (sipkt('I') >= 0)
  268.       BEGIN ipkt;
  269.     else
  270.       RESUME;
  271. }
  272.     break;
  273. case 9:
  274.     {                    /* Be a Server */
  275.     int x;
  276.     x = justone;
  277.     debug(F101,"x justone 1","",justone);
  278.     SERVE;                /* tinit() clears justone... */
  279.     debug(F101,"x justone 2","",justone);
  280.     justone = x;
  281. }
  282.     break;
  283. case 10:
  284.     {
  285.     int b1 = 0, b2 = 0;
  286.     if (!data) TINIT;            /* "ABEND" -- Tell other side. */
  287. #ifndef pdp11
  288.     if (epktflg) {            /* If because of E-PACKET command */
  289.     b1 = bctl; b2 = bctu;        /* Save block check type */
  290.     bctl = bctu = 1;        /* set it to 1 */
  291.     }
  292. #endif /* pdp11 */
  293.     errpkt((CHAR *)"User cancelled");    /* Send the packet */
  294. #ifndef pdp11
  295.     if (epktflg) {            /* Restore the block check */
  296.     epktflg = 0;
  297.     bctl = b1; bctu = b2;
  298.     }
  299.     screen(SCR_EM,0,0L,"User cancelled");
  300. #endif /* pdp11 */
  301.     success = 0;
  302.     return(0);                /* Return from protocol. */
  303. }
  304.     break;
  305. case 11:
  306.     {            /* Receive Send-Init packet. */
  307. #ifndef NOSERVER
  308.     if (state == serve && x_login && !x_logged) {
  309.     errpkt((CHAR *)"Login required");
  310.     SERVE;
  311.     } else
  312. #endif /* NOSERVER */
  313.       
  314.       if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */
  315.     errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */
  316.     RESUME;
  317.     } else {                /* OK to go ahead. */
  318. #ifdef CK_TMPDIR
  319.     if (dldir && !f_tmpdir) {    /* If they have a download directory */
  320.         debug(F110,"receive download dir",dldir,0);
  321.         if (s = zgtdir()) {        /* Get current directory */
  322.         debug(F110,"receive current dir",s,0);
  323.         if (zchdir(dldir)) {    /* Change to download directory */
  324.             debug(F100,"receive zchdir ok","",0);
  325.             strncpy(savdir,s,TMPDIRLEN);
  326.             f_tmpdir = 1;    /* Remember that we did this */
  327.         } else
  328.           debug(F100,"receive zchdir failed","",0);
  329.         }
  330.     }
  331. #endif /* CK_TMPDIR */
  332.     nakstate = 1;            /* Can send NAKs from here. */
  333.     rinit(rdatap);            /* Set parameters */
  334.     bctu = bctr;            /* Switch to agreed-upon block check */
  335.     bctl = (bctu == 4) ? 2 : bctu;    /* Set block-check length */
  336.     what = W_RECV;            /* Remember we're receiving */
  337.     resetc();            /* Reset counters */
  338.     rtimer();            /* Reset timer */
  339.     BEGIN rfile;            /* Go into receive-file state */
  340.     }
  341. }
  342.     break;
  343. case 12:
  344.     {                /* Get ack for I-packet */
  345.     int x = 0;
  346.     spar(rdatap);            /* Set parameters */
  347.     winlo = 0;                /* Set window-low back to zero */
  348.     if (vcmd) {                /* If sending a generic command */
  349.     TINIT;
  350.     x = scmd(vcmd,(CHAR *)cmarg);    /* Do that */
  351.     vcmd = 0;            /* and then un-remember it. */
  352.     } else if (vstate == get) {
  353.     debug(F101,"REGET sstate","",sstate);
  354.     x = srinit(reget, retrieve);    /* GET or REGET */
  355.     }
  356.     if (x < 0) {            /* If command was too long */
  357.     errpkt((CHAR *)"Command too long for server"); /* cancel both sides. */
  358.     ermsg("Command too long for server");
  359.     success = 0;
  360.     RESUME;
  361.     } else {
  362.     rtimer();            /* Reset the elapsed seconds timer. */
  363.     winlo = 0;            /* Window back to 0, again. */
  364.     nakstate = 1;            /* Can send NAKs from here. */
  365.     BEGIN vstate;            /* Switch to desired state */
  366.     }
  367. }
  368.     break;
  369. case 13:
  370.     {                /* Ignore Error reply to I packet */
  371.     int x = 0;
  372.     winlo = 0;                /* Set window-low back to zero */
  373.     if (vcmd) {                /* In case other Kermit doesn't */
  374.     TINIT;
  375.     x = scmd(vcmd,(CHAR *)cmarg);    /* understand I-packets. */
  376.     vcmd = 0;            /* Otherwise act as above... */
  377.     } else if (vstate == get) x = srinit(reget, retrieve);
  378.     if (x < 0) {            /* If command was too long */
  379.     errpkt((CHAR *)"Command too long for server"); /* cancel both sides. */
  380.     ermsg("Command too long for server");
  381.     success = 0;
  382.     RESUME;
  383.     } else {
  384.     winlo = 0;            /* Back to packet 0 again. */
  385.     freerpkt(winlo);        /* Discard the Error packet. */
  386.     nakstate = 1;            /* Can send NAKs from here. */
  387.     BEGIN vstate;
  388.     }
  389. }
  390.     break;
  391. case 14:
  392.     {        /* Resend of previous I-pkt ACK, same seq number! */
  393.     srinit(reget, retrieve);        /* Send the GET packet again. */
  394. }
  395.     break;
  396. case 15:
  397.     {                /* Get I-packet */
  398. #ifndef NOSERVER
  399.     spar(rdatap);            /* Set parameters from it */
  400.     ack1(rpar());            /* Respond with our own parameters */
  401.     pktinit();                /* Reinitialize packet numbers */
  402. #endif /* NOSERVER */
  403. }
  404.     break;
  405. case 16:
  406.     {                /* Get Receive-Init (GET) */
  407. #ifndef NOSERVER
  408.     if (x_login && !x_logged) {
  409.     errpkt((CHAR *)"Login required");
  410.     SERVE;
  411.     } else if (sgetinit(0) < 0) {
  412.     RESUME;
  413.     } else {
  414.     BEGIN ssinit;
  415.     }
  416. #endif /* NOSERVER */
  417. }
  418.     break;
  419. case 17:
  420.     {                /* GET and DELETE ("retrieve") */
  421. #ifndef NOSERVER
  422.     if (x_login && !x_logged) {
  423.     errpkt((CHAR *)"Login required");
  424.     RESUME;
  425.     } else if (!ENABLED(en_ret)) {
  426.     errpkt((CHAR *)"RETRIEVE disabled - use GET");
  427.     RESUME;
  428.     } else if (!ENABLED(en_del)) {
  429.     errpkt((CHAR *)"Deleting files disabled - use GET");
  430.     RESUME;
  431.     } else if (sgetinit(0) < 0) {
  432.     RESUME;
  433.     } else {
  434.     moving = 1;
  435.     BEGIN ssinit;
  436.     }
  437. #endif /* NOSERVER */
  438. }
  439.     break;
  440. case 18:
  441.     {                /* Get REGET */
  442. #ifndef NOSERVER
  443.     if (x_login && !x_logged) {
  444.     errpkt((CHAR *)"Login required");
  445.     SERVE;
  446.     } else if (sgetinit(1) < 0) {
  447.     RESUME;
  448.     } else {
  449.     BEGIN ssinit;
  450.     }
  451. #endif /* NOSERVER */
  452. }
  453.     break;
  454. case 19:
  455.     {                /* Generic server command */
  456. #ifndef NOSERVER
  457.     srvptr = srvcmd;            /* Point to command buffer */
  458.     decode(rdatap,putsrv,0);        /* Decode packet data into it */
  459.     putsrv(NUL);            /* Insert a couple nulls */
  460.     putsrv(NUL);            /* for termination */
  461.     if (srvcmd[0]) {
  462.     sstate = srvcmd[0];        /* Set requested start state */
  463.     if (x_login && !x_logged && sstate != 'I') {
  464.         errpkt((CHAR *)"Login required");
  465.         SERVE;
  466.     } else {
  467.         nakstate = 0;        /* Now I'm the sender. */
  468.         what = W_REMO;        /* Doing a REMOTE command. */
  469.         if (timint < 1)
  470.           timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
  471.         BEGIN generic;        /* Switch to generic command state */
  472.     }
  473.     } else {
  474.     errpkt((CHAR *)"Badly formed server command"); /* report error */
  475.     RESUME;            /* & go back to server command wait */
  476.     }
  477. #endif /* NOSERVER */
  478. }
  479.     break;
  480. case 20:
  481.     {                /* Receive Host command */
  482. #ifndef NOSERVER
  483.     if (x_login && !x_logged) {
  484.     errpkt((CHAR *)"Login required");
  485.     SERVE;
  486.     } else
  487.       if (!ENABLED(en_hos)) {
  488.     errpkt((CHAR *)"REMOTE HOST disabled");
  489.     RESUME;
  490.     } else {
  491.     srvptr = srvcmd;        /* Point to command buffer */
  492.     decode(rdatap,putsrv,0);    /* Decode command packet into it */
  493.     putsrv(NUL);            /* Null-terminate */
  494.     nakstate = 0;            /* Now sending, not receiving */
  495.     if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */
  496.         what = W_REMO;        /* Doing a REMOTE command. */
  497.         if (timint < 1)
  498.           timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
  499.         BEGIN ssinit;        /* If OK, send back its output */
  500.     } else {            /* Otherwise */
  501.         errpkt((CHAR *)"Can't do system command"); /* report error */
  502.         RESUME;            /* & go back to server command wait */
  503.     }
  504.     }
  505. #endif /* NOSERVER */
  506. }
  507.     break;
  508. case 21:
  509.     {                /* User typed Ctrl-C... */
  510. #ifndef NOSERVER
  511.     if (!ENABLED(en_fin)) {
  512.     errpkt((CHAR *)"QUIT disabled");
  513.     RESUME;
  514.     } else {
  515.     success = 0; QUIT;
  516.     }
  517. #endif /* NOSERVER */
  518. }
  519.     break;
  520. case 22:
  521.     {                /* Server got a NAK in command-wait */
  522. #ifndef NOSERVER
  523.     errpkt((CHAR *)"Did you say RECEIVE instead of GET?");
  524.     RESUME;
  525. #endif /* NOSERVER */
  526. }
  527.     break;
  528. case 23:
  529.     {                /* Any other command in this state */
  530. #ifndef NOSERVER
  531.     if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */
  532.       errpkt((CHAR *)"Unimplemented server function");
  533.     /* If we answer an E with an E, we get an infinite loop. */
  534.     /* A Y (ACK) can show up here if we sent back a short-form reply to */
  535.     /* a G packet and it was echoed.  ACKs can be safely ignored here. */
  536.     RESUME;                /* Go back to server command wait. */
  537. #endif /* NOSERVER */
  538. }
  539.     break;
  540. case 24:
  541.     {                /* Login/out */
  542. #ifndef NOSERVER
  543.     char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1];
  544.     CHAR *p;
  545.     int len, i;
  546.  
  547.     f1[0] = NUL; f2[0] = NUL; f3[0] = NUL;
  548.     if (x_login) {            /* Login required */
  549.     len = 0;
  550.     if (srvcmd[1])            /* First length field */
  551.       len = xunchar(srvcmd[1]);    /* Separate the parameters */
  552.     if (len > 0 && len <= LOGINLEN) { /* Have username */
  553.         p = srvcmd + 2;        /* Point to it */
  554.         for (i = 0; i < len; i++)    /* Copy it */
  555.           f1[i] = p[i];
  556.         f1[len] = NUL;        /* Terminate it */
  557.         p += len;            /* Point to next length field */
  558.         if (*p) {            /* If we have one */
  559.         len = xunchar(*p++);    /* decode it */
  560.         if (len > 0 && len <= LOGINLEN) {
  561.             for (i = 0; i < len; i++) /* Same deal for password */
  562.               f2[i] = p[i];
  563.             f2[len] = NUL;
  564.             p += len;        /* And account */
  565.             if (*p) {
  566.             len = xunchar(*p++);    
  567.             if (len > 0 && len <= LOGINLEN) {
  568.                 for (i = 0; i < len; i++)
  569.                   f3[i] = p[i];
  570.                 f3[len] = NUL;
  571.             }
  572.             }
  573.         }
  574.         }
  575.     }
  576.     debug(F110,"XXX user",f1,0);
  577.     debug(F110,"XXX pass",f2,0);
  578.     debug(F110,"XXX acct",f3,0);
  579.     if (!f1[0]) {
  580.         if (x_logged) {
  581.         tlog(F110,"Logged out",x_user,0);
  582.         ack1((CHAR *)"Logged out");
  583.         } else {
  584.         ack1((CHAR *)"You were not logged in");
  585.         }
  586.         x_logged = 0;
  587.     } else {
  588.         x_logged = 0;
  589.         if (x_user && x_passwd) {    /* Username and password must match */
  590.         if (!strcmp(x_user,f1))
  591.           if (!strcmp(x_passwd,f2))
  592.             x_logged = 1;
  593.         } else if (x_user) {    /* Only username must match */
  594.         if (!strcmp(x_user,f1))
  595.             x_logged = 1;
  596.         }          
  597.         if (x_logged) {
  598.         tlog(F110,"Logged in", x_user, 0);
  599.         ack1((CHAR *)"Logged in");
  600.         } else {
  601.         tlog(F110,"Login failed", f1, 0);
  602.         ack1((CHAR *)"Login failed");
  603.         }
  604.     }
  605.     } else {
  606.     ack1((CHAR *)"No login required");
  607.     }
  608.     SERVE;
  609. #endif /* NOSERVER */
  610. }
  611.     break;
  612. case 25:
  613.     {                /* Got REMOTE CD command */
  614. #ifndef NOSERVER
  615.     if (!ENABLED(en_cwd)) {
  616.     errpkt((CHAR *)"REMOTE CD disabled");
  617.     RESUME;
  618.     } else {
  619.     if (!cwd((char *)(srvcmd+1))) errpkt((CHAR *)"Can't change directory");
  620.     RESUME;                /* Back to server command wait */
  621.     }
  622. #endif /* NOSERVER */
  623. }
  624.     break;
  625. case 26:
  626.     {                /* Got REMOTE PWD command */
  627. #ifndef NOSERVER
  628.     if (!ENABLED(en_cwd)) {
  629.     errpkt((CHAR *)"REMOTE CD disabled");
  630.     RESUME;
  631.     } else {
  632.     if (encstr((CHAR *)zgtdir()) > -1) /* Get & encode current directory */
  633.       ack1(data);            /* If it fits, send it back in ACK */
  634.     RESUME;                /* Back to server command wait */
  635.     }
  636. #endif /* NOSERVER */
  637. }
  638.     break;
  639. case 27:
  640.     {                /* REMOTE DIRECTORY command */
  641. #ifndef NOSERVER
  642.     char *n2;
  643.     if (!ENABLED(en_dir)) {        /* If DIR is disabled, */
  644.     errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */
  645.     RESUME;
  646.     } else {                /* DIR is enabled. */
  647.     if (!ENABLED(en_cwd)) {        /* But CWD is disabled */
  648.         zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
  649.         if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
  650.         errpkt((CHAR *)"Access denied");
  651.         RESUME;            /* Remember, this is not a goto! */
  652.         }
  653.     }    
  654.     if (state == generic) {            /* It's OK to go ahead. */
  655. #ifdef COMMENT
  656.         n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2;
  657.         if (syscmd(n2,(char *)(srvcmd+2)))  /* If it can be done */
  658. #else
  659.         if (snddir((char*)(srvcmd+2)))
  660. #endif /* COMMENT */
  661.               BEGIN ssinit;            /* send the results back */
  662.         else {                /* otherwise */
  663.         errpkt((CHAR *)"Can't list directory"); /* report failure, */
  664.         RESUME;            /* return to server command wait */
  665.         }
  666.     }
  667.     }
  668. #endif /* NOSERVER */
  669. }
  670.     break;
  671. case 28:
  672.     {                /* REMOTE DELETE (Erase) command */
  673. #ifndef NOSERVER
  674.     char *n2;
  675.     if (!ENABLED(en_del)) {
  676.     errpkt((CHAR *)"REMOTE DELETE disabled");    
  677.     RESUME;
  678.     } else {                /* DELETE is enabled */
  679.     if (!ENABLED(en_cwd)) {        /* but CWD is disabled */
  680.         zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
  681.         if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
  682.         errpkt((CHAR *)"Access denied");
  683.         RESUME;            /* Remember, this is not a goto! */
  684.         }
  685.     }    
  686.     if (state == generic) {        /* It's OK to go ahead. */
  687.         if (
  688. #ifdef COMMENT
  689.         syscmd(DELCMD,(char *)(srvcmd+2)) /* Old way */
  690. #else
  691.         snddel((char*)(srvcmd+2))    /* New way */
  692. #endif /* COMMENT */
  693.         )
  694.           BEGIN ssinit;        /* If OK send results back */
  695.         else {            /* otherwise */
  696.         errpkt((CHAR *)"Can't remove file"); /* report failure */
  697.         RESUME;            /* & return to server command wait */
  698.         }
  699.     }
  700.     }
  701. #endif /* NOSERVER */
  702. }
  703.     break;
  704. case 29:
  705.     {                /* FINISH */
  706. #ifndef NOSERVER
  707.     if (!ENABLED(en_fin)) {
  708.     errpkt((CHAR *)"FINISH disabled");    
  709.     RESUME;
  710.     } else {
  711.     ack();                /* Acknowledge */
  712.     screen(SCR_TC,0,0L,"");        /* Display */
  713.     return(0);            /* Done */
  714.     }
  715. #endif /* NOSERVER */
  716. }
  717.     break;
  718. case 30:
  719.     {                /* BYE */
  720. #ifndef NOSERVER
  721.     if (!ENABLED(en_bye)) {
  722.     errpkt((CHAR *)"BYE disabled");    
  723.     RESUME;
  724.     } else {
  725.     ack();                /* Acknowledge */
  726.     ttres();            /* Reset the terminal */
  727.     screen(SCR_TC,0,0L,"");        /* Display */
  728.     doclean();            /* Clean up files, etc */
  729. #ifdef DEBUG
  730.     debug(F100,"C-Kermit BYE","",0);
  731.     zclose(ZDFILE);
  732. #endif /* DEBUG */
  733.     return(zkself());        /* Try to log self out */
  734.     }
  735. #endif /* NOSERVER */
  736. }
  737.     break;
  738. case 31:
  739.     {                /* REMOTE HELP */
  740. #ifndef NOSERVER
  741.     extern char * hlptxt;
  742.     if (sndhlp(hlptxt)) BEGIN ssinit;    /* Try to send it */
  743.     else {                /* If not ok, */
  744.     errpkt((CHAR *)"Can't send help"); /* send error message instead */
  745.     RESUME;                /* and return to server command wait */
  746.     }
  747. #endif /* NOSERVER */
  748. }
  749.     break;
  750. case 32:
  751.     {                            /* REMOTE RENAME */
  752. #ifndef NOSERVER
  753. #ifdef ZRENAME
  754.     char *str1, *str2, f1[256], f2[256];
  755.     int  len1, len2;
  756.  
  757.     if (!ENABLED(en_ren)) {
  758.     errpkt((CHAR *)"REMOTE RENAME disabled");
  759.     RESUME;
  760.     } else {                /* RENAME is enabled */
  761.     int len1, len2;
  762.     len1 = xunchar(srvcmd[1]);    /* Separate the parameters */
  763.     len2 = xunchar(srvcmd[2+len1]);
  764.     strncpy(f1,(char *)(srvcmd+2),len1);
  765.     f1[len1] = NUL;
  766.     strncpy(f2,(char *)(srvcmd+3+len1),len2);
  767.     f2[len2] = NUL; 
  768.  
  769.     len2 = xunchar(srvcmd[2+len1]);
  770.     strncpy(f1,(char *)(srvcmd+2),len1);
  771.     f1[len1] = NUL;
  772.     strncpy(f2,(char *)(srvcmd+3+len1),len2);
  773.     f2[len2] = NUL; 
  774.         
  775.     if (!ENABLED(en_cwd)) {        /* If CWD is disabled */
  776.         zstrip(f1,&str1);        /* and they included a pathname, */
  777.         zstrip(f2,&str2);
  778.         if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */
  779.         errpkt((CHAR *)"Access denied");
  780.         RESUME;            /* Remember, this is not a goto! */
  781.         }
  782.     }    
  783.     if (state == generic) {        /* It's OK to go ahead. */
  784.         if (zrename(f1,f2)) {    /* Try */ 
  785.         errpkt((CHAR *)"Can't rename file"); /* Give error msg */
  786.         } else ack();
  787.         RESUME;            /* Wait for next server command */
  788.     }
  789.     } 
  790. #else /* no ZRENAME */
  791.     /* Give error message */
  792.     errpkt((CHAR *)"REMOTE RENAME not available"); 
  793.     RESUME;                /* Wait for next server command */
  794. #endif /* ZRENAME */
  795. #endif /* NOSERVER */
  796. }
  797.     break;
  798. case 33:
  799.     {                            /* REMOTE COPY */
  800. #ifndef NOSERVER
  801. #ifdef ZCOPY
  802.     char *str1, *str2, f1[256], f2[256];
  803.     int  len1, len2;
  804.     if (!ENABLED(en_cpy)) {
  805.     errpkt((CHAR *)"REMOTE COPY disabled");
  806.     RESUME;
  807.     } else {
  808.         len1 = xunchar(srvcmd[1]);    /* Separate the parameters */
  809.         len2 = xunchar(srvcmd[2+len1]);
  810.         strncpy(f1,(char *)(srvcmd+2),len1);
  811.         f1[len1] = NUL;
  812.         strncpy(f2,(char *)(srvcmd+3+len1),len2);
  813.         f2[len2] = NUL; 
  814.  
  815.     if (!ENABLED(en_cwd)) {        /* If CWD is disabled */
  816.         zstrip(f1,&str1);        /* and they included a pathname, */
  817.             zstrip(f2,&str2);
  818.         if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */
  819.         errpkt((CHAR *)"Access denied");
  820.         RESUME;            /* Remember, this is not a goto! */
  821.         }
  822.     }    
  823.     if (state == generic) {        /* It's OK to go ahead. */
  824.             if (zcopy(f1,f2)) {        /* Try */ 
  825.         errpkt((CHAR *)"Can't copy file"); /* give error message */
  826.         } else ack();
  827.             RESUME;            /* wait for next server command */
  828.     }
  829.     }
  830. #else /* no ZCOPY */
  831.     errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */
  832.     RESUME;                /* wait for next server command */
  833. #endif /* ZCOPY */
  834. #endif /* NOSERVER */
  835. }
  836.     break;
  837. case 34:
  838.     {                /* REMOTE SET */
  839. #ifndef NOSERVER
  840.     if (!ENABLED(en_set)) {
  841.     errpkt((CHAR *)"REMOTE SET disabled");
  842.     RESUME;
  843.     } else {
  844.     if (remset((char *)(srvcmd+1)))    /* Try to do what they ask */
  845.       ack();            /* If OK, then acknowledge */
  846.     else                /* Otherwise */
  847.       errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */
  848.     RESUME;                /* Return to server command wait */
  849.     }
  850. #endif /* NOSERVER */
  851. }
  852.     break;
  853. case 35:
  854.     {                /* REMOTE TYPE */
  855. #ifndef NOSERVER
  856.     char *n2;
  857.     if (!ENABLED(en_typ)) {
  858.     errpkt((CHAR *)"REMOTE TYPE disabled");
  859.     RESUME;
  860.     } else {
  861.     if (!ENABLED(en_cwd)) {        /* If CWD disabled */
  862.         zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
  863.         if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
  864.         errpkt((CHAR *)"Access denied");
  865.         RESUME;            /* Remember, this is not a goto! */
  866.         }
  867.     }    
  868.     if (state == generic) {        /* It's OK to go ahead. */
  869.         binary = XYFT_T;        /* Use text mode for this. */
  870.         if (            /* (RESUME didn't change state) */
  871. #ifdef COMMENT
  872.           syscmd(TYPCMD,(char *)(srvcmd+2))    /* Old way */
  873. #else
  874.           sndtype((char *)(srvcmd+2)) /* New way */
  875. #endif /* COMMENT */
  876.         )
  877.           BEGIN ssinit;            /* OK */
  878.         else {                /* not OK */
  879.         errpkt((CHAR *)"Can't type file"); /* give error message */
  880.         RESUME;            /* wait for next server command */
  881.         }
  882.     }
  883.     }
  884. #endif /* NOSERVER */
  885. }
  886.     break;
  887. case 36:
  888.     {                /* REMOTE SPACE */
  889. #ifndef NOSERVER
  890.     if (!ENABLED(en_spa)) {
  891.     errpkt((CHAR *)"REMOTE SPACE disabled");
  892.     RESUME;
  893.     } else {
  894.     x = srvcmd[1];            /* Get area to check */
  895.     x = ((x == NUL) || (x == SP)
  896. #ifdef OS2
  897.          || (x == '!') || (srvcmd[3] == ':')
  898. #endif /* OS2 */
  899.          );
  900.     if (!x && !ENABLED(en_cwd)) {    /* CWD disabled */
  901.         errpkt((CHAR *)"Access denied"); /* and non-default area given, */
  902.         RESUME;            /* refuse. */
  903.     } else {
  904. #ifdef OS2
  905. _PROTOTYP(int sndspace,(int));
  906.         if (sndspace(x ? toupper(srvcmd[2]) : 0))
  907.           BEGIN ssinit;        /* Try to send it */
  908.         else {            /* If not ok, */
  909.         errpkt((CHAR *)"Can't send space"); /* send error message */
  910.         RESUME;            /* and return to server command wait */
  911.         }
  912. #else
  913.         x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2)));
  914.         if (x) {                /* If we got the info */
  915.         BEGIN ssinit;            /* send it */
  916.         } else {                /* otherwise */
  917.         errpkt((CHAR *)"Can't check space"); /* send error message */
  918.         RESUME;            /* and await next server command */
  919.         }
  920. #endif /* OS2 */
  921.     }
  922.     }
  923. #endif /* NOSERVER */
  924. }
  925.     break;
  926. case 37:
  927.     {                /* REMOTE WHO */
  928. #ifndef NOSERVER
  929.     if (!ENABLED(en_who)) {
  930.     errpkt((CHAR *)"REMOTE WHO disabled");
  931.     RESUME;
  932.     } else {
  933. #ifdef OS2
  934. _PROTOTYP(int sndwho,(char *));
  935.         if (sndwho((char *)(srvcmd+2)))
  936.           BEGIN ssinit;        /* Try to send it */
  937.         else {            /* If not ok, */
  938.         errpkt((CHAR *)"Can't do who command"); /* send error msg */
  939.         RESUME;            /* and return to server command wait */
  940.         }
  941. #else
  942.     if (syscmd(WHOCMD,(char *)(srvcmd+2))) /* The now-familiar scenario. */
  943.       BEGIN ssinit;
  944.     else {
  945.         errpkt((CHAR *)"Can't do who command");
  946.         RESUME;
  947.     }
  948. #endif /* OS2 */
  949.     }
  950. #endif /* NOSERVER */
  951. }
  952.     break;
  953. case 38:
  954.     {                /* Variable query or set */
  955. #ifndef NOSERVER
  956. #ifndef NOSPL
  957. _PROTOTYP( int addmac, (char *, char *) );
  958. _PROTOTYP( int zzstring, (char *, char **, int *) );
  959.     char c;
  960.     c = *(srvcmd+2);            /* Q = Query, S = Set */
  961.     if (c == 'Q') {            /* Query */
  962.     if (!ENABLED(en_que)) { /* Security */
  963.         errpkt((CHAR *)"REMOTE QUERY disabled");
  964.         RESUME;
  965.     } else {            /* Query allowed */
  966.         int n; char *p, *q;
  967.         qbufp = querybuf;        /* Wipe out old stuff */
  968.         qbufn = 0;
  969.         querybuf[0] = NUL;
  970.         p = (char *) srvcmd + 3;    /* Pointer for making wrapper */
  971.         n = strlen((char *)srvcmd);    /* Position of end */
  972.         c = *(srvcmd+4);        /* Which type of variable */
  973.  
  974.         if (*(srvcmd+6) == CMDQ) {    /* Starts with command quote? */
  975.         p = (char *) srvcmd + 6; /* Take it literally */
  976.         if (*p == CMDQ) p++;
  977.         } else {            /* They played by the rules */
  978.         if (c == 'K') {        /* Kermit variable */
  979.             int k;
  980.             k = (int) strlen(p);
  981.             if (k > 0 && p[k-1] == ')') {
  982.             p = (char *)(srvcmd + 4);
  983.             *(srvcmd+4) = CMDQ;
  984.             *(srvcmd+5) = 'f'; /* Function, so make it \f...() */
  985.             } else {
  986.             *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
  987.             *(srvcmd+4) = 'v';  /* Variable, so make it \v(...) */
  988.             *(srvcmd+5) = '(';  /* around variable name */
  989.             *(srvcmd+n) = ')';
  990.             *(srvcmd+n+1) = NUL;
  991.             }
  992.         } else {
  993.             *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
  994.             *(srvcmd+4) = 'v'; /*  Variable, so make it \v(...) */
  995.             *(srvcmd+5) = '(';    /* around variable name */
  996.             *(srvcmd+n) = ')';
  997.             *(srvcmd+n+1) = NUL;
  998.             if (c == 'S') {    /* System variable */
  999.             *(srvcmd+4) = '$'; /*  so it's \$(...) */
  1000.             } else if (c == 'G') { /* Non-\ Global variable */
  1001.             *(srvcmd+4) = 'm'; /*  so wrap it in \m(...) */
  1002.             }
  1003.         }
  1004.         }                /* Now evaluate it */
  1005.         n = QBUFL;            /* Max length */
  1006.         q = querybuf;        /* Where to put it */
  1007.         if (zzstring(p,&q,&n) < 0) {
  1008.         errpkt((n > 0) ? (CHAR *)"Can't get value"
  1009.                        : (CHAR *)"Value too long"
  1010.                );
  1011.         RESUME;
  1012.         } else {
  1013.         if (encstr((CHAR *)querybuf) > -1) { /* Encode it */
  1014.             ack1(data);        /* If it fits, send it back in ACK */
  1015.             RESUME;
  1016.         } else if (sndhlp(querybuf)) { /* Long form response */
  1017.             BEGIN ssinit;
  1018.         } else {        /* sndhlp() fails */
  1019.             errpkt((CHAR *)"Can't send value");
  1020.             RESUME;
  1021.         }
  1022.         }
  1023.     }
  1024.     } else if (c == 'S') {        /* Set (assign) */
  1025.     if (!ENABLED(en_asg)) {        /* Security */
  1026.         errpkt((CHAR *)"REMOTE ASSIGN disabled");
  1027.         RESUME;
  1028.     } else {            /* OK */
  1029.         int n;
  1030.         n = xunchar(*(srvcmd+3));    /* Length of name */
  1031.         n = 3 + n + 1;        /* Position of length of value */
  1032.         *(srvcmd+n) = NUL;        /* Don't need it */
  1033.         if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0)
  1034.           errpkt((CHAR *)"REMOTE ASSIGN failed");
  1035.         else
  1036.           ack();
  1037.         RESUME;
  1038.     }
  1039.     } else {
  1040.     errpkt((CHAR *)"Badly formed server command");
  1041.     RESUME;
  1042.     }
  1043. #else
  1044.     errpkt((CHAR *)"Variable query/set not available");
  1045.     RESUME;
  1046. #endif /* NOSPL */
  1047. #endif /* NOSERVER */
  1048. }
  1049.     break;
  1050. case 39:
  1051.     {
  1052. #ifndef NOSERVER
  1053.     if (!ENABLED(en_fin)) {        /* Ctrl-C typed */
  1054.     errpkt((CHAR *)"QUIT disabled");
  1055.     RESUME;
  1056.     } else {
  1057.     success = 0; QUIT;
  1058.     }
  1059. #endif /* NOSERVER */
  1060. }
  1061.     break;
  1062. case 40:
  1063.     {                /* Anything else in this state... */
  1064. #ifndef NOSERVER
  1065.     errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */
  1066.     RESUME;                /* and return to server command wait */
  1067. #endif /* NOSERVER */
  1068. }
  1069.     break;
  1070. case 41:
  1071.     {                /* Short-Form reply */
  1072. #ifndef NOSERVER
  1073. #ifndef NOSPL
  1074.     if (query) {            /* If to query, */
  1075.     qbufp = querybuf;        /*  initialize query response buffer */
  1076.     qbufn = 0;
  1077.     querybuf[0] = NUL;
  1078.     }
  1079. #endif /* NOSPL */
  1080.     decode(rdatap,puttrm,0);        /* Text is in ACK Data field */
  1081.     if (rdatap)                /* If we had data */
  1082.       if (*rdatap)
  1083.      conoll("");            /* Then add a CRLF */
  1084.     if (bye_active && network) {    /* I sent a BYE command and got */
  1085.     msleep(500);            /* the ACK... */
  1086.     tthang();
  1087.     }
  1088.     success = 1;
  1089.     RESUME;
  1090. #endif /* NOSERVER */
  1091. }
  1092.     break;
  1093. case 42:
  1094.     {                /* File header */
  1095.     xflg = 0;                /* Not screen data */
  1096.     if (!rcvfil(filnam)) {        /* Figure out local filename */
  1097.     errpkt((CHAR *)rf_err);        /* Trouble */
  1098.     screen(SCR_EM,0,0L,rf_err);
  1099.     RESUME;
  1100.     } else {                /* Real file, OK to receive */
  1101.     if (filcnt == 1)        /* rcvfil set this to 1 for 1st file */
  1102.       crc16 = 0L;            /* Clear file CRC */
  1103. #ifndef NOFULLNAME
  1104. #ifdef ZFNQFP                /* Because of zfnqfp() */
  1105. #ifdef BIGBUFOK                /* Because it's another 1K buffer */
  1106. #define USEFULLNAME            /* Memory to burn - do it */
  1107. #endif /* BIGBUFOK */
  1108. #endif /* ZFNQFP */
  1109. #endif /* NOFULLNAME */
  1110.  
  1111. #ifdef USEFULLNAME            /* Name to send back in ACK */
  1112.     if (!isabsolute(filnam)) {
  1113.         CHAR tmpbuf[91];        /* Must fit in ACK Data field */
  1114.         struct zfnfp * fnp;
  1115.         fnp = zfnqfp(filnam,90,(char *)tmpbuf);
  1116.         encstr(fnp ? tmpbuf: (CHAR *)filnam); /* Send the full pathname */
  1117.     } else
  1118. #endif /* USEFULLNAME */
  1119.       encstr((CHAR *)filnam);    /* Encode the local filename */
  1120.  
  1121.     ack1(data);            /* Send it back in ACK */
  1122.     initattr(&iattr);        /* Clear file attribute structure */
  1123.     if (window(wslotn) < 0) {    /* Allocate negotiated window slots */
  1124.         errpkt((CHAR *)"Can't open window");
  1125.         RESUME;
  1126.     }
  1127.     BEGIN rattr;            /* Now expect Attribute packets */
  1128.     }
  1129. }
  1130.     break;
  1131. case 43:
  1132.     {                /* X-packet instead of file header */
  1133.     xflg = 1;                /* Screen data */
  1134.     ack();                /* Acknowledge the X-packet */
  1135.     initattr(&iattr);            /* Initialize attribute structure */
  1136.     if (window(wslotn) < 0) {        /* allocate negotiated window slots */
  1137.     errpkt((CHAR *)"Can't open window");
  1138.     RESUME;
  1139.     }
  1140. #ifndef NOSPL
  1141.     if (query) {            /* If this is the response to */
  1142.     qbufp = querybuf;        /* a query that we sent, initialize */
  1143.     qbufn = 0;            /* the response buffer */
  1144.     querybuf[0] = NUL;
  1145.     }
  1146. #endif /* NOSPL */
  1147.     what = W_REMO;            /* we're doing a REMOTE command */
  1148.     BEGIN rattr;            /* Expect Attribute packets */
  1149. }
  1150.     break;
  1151. case 44:
  1152.     {                /* Attribute packet */
  1153.     if (gattr(rdatap,&iattr) == 0) {    /* Read into attribute structure */
  1154. #ifdef CK_RESEND
  1155.     ack1((CHAR *)iattr.reply.val);    /* Reply with data */
  1156. #else
  1157.     ack();                /* If OK, acknowledge */
  1158. #endif /* CK_RESEND */
  1159.     } else {                /* Otherwise */
  1160.     ack1((CHAR *)iattr.reply.val);    /* refuse to accept the file */
  1161.     screen(SCR_ST,ST_REFU,0L,getreason(iattr.reply.val)); /* give reason */
  1162.     }
  1163. }
  1164.     break;
  1165. case 45:
  1166.     {                /* First data packet */
  1167.     if (discard) {            /* if we're discarding the file */
  1168.     ack1((CHAR *)"X");        /* just ack the data like this. */
  1169.     BEGIN rdata;            /* and wait for more data packets. */
  1170.     } else {                /* Not discarding. */
  1171.     rf_err = "Can't open file";
  1172.     if (xflg) {            /* If screen data */
  1173.         if (remfile) {        /* redirected to file */
  1174.         if (rempipe)        /* or pipe */
  1175.           x = zxcmd(ZOFILE,remdest); /* Pipe: start command */
  1176.         else
  1177.           x = opena(remdest,&iattr); /* File: open with attributes */
  1178.         } else {            /* otherwise */
  1179.         x = opent(&iattr);    /* "open" the screen */
  1180.         }
  1181.     } else {            /* otherwise */
  1182.         x = opena(filnam,&iattr);    /* open the file, with attributes */
  1183.     }
  1184.     if (x) {            /* If file was opened ok */
  1185.         if (decode(rdatap, 
  1186. #ifndef NOSPL
  1187.                query ? puttrm : 
  1188. #endif /* NOSPL */
  1189.                putfil, 1) < 0) {
  1190.  
  1191.         errpkt((CHAR *)"Error writing data");
  1192.         RESUME;
  1193.         }
  1194.         ack();            /* acknowledge it */
  1195.         BEGIN rdata;        /* and switch to receive-data state */
  1196.     } else {            /* otherwise */
  1197.         errpkt((CHAR *) rf_err);    /* send error message */
  1198.         RESUME;            /* and quit. */
  1199.     }
  1200.     }
  1201. }
  1202.     break;
  1203. case 46:
  1204.     {                /* EOT, no more files */
  1205.     ack();                /* Acknowledge */
  1206.     tsecs = gtimer();            /* Get timing for statistics */
  1207.     reot();                /* Do EOT things */
  1208. #ifdef CK_TMPDIR
  1209. /* If we were cd'd temporarily to another device or directory ... */
  1210.     if (f_tmpdir) {
  1211.     int x;
  1212.     x = zchdir((char *) savdir);    /* ... restore previous directory */
  1213.     f_tmpdir = 0;            /* and remember we did it. */
  1214.     debug(F111,"ckcpro.w B tmpdir restoring",savdir,x);
  1215.     }
  1216. #endif /* CK_TMPDIR */
  1217.     RESUME;                /* and quit */
  1218. }
  1219.     break;
  1220. case 47:
  1221.     {                /* Data packet */
  1222.     if (cxseen || discard)        /* If file interrupt */
  1223.       ack1((CHAR *)"X");        /* put "X" in ACK */
  1224.     else if (czseen)            /* If file-group interrupt */
  1225.       ack1((CHAR *)"Z");        /* put "Z" in ACK */
  1226.     else if (decode(rdatap, 
  1227. #ifndef NOSPL
  1228.                query ? puttrm : 
  1229. #endif /* NOSPL */
  1230.                putfil, 1) < 0) {
  1231.     errpkt((CHAR *)"Error writing data"); /* If failure, */
  1232.     clsof(!keep);            /*   Close & keep/discard the file */
  1233.     RESUME;                /* Send ACK only after data */
  1234.     } else ack();            /* written to file OK. */
  1235. }
  1236.     break;
  1237. case 48:
  1238.     {                /* EOF immediately after A-Packet. */
  1239.     rf_err = "Can't create file";
  1240.     if (discard) {            /* Discarding a real file... */
  1241.     x = 1;
  1242.     } else if (xflg) {            /* If screen data */
  1243.     if (remfile) {            /* redirected to file */
  1244.         if (rempipe)        /* or pipe */
  1245.           x = zxcmd(ZOFILE,remdest); /* Pipe: start command */
  1246.         else
  1247.           x = opena(remdest,&iattr); /* File: open with attributes */
  1248.     } else {            /* otherwise */
  1249.         x = opent(&iattr);        /* "open" the screen */
  1250.     }
  1251.     } else {                /* otherwise */
  1252.     x = opena(filnam,&iattr);    /* open the file, with attributes */
  1253.     }
  1254.     if (!x || reof(filnam, &iattr) < 0) { /* Now close & dispose of the file */
  1255.     errpkt((CHAR *) rf_err);    /* If problem, send error msg */
  1256.     RESUME;                /* and quit */
  1257.     } else {                /* otherwise */
  1258.     ack();                /* acknowledge the EOF packet */
  1259.     BEGIN rfile;            /* and await another file */
  1260.     }
  1261. }
  1262.     break;
  1263. case 49:
  1264.     {                /* End Of File (EOF) Packet */
  1265. /*  wslots = 1;    */            /* Window size back to 1 */
  1266. #ifndef COHERENT
  1267. /*
  1268.   Coherent compiler blows up on this switch() statement.
  1269. */
  1270.     x = reof(filnam, &iattr);        /* Handle the EOF packet */
  1271.     switch (x) {            /* reof() sets the success flag */
  1272.       case -3:                /* If problem, send error msg */
  1273.     errpkt((CHAR *)"Can't print file"); /* Fatal */
  1274.         RESUME;
  1275.     break;
  1276.       case -2:
  1277.     errpkt((CHAR *)"Can't mail file"); /* Fatal */
  1278.         RESUME;
  1279.     break;
  1280.       case 2:
  1281.       case 3:
  1282.     screen(SCR_EM,0,0L,"Can't delete temp file"); /* Not fatal */
  1283.         RESUME;
  1284.     break;
  1285.       default:
  1286.     if (x < 0) {            /* Fatal */
  1287.         errpkt((CHAR *)"Can't close file");
  1288.         RESUME;
  1289.     } else {            /* Success */
  1290. #ifndef NOSPL
  1291.         if (query)            /* Query reponses generally */
  1292.           conoll("");        /* don't have line terminators */
  1293. #endif /* NOSPL */
  1294.         ack();            /* Acknowledge the EOF packet */
  1295.         BEGIN rfile;        /* and await another file */
  1296.     }
  1297.     }
  1298. #else
  1299.     if (reof(filnam, &iattr) < 0) {    /* Close and dispose of the file */
  1300.     errpkt((CHAR *)"Error at end of file");
  1301.     RESUME;
  1302.     } else {                /* reof() sets success flag */
  1303.     ack();
  1304.     BEGIN rfile;
  1305.     }
  1306. #endif /* COHERENT */
  1307. }
  1308.     break;
  1309. case 50:
  1310.     {                /* ACK for Send-Init */
  1311.     spar(rdatap);            /* set parameters from it */
  1312.     bctu = bctr;            /* switch to agreed-upon block check */
  1313.     bctl = (bctu == 4) ? 2 : bctu;    /* Set block-check length */
  1314. #ifdef CK_RESEND
  1315.     if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */
  1316.     errpkt((CHAR *) "RESEND capabilities not negotiated");
  1317.     ermsg("RESEND capabilities not negotiated");
  1318.     RESUME;
  1319.     } else {
  1320. #endif /* CK_RESEND */
  1321.     what = W_SEND;            /* Remember we're sending */
  1322.     x = sfile(xflg);        /* Send X or F header packet */
  1323.     if (x) {            /* If the packet was sent OK */
  1324.         if (!xflg && filcnt == 1)    /* and it's a real file */
  1325.           crc16 = 0L;        /* Clear the file CRC */
  1326.         resetc();            /* reset per-transaction counters */
  1327.         rtimer();            /* reset timers */
  1328.         BEGIN ssfile;        /* and switch to receive-file state */
  1329.     } else {            /* otherwise send error msg & quit */
  1330.         s = xflg ? "Can't execute command" : "Can't open file";
  1331.         errpkt((CHAR *)s);
  1332.         RESUME;
  1333.     }
  1334. #ifdef CK_RESEND
  1335.     }
  1336. #endif /* CK_RESEND */
  1337. }
  1338.     break;
  1339. case 51:
  1340.     {                /* R packet was retransmitted. */
  1341.     xsinit();                /* Resend packet 0 */
  1342. }
  1343.     break;
  1344. case 52:
  1345.     {                /* Same deal if G packet comes again */
  1346.     xsinit();
  1347. }
  1348.     break;
  1349. case 53:
  1350.     {                /* Same deal if C packet comes again */
  1351.     xsinit();
  1352. }
  1353.     break;
  1354. case 54:
  1355.     {                /* ACK for F packet */
  1356.     srvptr = srvcmd;            /* Point to string buffer */
  1357.     decode(rdatap,putsrv,0);        /* Decode data field, if any */
  1358.     putsrv(NUL);            /* Terminate with null */
  1359.     ffc = 0L;                /* Reset file byte counter */
  1360.     if (*srvcmd) {            /* If remote name was recorded */
  1361.         if (sendmode != SM_RESEND) {
  1362.         if (fdispla == XYFD_C) 
  1363.           screen(SCR_AN,0,0L,(char *)srvcmd);
  1364.         tlog(F110," remote name:",(char *) srvcmd,0L);
  1365.         }
  1366.     }
  1367.     if (atcapu) {            /* If attributes are to be used */
  1368.     if (sattr(xflg | stdinf) < 0) {    /* set and send them */
  1369.         errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */
  1370.         RESUME;                 /* and quit */
  1371.     } else BEGIN ssattr;        /* if ok, switch to attribute state */
  1372.     } else {
  1373.     if (window(wslotn) < 0) {
  1374.         errpkt((CHAR *)"Can't open window");
  1375.         RESUME;
  1376.     }
  1377.     if ((x = sdata()) == -2) {    /* No attributes, send data */
  1378.         return(success = 0);    /* Failed */
  1379.     } else if (x == -1) {        /* EOF (eh?) */
  1380.         clsif();            /* If not ok, close input file, */
  1381.         window(1);            /* put window size back to 1, */
  1382.         seof((CHAR *)"");        /* send EOF packet, */
  1383.         BEGIN sseof;        /* and switch to EOF state. */
  1384.     } else BEGIN ssdata;        /* All ok, switch to send-data state */
  1385.     }
  1386. }
  1387.     break;
  1388. case 55:
  1389.     {                /* Got ACK to A packet */
  1390.     ffc = 0L;                /* Reset file byte counter */
  1391.     if (rsattr(rdatap) < 0) {        /* Was the file refused? */
  1392.     discard = 1;            /* Set the discard flag */
  1393.     clsif();            /* Close the file */
  1394.     sxeof((CHAR *)"D");        /* send EOF with "discard" code */
  1395.     BEGIN sseof;            /* switch to send-EOF state */
  1396.     } else {
  1397.     if (window(wslotn) < 0) {    /* Allocate negotiated window slots */
  1398.         errpkt((CHAR *)"Can't open window");
  1399.         RESUME;
  1400.     }
  1401.     if ((x = sdata()) == -2) {    /* File accepted, send data */
  1402.         return(success = 0);    /* Failed */
  1403.     } else if (x == -1) {        /* EOF */
  1404.         clsif();            /* If not ok, close input file, */
  1405.         window(1);            /* put window size back to 1, */
  1406.         seof((CHAR *)"");        /* send EOF packet, */
  1407.         BEGIN sseof;        /* and switch to EOF state. */
  1408.     } else BEGIN ssdata;        /* All ok, switch to send-data state */
  1409.     }
  1410. }
  1411.     break;
  1412. case 56:
  1413.     {                /* Got ACK to Data packet */
  1414.     canned(rdatap);            /* Check if file transfer cancelled */
  1415.     if ((x = sdata()) == -2) {        /* Try to send next data */
  1416.     return(success = 0);        /* Failed */
  1417.     } else if (x == -1) {        /* EOF - finished sending data */
  1418.     clsif();            /* Close file */
  1419.     window(1);            /* Set window size back to 1... */
  1420.     if (cxseen || czseen)        /* If interrupted */
  1421.       seof((CHAR *)"D");        /* send special EOF packet */
  1422.     else                /* otherwise */
  1423.       seof((CHAR *)"");        /* regular EOF packet */
  1424.     BEGIN sseof;            /* and enter send-eof state */
  1425.     }
  1426. }
  1427.     break;
  1428. case 57:
  1429.     {                /* Got ACK to EOF */
  1430.     success = (cxseen == 0 && czseen == 0); /* Transfer status... */
  1431.     if (success && rejection > 0)        /* If rejected, succeed if */
  1432.       if (rejection != '#' &&            /* reason was date */
  1433.       rejection != 1 && rejection != '?') /* or name; */
  1434.     success = 0;                /* fail otherwise. */
  1435.     cxseen = 0;                /* This goes back to zero. */
  1436.     if (success && moving) {        /* If MOVE'ing */
  1437.     tlog(F110," deleting",filnam,0); /* delete the file */
  1438.     zdelet(filnam);
  1439.     }
  1440.     if (gnfile() > 0) {            /* Any more files to send? */
  1441.     if (sfile(xflg))        /* Yes, try to send next file header */
  1442.       BEGIN ssfile;            /* if ok, enter send-file state */
  1443.     else {                /* otherwise */
  1444.         errpkt((CHAR *)"Can't open file");    /* send error message */
  1445.         RESUME;            /* and quit */
  1446.     }
  1447.     } else {                /* No next file */
  1448.     tsecs = gtimer();        /* get statistics timers */
  1449.     seot();                /* send EOT packet */
  1450.     BEGIN sseot;            /* enter send-eot state */
  1451.     }
  1452. }
  1453.     break;
  1454. case 58:
  1455.     {                /* Got ACK to EOT */
  1456.     debug(F101,"sseot justone","",justone);
  1457.     RESUME;                /* All done, just quit */
  1458. }
  1459.     break;
  1460. case 59:
  1461.     {                    /* Got Error packet, in any state */
  1462.     char *s = "";
  1463.     if (pktmsg)                /* Or we sent one. */
  1464.       if (*pktmsg)            /* If so, this was the message. */
  1465.     s = (char *)pktmsg;
  1466.     if (!*s)                /* We received an Error packet */
  1467.       s = (char *)rdatap;        /* with this message. */
  1468.     if (!*s)                /* Hopefully we'll never see this. */
  1469.       s = "Unknown error";
  1470.     ermsg(s);                /* Issue the message. */
  1471.     success = 0;            /* For IF SUCCESS/FAIL. */
  1472.     debug(F101,"ckcpro.w justone at E pkt","",justone);
  1473.     x = quiet; quiet = 1;        /* Close files silently, */
  1474.     clsif(); clsof(1);             /* discarding any output file. */
  1475.     tsecs = gtimer();            /* Get timers */
  1476.     quiet = x;                /* restore quiet state */
  1477. /*
  1478.   If we are executing commands from a command file or macro, let the command
  1479.   file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR.
  1480. */
  1481.     if (
  1482. #ifndef NOSPL
  1483.     cmdlvl == 0
  1484. #else
  1485.     tlevel < 0
  1486. #endif /* NOSPL */
  1487.     )
  1488.       if (backgrd && !server)
  1489.     fatal("Protocol error");
  1490.     xitsta |= what;            /* Save this for doexit(). */
  1491. #ifdef CK_TMPDIR
  1492. /* If we were cd'd temporarily to another device or directory ... */
  1493.     if (f_tmpdir) {
  1494.     int x;
  1495.     x = zchdir((char *) savdir);    /* ... restore previous directory */
  1496.     f_tmpdir = 0;            /* and remember we did it. */
  1497.     debug(F111,"ckcpro.w E tmpdir restoring",savdir,x);
  1498.     }
  1499. #endif /* CK_TMPDIR */
  1500.     RESUME;
  1501. }
  1502.     break;
  1503. case 60:
  1504.     { success = 0; QUIT; }
  1505.     break;
  1506. case 61:
  1507.     {                    /* Anything not accounted for above */
  1508.     errpkt((CHAR *)"Unexpected packet type"); /* Give error message */
  1509.     xitsta |= what;            /* Save this for doexit(). */
  1510.     RESUME;                /* and quit */
  1511. }
  1512.     break;
  1513.  
  1514.         }
  1515.     }
  1516. }
  1517.  
  1518. char tbl[] = {
  1519. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1520. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1521. 61, 61, 61, 61, 61, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1522. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1523. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1524. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1525. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1526. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1527. 61, 61, 61, 61, 61, 13, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1528. 61, 61, 61, 61, 61, 61, 61, 61, 61, 12, 61, 61, 61, 61, 61, 61, 
  1529. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1530. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1531. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1532. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1533. 61, 61, 46, 61, 61, 59, 42, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1534. 61, 61, 61, 61, 61, 61, 61, 61, 43, 61, 61, 61, 61, 61, 61, 61, 
  1535. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1536. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1537. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1538. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1539. 61, 44, 61, 61, 45, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1540. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 48, 61, 61, 61, 61, 61, 
  1541. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1542. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1543. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1544. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1545. 61, 61, 61, 61, 47, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1546. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 49, 61, 61, 61, 61, 61, 
  1547. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1548. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1549. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1550. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1551. 61, 61, 61, 53, 61, 59, 61, 52, 61, 61, 61, 61, 61, 61, 61, 61, 
  1552. 61, 61, 51, 61, 61, 61, 61, 61, 61, 50, 61, 61, 61, 61, 61, 61, 
  1553. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1554. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1555. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1556. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1557. 61, 61, 61, 61, 61, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1558. 61, 61, 61, 61, 61, 61, 61, 61, 61, 54, 61, 61, 61, 61, 61, 61, 
  1559. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1560. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1561. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1562. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1563. 61, 61, 61, 61, 61, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1564. 61, 61, 61, 61, 61, 61, 61, 61, 61, 55, 61, 61, 61, 61, 61, 61, 
  1565. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1566. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1567. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1568. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1569. 61, 61, 61, 61, 61, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1570. 61, 61, 61, 61, 61, 61, 61, 61, 61, 56, 61, 61, 61, 61, 61, 61, 
  1571. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1572. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1573. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1574. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1575. 61, 61, 61, 61, 61, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1576. 61, 61, 61, 61, 61, 61, 61, 61, 61, 57, 61, 61, 61, 61, 61, 61, 
  1577. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1578. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1579. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1580. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1581. 61, 61, 61, 61, 61, 59, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1582. 61, 61, 61, 61, 61, 61, 61, 61, 61, 58, 61, 61, 61, 61, 61, 61, 
  1583. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1584. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1585. -1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  1586. 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  1587. 23, 23, 23, 20, 23, 23, 23, 19, 17, 15, 18, 23, 23, 23, 22, 23, 
  1588. 23, 23, 16, 11, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 
  1589. 23, 10, 23,  6, 23, 23, 23,  8,  4, 23,  5,  7, 23, 23, 23, 23, 
  1590. 23, 21,  3,  1, 23, 23,  2, 23,  9, 23, 23, 23, 23, 23, 23, 23, 
  1591. -1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
  1592. 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 
  1593. 40, 26, 40, 25, 27, 28, 29, 40, 31, 24, 40, 33, 30, 40, 40, 40, 
  1594. 40, 40, 32, 34, 35, 36, 38, 37, 40, 40, 40, 40, 40, 40, 40, 40, 
  1595. 40, 10, 40,  6, 40, 40, 40,  8,  4, 40,  5,  7, 40, 40, 40, 40, 
  1596. 40, 39,  3,  1, 40, 40,  2, 40,  9, 40, 40, 40, 40, 40, 40, 40, 
  1597. -1, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1598. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1599. 61, 61, 61, 61, 61, 59, 61, 61, 61, 15, 61, 61, 61, 61, 61, 61, 
  1600. 61, 61, 61, 11, 61, 61, 61, 61, 61, 14, 61, 61, 61, 61, 61, 61, 
  1601. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1602. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61, 
  1603.  0, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1604. 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1605. 61, 61, 61, 61, 61, 59, 42, 61, 61, 61, 61, 61, 61, 61, 61, 61, 
  1606. 61, 61, 61, 11, 61, 61, 61, 61, 43, 41, 61, 61, 61, 61, 61, 61, 
  1607. 61, 10, 61,  6, 61, 61, 61,  8,  4, 61,  5,  7, 61, 61, 61, 61, 
  1608. 61, 60,  3,  1, 61, 61,  2, 61,  9, 61, 61, 61, 61, 61, 61, 61 };
  1609.  
  1610.  
  1611. /*  P R O T O  --  Protocol entry function  */
  1612.  
  1613. VOID
  1614. proto() {
  1615.     extern int b_save, f_save;
  1616. #ifdef OS2
  1617.     extern int cursorena[], cursor_save;
  1618.     extern BYTE vmode;
  1619. #endif /* OS2 */
  1620. /*
  1621.   This is simply a wrapper for the real protocol function just below,
  1622.   that saves any items that might be changed automatically by protocol
  1623.   negotiations, but which should not be sticky, and then restores them
  1624.   upon exit from protocol mode.
  1625. */
  1626. #ifdef OS2
  1627.     cursor_save = cursorena[vmode] ;
  1628.     cursorena[vmode] = 0 ;
  1629. #endif /* OS2 */
  1630.     b_save = binary;            /* SET FILE TYPE */
  1631.     f_save = fncnv;            /* SET FILE NAMES */
  1632.     xxproto();                /* Call the real protocol function */
  1633.     fncnv  = f_save;
  1634.     binary = b_save;
  1635. #ifdef OS2
  1636.     cursorena[vmode] = cursor_save ;
  1637. #endif /* OS2 */
  1638. }
  1639.  
  1640. static VOID
  1641. xxproto() {
  1642.  
  1643.     int x;
  1644.     long lx;
  1645. #ifdef CK_XYZ
  1646. #ifdef XYZ_INTERNAL
  1647. _PROTOTYP( int pxyz, (int) );
  1648. #endif /* XYZ_INTERNAL */
  1649. #endif /* CK_XYZ */
  1650.  
  1651.     debug(F101,"xxproto entry justone","",justone);
  1652.  
  1653. /* Set up the communication line for file transfer. */
  1654.  
  1655.     if (local && (speed < 0L) && (network == 0)) {
  1656.     screen(SCR_EM,0,0L,"Sorry, you must 'set speed' first");
  1657.     return;
  1658.     }
  1659.     x = -1;
  1660.     if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) {
  1661.     debug(F111,"failed: proto ttopen local",ttname,local);
  1662.     screen(SCR_EM,0,0L,"Can't open line");
  1663.     success = 0;
  1664.     return;
  1665.     }
  1666.     if (x > -1) local = x;
  1667.     debug(F111,"proto ttopen local",ttname,local);
  1668.  
  1669.     lx = (local && !network) ? speed : -1;
  1670. #ifdef NETCONN
  1671. #ifdef CK_SPEED
  1672. /*
  1673.   If we are a TELNET client, force quoting of IAC.
  1674.   Note hardwired "1" rather than NP_TELNET symbol, so we don't have
  1675.   to schlurp in ckcnet.h.
  1676. */
  1677.     if (network && ttnproto == 1) {
  1678.     ctlp[255] = ctlp[CR] = 1;
  1679.     if (parity == 'e' || parity == 'm') ctlp[127] = 1;
  1680.     }
  1681. #endif /* CK_SPEED */
  1682. #endif /* NETCONN */
  1683.     if (ttpkt(lx,flow,parity) < 0) {    /* Put line in packet mode, */
  1684.     screen(SCR_EM,0,0L,"Can't condition line");
  1685.     success = 0;
  1686.     return;
  1687.     }
  1688.     /* Send remote side "receive" startup string, if any */
  1689.     if (local && sstate == 's') {
  1690.     char *s;
  1691.     s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init;
  1692.     if (s) if (*s) {
  1693.         char tmpbuf[356];
  1694.         int stuff = -1, stuff2 = -1, len = 0;
  1695.         extern int tnlm;
  1696.  
  1697.         sprintf(tmpbuf, s, fspec);    /* We need this for XMODEM... */
  1698.  
  1699.         strcat(tmpbuf, "\015");
  1700.         if (tnlm)            /* TERMINAL NEWLINE ON */
  1701.           stuff = LF;        /* Stuff LF */
  1702. #ifdef NETCONN
  1703. #ifdef TCPSOCKET
  1704.         /* TELNET NEWLINE MODE */
  1705.         if (network) {
  1706.         if (ttnproto == NP_TELNET) {
  1707.             switch (me_binary ? tn_b_nlm : tn_nlm) {
  1708.               case TNL_CR:
  1709.             break;
  1710.               case TNL_CRNUL:
  1711.             break;
  1712.               case TNL_CRLF:
  1713.             stuff2 = stuff;
  1714.             stuff = LF;
  1715.             break;
  1716.             }
  1717.         }
  1718. #ifdef RLOGCODE
  1719.         else if (ttnproto == NP_RLOGIN) {
  1720.             switch (tn_b_nlm) { /* Always BINARY */
  1721.               case TNL_CR:
  1722.             break;
  1723.               case TNL_CRNUL:
  1724.             stuff2 = stuff;
  1725.             stuff  = NUL;
  1726.             break;
  1727.               case TNL_CRLF:
  1728.             stuff2 = stuff;
  1729.             stuff = LF;
  1730.             break;
  1731.             }
  1732.         }
  1733. #endif /* RLOGCODE */
  1734.         }
  1735. #endif /* TCPSOCKET */
  1736. #endif /* NETCONN */
  1737.         len = strlen(tmpbuf);
  1738.         if (stuff >= 0) {
  1739.         tmpbuf[len++] = stuff;
  1740.         if (stuff2 >= 0)
  1741.           tmpbuf[len++] = stuff2;
  1742.         tmpbuf[len] = NUL;
  1743.         }
  1744.         ttol((CHAR *)tmpbuf,len);
  1745.     }
  1746.     }
  1747. #ifdef CK_XYZ
  1748.     if (protocol != PROTO_K) {        /* Non-Kermit protocol selected */
  1749.     char tmpbuf[356];
  1750.     char * s = "";
  1751. #ifdef XYZ_INTERNAL            /* Internal */
  1752.     success = !pxyz(sstate); 
  1753. #else
  1754. #ifdef CK_REDIR                /* External */
  1755.     switch (sstate) {
  1756.       case 's':            /* 'Tis better to SEND... */
  1757.         s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd;
  1758.         break;
  1759.       case 'v':            /* ... than RECEIVE */
  1760.         s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd;
  1761.         break;
  1762.     }
  1763.     if (!s) s = "";
  1764.     if (*s) {
  1765.         sprintf(tmpbuf,s,(sstate == 's') ? fspec : cmarg2);
  1766.         ttruncmd(tmpbuf);
  1767.     } else {
  1768.         printf("?Sorry, no external protocol defined for %s\r\n",
  1769.            ptab[protocol].p_name
  1770.            );
  1771.     }
  1772. #else
  1773.     printf(
  1774. "Sorry, only Kermit protocol is supported in this version of Kermit\n"
  1775.            );
  1776. #endif /* CK_REDIR */
  1777. #endif /* XYZ_INTERNAL */
  1778.     return;
  1779.     }
  1780. #endif /* CK_XYZ */
  1781.  
  1782. #ifdef NTSIGX
  1783.     conraw();
  1784.     connoi();
  1785. #else
  1786.     if (!local)
  1787.       connoi();                /* No console interrupts if remote */
  1788. #endif /* NTSIG */
  1789.  
  1790.     if (sstate == 'x') {        /* If entering server mode, */
  1791.     server = 1;            /* set flag, */
  1792.     debug(F101,"server backgrd","",backgrd);
  1793.     debug(F101,"server quiet","",quiet);
  1794.     if (!quiet && !backgrd) {
  1795.             debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0);
  1796.         if (!local)    {        /* and issue appropriate message. */
  1797.             conoll(srvtxt);
  1798.         conoll("KERMIT READY TO SERVE...");
  1799.         } else {
  1800.             conol("Entering server mode on ");
  1801.         conoll(ttname);
  1802.         conoll("Type Ctrl-C to quit.");
  1803.         if (srvdis) intmsg(-1L);
  1804.         }
  1805.     }
  1806. #ifdef TCPSOCKET
  1807. #ifndef NOLISTEN
  1808. #ifndef NOSPL
  1809.     if (network && tcpsrfd > 0) {
  1810.         dooutput("KERMIT READY TO SERVE...\015\012");
  1811.     }
  1812. #endif /* NOSPL */
  1813. #endif /* NOLISTEN */
  1814. #endif /* TCPSOCKET */
  1815.     } else server = 0;
  1816. #ifdef VMS
  1817.     if (!quiet && !backgrd)    /* So message doesn't overwrite prompt */
  1818.       conoll("");
  1819.     if (local) conres();       /* So Ctrl-C will work */
  1820. #endif /* VMS */
  1821. /*
  1822.   If in remote mode, not shushed, not in background, and at top command level,
  1823.   issue a helpful message telling what to do...
  1824. */
  1825.     if (!local && !quiet && !backgrd) {
  1826.     if (sstate == 'v') {
  1827.         conoll("Return to your local Kermit and give a SEND command.");
  1828.         conoll("");
  1829.         conoll("KERMIT READY TO RECEIVE...");
  1830.     } else if (sstate == 's') {
  1831.         conoll("Return to your local Kermit and give a RECEIVE command.");
  1832.         conoll("");
  1833.         conoll("KERMIT READY TO SEND...");
  1834.     } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' ||
  1835.             sstate == 'j' || sstate == 'c' ) {
  1836.         conoll("Return to your local Kermit and give a SERVER command.");
  1837.         conoll("");
  1838.         conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ?
  1839.            "KERMIT READY TO GET..." :
  1840.            "KERMIT READY TO SEND SERVER COMMAND...");
  1841.     }
  1842.     }
  1843. #ifdef COMMENT
  1844.     if (!local) sleep(1);
  1845. #endif /* COMMENT */
  1846. /*
  1847.   The 'wart()' function is generated by the wart program.  It gets a
  1848.   character from the input() routine and then based on that character and
  1849.   the current state, selects the appropriate action, according to the state
  1850.   table above, which is transformed by the wart program into a big case
  1851.   statement.  The function is active for one transaction.
  1852. */
  1853.     rtimer();                /* Reset elapsed-time timer */
  1854.     resetc();                /* & other per-transaction counters. */
  1855.  
  1856.     debug(F101,"proto calling wart, justone","",justone);
  1857.  
  1858.     wart();                /* Enter the state table switcher. */
  1859.     
  1860.     if (server) {            /* Back from packet protocol. */
  1861.         if (!quiet && !backgrd) {    /* Give appropriate message */
  1862.         conoll("");
  1863.         conoll("C-Kermit server done");
  1864.         }
  1865.     }
  1866. /*
  1867.   Note: the following is necessary in case we have just done a remote-mode
  1868.   file transfer, in which case the controlling terminal modes have been
  1869.   changed by ttpkt().  In particular, special characters like Ctrl-C and
  1870.   Ctrl-\ might have been turned off (see ttpkt).  So this call to ttres() is
  1871.   essential.
  1872. */
  1873. #ifdef OS2
  1874.     ttres();                /* Reset the communication device */
  1875. #else
  1876.     if (!local) {
  1877.     msleep(500);
  1878.     ttres();            /* Reset the communication device */
  1879.     }
  1880. #endif /* OS2 */
  1881.     screen(SCR_TC,0,0L,"");        /* Transaction complete */
  1882.     server = 0;                /* Not a server any more */
  1883. }
  1884.  
  1885. static int
  1886. sgetinit(reget) int reget; {
  1887.     if (!ENABLED(en_get)) {        /* Only if not disabled!  */
  1888.     errpkt((CHAR *)"GET disabled");
  1889.     return(-1);
  1890.     } else {                /* OK to go ahead. */
  1891. #ifdef WHATAMI
  1892.     debug(F101,"sgetinit whatru","",whatru);
  1893.     if (whatru & WM_FLAG) {        /* Did we get WHATAMI info? */
  1894.         debug(F101,"sgetinit binary (1)","",binary);
  1895. #ifdef VMS
  1896.         if (binary != XYFT_I && binary != XYFT_L)
  1897. #else
  1898. #ifdef OS2
  1899.         if (binary != XYFT_L)
  1900. #endif /* OS2 */
  1901. #endif /* VMS */
  1902.         binary = (whatru & WM_FMODE) ?  /* Yes, set transfer mode */
  1903.           XYFT_B : XYFT_T;            /* automatically */
  1904.         debug(F101,"sgetinit binary (2)","",binary);
  1905.         fncnv = (whatru & WM_FNAME) ? 1 : 0; /* And name conversion */
  1906.     }
  1907. #endif /* WHATAMI */
  1908.     srvptr = srvcmd;        /* Point to server command buffer */
  1909.     decode(rdatap,putsrv,0);    /* Decode the GET command into it */
  1910.     /* Accept multiple filespecs */
  1911.         cmarg2 = "";            /* Don't use cmarg2 */
  1912.     cmarg = "";            /* Don't use cmarg */
  1913. #ifndef NOMSEND                /* New way. */
  1914.     nfils = fnparse((char *)srvcmd); /* Use cmlist instead */
  1915. #else
  1916.     nfils = 0 - zxpand((char *)srvcmd);
  1917. #endif /* NOMSEND */
  1918.     nakstate = 0;            /* Now I'm the sender! */
  1919.     if (reget) sendmode = SM_RESEND;
  1920.     if (sinit() > 0) {        /* Send Send-Init */
  1921.         timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
  1922.         return(0);            /* If successful, switch state */
  1923.     } else return(-1);        /* Else back to server command wait */
  1924.     }
  1925. }
  1926.