home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckcpro.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  112KB  |  3,815 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 2.14, 10 Nov 1999";
  8.  
  9. char *protv =                                                     /* -*-C-*- */
  10. "C-Kermit Protocol Module 8.0.160, 12 Aug 2007";
  11.  
  12. int kactive = 0;            /* Kermit protocol is active */
  13.  
  14. #define PKTZEROHACK
  15.  
  16. /* C K C P R O  -- C-Kermit Protocol Module, in Wart preprocessor notation. */
  17. /*
  18.   Author: Frank da Cruz <fdc@columbia.edu>,
  19.   Columbia University Academic Information Systems, New York City.
  20.  
  21.   Copyright (C) 1985, 2007,
  22.     Trustees of Columbia University in the City of New York.
  23.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  24.     copyright text in the ckcmai.c module for disclaimer and permissions.
  25. */
  26. #ifndef NOXFER
  27. #include "ckcsym.h"
  28. #include "ckcdeb.h"
  29. #include "ckcasc.h"
  30. #include "ckcker.h"
  31. #ifdef OS2
  32. #ifndef NT
  33. #define INCL_NOPM
  34. #define INCL_VIO            /* Needed for ckocon.h */
  35. #include <os2.h>
  36. #undef COMMENT
  37. #endif /* NT */
  38. #include "ckocon.h"
  39. #endif /* OS2 */
  40.  
  41. /*
  42.  Note -- This file may also be preprocessed by the UNIX Lex program, but
  43.  you must indent the above #include statements before using Lex, and then
  44.  restore them to the left margin in the resulting C program before compilation.
  45.  Also, the invocation of the "wart()" function below must be replaced by an
  46.  invocation  of the "yylex()" function.  It might also be necessary to remove
  47.  comments in the (%)(%)...(%)(%) section.
  48. */
  49.  
  50. /* State definitions for Wart (or Lex) */
  51. #define ipkt 1
  52. #define rfile 2
  53. #define rattr 3
  54. #define rdpkt 4
  55. #define ssinit 5
  56. #define ssfile 6
  57. #define ssattr 7
  58. #define ssdata 8
  59. #define sseof 9
  60. #define sseot 10
  61. #define serve 11
  62. #define generic 12
  63. #define get 13
  64. #define rgen 14
  65. #define ssopkt 15
  66. #define ropkt 16
  67.  
  68. _PROTOTYP(static VOID xxproto,(void));
  69. _PROTOTYP(static VOID wheremsg,(void));
  70. _PROTOTYP(int wart,(void));
  71. _PROTOTYP(static int sgetinit,(int,int));
  72. _PROTOTYP(int sndspace,(int));
  73.  
  74. /* External C-Kermit variable declarations */
  75.   extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err;
  76.   extern char * rfspec, * sfspec, * srfspec, * rrfspec;
  77.   extern char * prfspec, * psfspec, * psrfspec, * prrfspec;
  78.   extern char *cdmsgfile[];
  79.   extern char * snd_move, * snd_rename, * srimsg;
  80.   extern char filnam[], ofilnam[], fspec[], ttname[], ofn1[];
  81.   extern CHAR sstate, *srvptr, *data;
  82.   extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network;
  83.   extern int oopts, omode, oname, opath, nopush, isguest, xcmdsrc, rcdactive;
  84.   extern int rejection, moving, fncact, bye_active, urserver, fatalio;
  85.   extern int protocol, prefixing, filcnt, carrier, fnspath, interrupted;
  86.   extern int recursive, inserver, nzxopts, idletmo, srvidl, xfrint;
  87.   extern struct ck_p ptab[];
  88.   extern int remfile, rempipe, xferstat, filestatus, wearealike, fackpath;
  89.   extern int patterns, filepeek, gnferror;
  90.   extern char * remdest;
  91.  
  92. #ifdef PKTZEROHACK
  93. #define PKTZEROLEN 32
  94. static char ipktack[PKTZEROLEN];
  95. static int ipktlen = 0;
  96. #endif /* PKTZEROHACK */
  97.  
  98. static int s_timint = -1;        /* For saving timeout value */
  99. static int myjob = 0;
  100. static int havefs = 0;
  101. #ifdef CK_LOGIN
  102. static int logtries = 0;
  103. #endif /* CK_LOGIN */
  104.  
  105. static int cancel = 0;
  106. int fackbug = 0;
  107.  
  108. #ifdef STREAMING
  109. extern int streaming, streamok;
  110.  
  111. static VOID
  112. streamon() {
  113.     if (streamok) {
  114.     debug(F100,"streamon","",0);
  115.     streaming = 1;
  116.     timint = 0;            /* No timeouts while streaming. */
  117.     }
  118. }
  119.  
  120. #ifdef COMMENT                /* (not used) */
  121. static VOID
  122. streamoff() {
  123.     if (streaming) {
  124.     debug(F100,"streamoff","",0);
  125.     streaming = 0;
  126.     timint = s_timint;        /* Restore timeout */
  127.     }
  128. }
  129. #endif /* COMMENT */
  130. #else /* STREAMING */
  131. #define streamon()
  132. #define streamoff()
  133. #endif /* STREAMING */
  134.  
  135. #ifndef NOSPL
  136. _PROTOTYP( int addmac, (char *, char *) );
  137. _PROTOTYP( int zzstring, (char *, char **, int *) );
  138. #endif /* NOSPL */
  139. #ifndef NOICP
  140. _PROTOTYP( int cmdsrc, (void) );
  141. #endif /* NOICP */
  142.  
  143. #ifndef NOSERVER
  144.   extern char * x_user, * x_passwd, * x_acct;
  145.   extern int x_login, x_logged;
  146. #endif /* NOSERVER */
  147.  
  148. #include "ckcnet.h"
  149.  
  150. #ifdef TNCODE
  151.   extern int ttnproto;            /* Network protocol */
  152. #endif /* TNCODE */
  153.  
  154. #ifdef CK_SPEED
  155.   extern short ctlp[];            /* Control-character prefix table */
  156. #endif /* CK_SPEED */
  157.  
  158. #ifdef TNCODE
  159.   extern int tn_b_nlm, tn_b_xfer, tn_nlm;
  160. #ifdef CK_ENCRYPTION
  161.   extern int tn_no_encrypt_xfer;
  162. #endif /* CK_ENCRYPTION */
  163. #endif /* TNCODE */
  164.  
  165. #ifdef TCPSOCKET
  166. #ifndef NOLISTEN
  167.   extern int tcpsrfd;
  168. #endif /* NOLISTEN */
  169. #endif /* TCPSOCKET */
  170.  
  171.   extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl;
  172.   extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo;
  173.   extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla;
  174.   extern int timef, stdinf, rscapu, sendmode, epktflg, epktrcvd, epktsent;
  175.   extern int binary, fncnv;
  176.   extern long speed, ffc, crc16, calibrate, dest;
  177. #ifdef COMMENT
  178.   extern char *TYPCMD, *DIRCMD, *DIRCM2;
  179. #endif /* COMMENT */
  180. #ifndef OS2
  181.   extern char *SPACMD, *SPACM2, *WHOCMD;
  182. #endif /* OS2 */
  183.   extern CHAR *rdatap;
  184.   extern struct zattr iattr;
  185.  
  186. #ifdef VMS
  187.   extern int batch;
  188. #endif /* VMS */
  189.  
  190. #ifdef GFTIMER
  191.   extern CKFLOAT fptsecs;
  192. #endif /* GFTIMER */
  193.  
  194.   extern CHAR *srvcmd;
  195.   extern CHAR *epktmsg;
  196.  
  197. #ifdef CK_TMPDIR
  198. extern int f_tmpdir;            /* Directory changed temporarily */
  199. extern char savdir[];            /* For saving current directory */
  200. extern char * dldir;
  201. #endif /* CK_TMPDIR */
  202.  
  203.   extern int query;            /* Query-active flag */
  204. #ifndef NOSPL
  205.   extern int cmdlvl;
  206.   char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */
  207.   char *qbufp = querybuf;        /* Pointer to it */
  208.   int qbufn = 0;            /* Length of data in it */
  209. #else
  210.   extern int tlevel;
  211. #endif /* NOSPL */
  212.  
  213. #ifndef NOICP
  214.   extern int escape;
  215. #endif /* NOICP */
  216. /*
  217.   If the following flag is nonzero when the protocol module is entered,
  218.   then server mode persists for exactly one transaction, rather than
  219.   looping until BYE or FINISH is received.
  220. */
  221. extern int justone;
  222.  
  223. static int r_save = -1;
  224. static int p_save = -1;
  225.  
  226. /* Function to let remote-mode user know where their file(s) went */
  227.  
  228. int whereflg = 1;            /* Unset with SET XFER REPORT */
  229.  
  230. static VOID
  231. wheremsg() {
  232.     extern int quiet, filrej;
  233.     int n;
  234.     n = filcnt - filrej;
  235.     debug(F101,"wheremsg n","",n);
  236.  
  237.     debug(F110,"wheremsg prfspec",prfspec,0);
  238.     debug(F110,"wheremsg rfspec",rfspec,0);
  239.     debug(F110,"wheremsg psfspec",psfspec,0);
  240.     debug(F110,"wheremsg sfspec",sfspec,0);
  241.  
  242.     debug(F110,"wheremsg prrfspec",prrfspec,0);
  243.     debug(F110,"wheremsg rrfspec",rrfspec,0);
  244.     debug(F110,"wheremsg psrfspec",psrfspec,0);
  245.     debug(F110,"wheremsg srfspec",srfspec,0);
  246.  
  247.     if (!quiet && !local) {
  248.     if (n == 1) {
  249.         switch (myjob) {
  250.           case 's':
  251.         if (sfspec) {
  252.             printf(" SENT: [%s]",sfspec);
  253.             if (srfspec)
  254.               printf(" To: [%s]",srfspec);
  255.             printf(" (%s)\r\n", success ? "OK" : "FAILED");
  256.         }
  257.         break;
  258.           case 'r':
  259.           case 'v':
  260.         if (rrfspec) {
  261.             printf(" RCVD: [%s]",rrfspec);
  262.             if (rfspec)
  263.               printf(" To: [%s]",rfspec);
  264.             printf(" (%s)\r\n", success ? "OK" : "FAILED");
  265.         }
  266.         }
  267.     } else if (n > 1) {
  268.         switch (myjob) {
  269.           case 's':
  270.         if (sfspec) {
  271.             printf(" SENT: (%d files)",n);
  272.             if (srfspec)
  273.               printf(" Last: [%s]",srfspec);
  274.             printf(" (%s)\r\n", success ? "OK" : "FAILED");
  275.         }
  276.         break;
  277.           case 'r':
  278.           case 'v':
  279.         if (rrfspec) {
  280.             printf(" RCVD: (%d files)",n);
  281.             if (rfspec)
  282.               printf(" Last: [%s]",rfspec);
  283.             printf(" (%s)\r\n", success ? "OK" : "FAILED");
  284.         }
  285.         }
  286.     } else if (n == 0) {
  287.         if (myjob == 's')
  288.           printf(" SENT: (0 files)          \r\n");
  289.         else if (myjob == 'r' || myjob == 'v')
  290.           printf(" RCVD: (0 files)          \r\n");
  291.     }
  292.     }
  293. }
  294.  
  295. static VOID
  296. rdebug() {
  297.     if (server)
  298.       debug(F111,"RESUME","server=1",justone);
  299.     else
  300.       debug(F111,"RESUME","server=0",justone);
  301. }
  302.  
  303. /* Flags for the ENABLE and DISABLE commands */
  304. extern int
  305.   en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
  306.   en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
  307.   en_mkd, en_rmd;
  308. #ifndef NOSPL
  309. extern int en_asg, en_que;
  310. #endif /* NOSPL */
  311. extern int what, lastxfer;
  312.  
  313. /* Global variables declared here */
  314.  
  315.   int whatru = 0;            /* What are you. */
  316.   int whatru2 = 0;            /* What are you, cont'd. */
  317.  
  318. /* Local variables */
  319.  
  320.   static char vstate = 0;          /* Saved State   */
  321.   static char vcmd = 0;            /* Saved Command */
  322.   static int reget = 0;            /* Flag for executing REGET */
  323.   static int retrieve = 0;        /* Flag for executing RETRIEVE */
  324.   static int opkt = 0;            /* Send Extended GET packet */
  325.  
  326.   static int x;                /* General-purpose integer */
  327.   static char *s;            /* General-purpose string pointer */
  328.  
  329. /* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */
  330. /* BEGIN is NOT a GOTO! */
  331. #define TINIT if (tinit(1) < 0) return(-9)
  332. #define SERVE { TINIT; resetc(); nakstate=1; what=W_NOTHING; cmarg2=""; \
  333. sendmode=SM_SEND; havefs=0; recursive=r_save; fnspath=p_save; BEGIN serve; }
  334. #define RESUME { rdebug(); if (!server) { wheremsg(); return(0); } else \
  335. if (justone) { justone=0; wheremsg(); return(0); } else { SERVE; } }
  336.  
  337. #ifdef GFTIMER
  338. #define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); \
  339.  fptsecs=gftimer(); quiet=x; return(success)
  340. #else
  341. #define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \
  342.  return(success)
  343. #endif /* GFTIMER */
  344.  
  345. /*
  346.   By late 1999, the big switch() statement generated from the following state
  347.   table began choking even gcc, so here we extract the code from the larger
  348.   states into static routines to reduce the size of the cases and the
  349.   switch() overall.  The routines follow the state table; the prototypes are
  350.   here.  Each of these routines simply contains the text from the
  351.   corresponding case, but with return(-1) added in appropriate places; see
  352.   instructions after the state table switcher.
  353. */
  354. static int rc;                /* Return code for these routines */
  355. static int rcv_s_pkt();            /* Received an S packet */
  356. static int rcv_firstdata();        /* Received first Data packet */
  357. static int rcv_shortreply();        /* Short reply to a REMOTE command  */
  358. static int srv_query();            /* Server answers an query */
  359. static int srv_copy();            /* Server executes REMOTE COPY */
  360. static int srv_rename();        /* Server executes REMOTE RENAME */
  361. static int srv_login();            /* Server executes REMOTE LOGIN */
  362. static int srv_timeout();        /* Server times out */
  363.  
  364.  
  365. #define BEGIN state =
  366.  
  367. int state = 0;
  368.  
  369. int
  370. wart()
  371. {
  372.     int c,actno;
  373.     extern char tbl[];
  374.     while (1) {
  375.     c = input() - 32;
  376.     debug(F000,"PROTO input",ckitoa(state),c+32);
  377.     if (c < 0 || c > 95) c = 0;
  378.     if ((actno = tbl[c + state*96]) != -1)
  379.         switch(actno) {
  380. case 1:
  381.     { TINIT;                /* Send file(s) */
  382.     if (sinit() > 0) BEGIN ssinit;
  383.        else RESUME; }
  384.     break;
  385. case 2:
  386.     { TINIT; nakstate = 1; BEGIN get; }
  387.     break;
  388. case 3:
  389.     {                    /* Client sends a GET command */
  390.     TINIT;
  391.     vstate = get;
  392.     reget = 0;
  393.     retrieve = 0;
  394.     opkt = 0;
  395.     vcmd = 0;
  396. #ifdef PKTZEROHACK
  397.     ipktack[0] = NUL;
  398. #endif /* PKTZEROHACK */
  399.     if (sipkt('I') >= 0)
  400.       BEGIN ipkt;
  401.     else
  402.       RESUME;
  403. }
  404.     break;
  405. case 4:
  406.     {                    /* Client sends a RETRIEVE command */
  407.     TINIT;
  408.     vstate = get;
  409.     reget = 0;
  410.     retrieve = 1;
  411.     opkt = 0;
  412.     vcmd = 0;
  413.     if (sipkt('I') >= 0)
  414.       BEGIN ipkt;
  415.     else
  416.       RESUME;
  417. }
  418.     break;
  419. case 5:
  420.     {                    /* Client sends a REGET command */
  421.     TINIT;
  422.     vstate = get;
  423.     reget = 1;
  424.     retrieve = 0;
  425.     opkt = 0;
  426.     vcmd = 0;
  427.     if (sipkt('I') >= 0)
  428.       BEGIN ipkt;
  429.     else
  430.       RESUME;
  431. }
  432.     break;
  433. case 6:
  434.     {                    /* Client sends Extended GET Packet */
  435.     TINIT;
  436.     vstate = get;
  437.     reget = oopts & GOPT_RES;
  438.     retrieve = oopts & GOPT_DEL;
  439.     opkt = 1;
  440.     vcmd = 0;
  441.     if (sipkt('I') >= 0)
  442.       BEGIN ipkt;
  443.     else
  444.       RESUME;
  445. }
  446.     break;
  447. case 7:
  448.     {                    /* Client sends a Host command */
  449.     TINIT;
  450.     vstate = rgen;
  451.     vcmd = 'C';
  452.     if (sipkt('I') >= 0)
  453.       BEGIN ipkt;
  454.     else
  455.       RESUME;
  456. }
  457.     break;
  458. case 8:
  459.     { TINIT;                /* Client sends a Kermit command */
  460.     vstate = rgen;
  461.     vcmd = 'K';
  462.     if (sipkt('I') >= 0)
  463.       BEGIN ipkt;
  464.     else
  465.       RESUME;
  466. }
  467.     break;
  468. case 9:
  469.     {                    /* Client sends a REMOTE command */
  470.     TINIT;
  471.     vstate = rgen;
  472.     vcmd = 'G';
  473.     if (sipkt('I') >= 0)
  474.       BEGIN ipkt;
  475.     else
  476.       RESUME;
  477. }
  478.     break;
  479. case 10:
  480.     {                    /* Enter server mode */
  481.     int x;
  482.     x = justone;
  483.     if (!ENABLED(en_del)) {        /* If DELETE is disabled */
  484.     if (fncact == XYFX_B ||        /* undo any file collision action */
  485.         fncact == XYFX_U ||        /* that could result in deletion or */
  486.         fncact == XYFX_A ||        /* modification of existing files. */
  487.         fncact == XYFX_X) {
  488. #ifndef NOICP
  489.         extern int g_fncact;
  490.         g_fncact = fncact;        /* Save current setting */
  491. #endif /* NOICP */
  492.         fncact = XYFX_R;        /* Change to RENAME */
  493.         debug(F101,"server DELETE disabled so fncact RENAME","",fncact);
  494.     }
  495.     }
  496.     SERVE;                /* tinit() clears justone... */
  497.     justone = x;
  498. #ifdef IKSDB
  499.     if (ikdbopen) slotstate(what, "SERVER", "", "");
  500. #endif /* IKSDB */
  501. }
  502.     break;
  503. case 11:
  504.     {
  505.     int b1 = 0, b2 = 0;
  506.     if (!data) TINIT;            /* "ABEND" -- Tell other side. */
  507. #ifndef pdp11
  508.     if (epktflg) {            /* If because of E-PACKET command */
  509.     b1 = bctl; b2 = bctu;        /* Save block check type */
  510.     bctl = bctu = 1;        /* set it to 1 */
  511.     }
  512. #endif /* pdp11 */
  513.     errpkt((CHAR *)"User cancelled");    /* Send the packet */
  514. #ifndef pdp11
  515.     if (epktflg) {            /* Restore the block check */
  516.     epktflg = 0;
  517.     bctl = b1; bctu = b2;
  518.     }
  519. #endif /* pdp11 */
  520.     success = 0;
  521.     return(0);                /* Return from protocol. */
  522. }
  523.     break;
  524. case 12:
  525.     {        /* Receive Send-Init packet. */
  526.     rc = rcv_s_pkt();
  527.     cancel = 0;                /* Reset cancellation counter */
  528.     debug(F101,"rcv_s_pkt","",rc);
  529.     if (rc > -1) return(rc);        /* (see below) */
  530. }
  531.     break;
  532. case 13:
  533.     {                /* Get ack for I-packet */
  534.     int x = 0;
  535. #ifdef PKTZEROHACK
  536.     ckstrncpy(ipktack,(char *)rdatap,PKTZEROLEN); /* Save a copy of the ACK */
  537.     ipktlen = strlen(ipktack);
  538. #endif /* PKTZEROHACK */
  539.     spar(rdatap);            /* Set parameters */
  540.     cancel = 0;
  541.     winlo = 0;                /* Set window-low back to zero */
  542.     debug(F101,"<ipkt>Y winlo","",winlo);
  543.     urserver = 1;            /* So I know I'm talking to a server */
  544.     if (vcmd) {                /* If sending a generic command */
  545.     if (tinit(0) < 0) return(-9);    /* Initialize many things */
  546.     x = scmd(vcmd,(CHAR *)cmarg);    /* Do that */
  547.     if (x >= 0) x = 0;        /* (because of O-Packet) */
  548.     debug(F101,"proto G packet scmd","",x);
  549.     vcmd = 0;            /* and then un-remember it. */
  550.     } else if (vstate == get) {
  551.     debug(F101,"REGET sstate","",sstate);
  552.     x = srinit(reget, retrieve, opkt); /* GET or REGET, etc */
  553.     }
  554.     if (x < 0) {            /* If command was too long */
  555.     if (!srimsg)
  556.       srimsg = "Error sending string";
  557.     errpkt((CHAR *)srimsg);        /* cancel both sides. */
  558.     success = 0;
  559.     RESUME;
  560.     } else if (x > 0) {            /* Need to send more O-Packets */
  561.     BEGIN ssopkt;
  562.     } else {
  563.     rtimer();            /* Reset the elapsed seconds timer. */
  564. #ifdef GFTIMER
  565.     rftimer();
  566. #endif /* GFTIMER */
  567.     winlo = 0;            /* Window back to 0, again. */
  568.     debug(F101,"<ipkt>Y vstate","",vstate);
  569.     nakstate = 1;            /* Can send NAKs from here. */
  570.     BEGIN vstate;            /* Switch to desired state */
  571.     }
  572. }
  573.     break;
  574. case 14:
  575.     {                /* Got ACK to O-Packet */
  576.     debug(F100,"CPCPRO <ssopkt>Y","",0);
  577.     x = sopkt();
  578.     debug(F101,"CPCPRO <ssopkt>Y x","",x);
  579.     if (x < 0) {            /* If error */
  580.     errpkt((CHAR *)srimsg);        /* cancel both sides. */
  581.     success = 0;
  582.     RESUME;
  583.     } else if (x == 0) {        /* This was the last O-Packet */
  584.     rtimer();            /* Reset the elapsed seconds timer. */
  585. #ifdef GFTIMER
  586.     rftimer();
  587. #endif /* GFTIMER */
  588.     winlo = 0;            /* Window back to 0, again. */
  589.     debug(F101,"<ssopkt>Y winlo","",winlo);
  590.     nakstate = 1;            /* Can send NAKs from here. */
  591.     BEGIN vstate;            /* Switch to desired state */
  592.     }
  593.     debug(F101,"CPCPRO <ssopkt>Y not changing state","",x);
  594. }
  595.     break;
  596. case 15:
  597.     {                /* Ignore Error reply to I packet */
  598.     int x = 0;
  599.     winlo = 0;                /* Set window-low back to zero */
  600.     debug(F101,"<ipkt>E winlo","",winlo);
  601.     if (vcmd) {                /* In case other Kermit doesn't */
  602.     if (tinit(0) < 0) return(-9);
  603.     x = scmd(vcmd,(CHAR *)cmarg);    /* understand I-packets. */
  604.     if (x >= 0) x = 0;        /* (because of O-Packet) */
  605.     vcmd = 0;            /* Otherwise act as above... */
  606.     } else if (vstate == get) x = srinit(reget, retrieve, opkt);
  607.     if (x < 0) {            /* If command was too long */
  608.     errpkt((CHAR *)srimsg);        /* cancel both sides. */
  609.     success = 0;
  610.     RESUME;
  611.     } else if (x > 0) {            /* Need to send more O-Packets */
  612.     BEGIN ssopkt;
  613.     } else {
  614.     freerpkt(winlo);        /* Discard the Error packet. */
  615.     debug(F101,"<ipkt>E winlo","",winlo);
  616.     winlo = 0;            /* Back to packet 0 again. */
  617.     nakstate = 1;            /* Can send NAKs from here. */
  618.     BEGIN vstate;
  619.     }
  620. }
  621.     break;
  622. case 16:
  623.     {        /* Resend of previous I-pkt ACK, same seq number */
  624.     freerpkt(0);            /* Free the ACK's receive buffer */
  625.     resend(0);                /* Send the GET packet again. */
  626. }
  627.     break;
  628. case 17:
  629.     {                /* Get I-packet */
  630. #ifndef NOSERVER
  631.     spar(rdatap);            /* Set parameters from it */
  632.     ack1(rpar());            /* Respond with our own parameters */
  633. #ifdef COMMENT
  634.     pktinit();                /* Reinitialize packet numbers */
  635. #else
  636. #ifdef COMMENT
  637.     /* This can't be right - it undoes the stuff we just negotiated */
  638.     x = justone;
  639.     tinit(1);                /* Reinitialize EVERYTHING */
  640.     justone = x;            /* But this... */
  641. #else
  642.     tinit(0);                /* Initialize most things */
  643. #endif /* COMMENT */
  644. #endif /* COMMENT */
  645. #endif /* NOSERVER */
  646.     cancel = 0;                /* Reset cancellation counter */
  647. }
  648.     break;
  649. case 18:
  650.     {                /* GET */
  651. #ifndef NOSERVER
  652.     if (x_login && !x_logged) {
  653.     errpkt((CHAR *)"Login required");
  654.     SERVE;
  655.     } else if (sgetinit(0,0) < 0) {
  656.     RESUME;
  657.     } else {
  658. #ifdef CKSYSLOG
  659.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  660.       cksyslog(SYSLG_PR, 1, "server", "GET", (char *)srvcmd);
  661. #endif /* CKSYSLOG */
  662.     BEGIN ssinit;
  663.     }
  664. #endif /* NOSERVER */
  665. }
  666.     break;
  667. case 19:
  668.     {                /* GET /DELETE (RETRIEVE) */
  669. #ifndef NOSERVER
  670.     if (x_login && !x_logged) {
  671.     errpkt((CHAR *)"Login required");
  672.     RESUME;
  673.     } else if (!ENABLED(en_del)) {
  674.     errpkt((CHAR *)"Deleting files is disabled");
  675.     RESUME;
  676.     } else if (sgetinit(0,0) < 0) {
  677.     RESUME;
  678.     } else {
  679.     moving = 1;
  680. #ifdef CKSYSLOG
  681.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  682.       cksyslog(SYSLG_PR, 1, "server", "GET /DELETE", (char *)srvcmd);
  683. #endif /* CKSYSLOG */
  684.     BEGIN ssinit;
  685.     }
  686. #endif /* NOSERVER */
  687. }
  688.     break;
  689. case 20:
  690.     {                /* GET /RECURSIVE */
  691. #ifndef NOSERVER
  692.     recursive = 1;            /* Set these before sgetinit() */
  693.     if (fnspath == PATH_OFF)
  694.       fnspath = PATH_REL;        /* Don't worry, they will be */
  695.     if (x_login && !x_logged) {        /* reset next time through. */
  696.     errpkt((CHAR *)"Login required");
  697.     RESUME;
  698.     } else if (sgetinit(0,0) < 0) {
  699.     RESUME;
  700.     } else {
  701. #ifdef CKSYSLOG
  702.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  703.       cksyslog(SYSLG_PR, 1, "server", "GET /RECURSIVE", (char *)srvcmd);
  704. #endif /* CKSYSLOG */
  705.     BEGIN ssinit;
  706.     }
  707. #endif /* NOSERVER */
  708. }
  709.     break;
  710. case 21:
  711.     {                /* GET /RECURSIVE /DELETE */
  712. #ifndef NOSERVER
  713.     recursive = 1;            /* Set these before sgetinit() */
  714.     if (fnspath == PATH_OFF)
  715.       fnspath = PATH_REL;        /* Don't worry, they will be */
  716.     moving = 1;                /* reset next time through. */
  717.     if (x_login && !x_logged) {
  718.     errpkt((CHAR *)"Login required");
  719.     RESUME;
  720.     } else if (!ENABLED(en_del)) {
  721.     errpkt((CHAR *)"Deleting files is disabled");
  722.     RESUME;
  723.     } else if (sgetinit(0,0) < 0) {
  724.     RESUME;
  725.     } else {
  726. #ifdef CKSYSLOG
  727.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  728.       cksyslog(SYSLG_PR,1,"server",
  729.            "GET /RECURSIVE /DELETE",(char *)srvcmd);
  730. #endif /* CKSYSLOG */
  731.     BEGIN ssinit;
  732.     }
  733. #endif /* NOSERVER */
  734. }
  735.     break;
  736. case 22:
  737.     {                /* GET /RECOVER (REGET) */
  738. #ifndef NOSERVER
  739.     if (x_login && !x_logged) {
  740.     errpkt((CHAR *)"Login required");
  741.     SERVE;
  742.     } else if (sgetinit(1,0) < 0) {
  743.     RESUME;
  744.     } else {
  745. #ifdef CKSYSLOG
  746.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  747.       cksyslog(SYSLG_PR, 1, "server", "GET /RECOVER", (char *)srvcmd);
  748. #endif /* CKSYSLOG */
  749.     BEGIN ssinit;
  750.     }
  751. #endif /* NOSERVER */
  752. }
  753.     break;
  754. case 23:
  755.     {                /* Extended GET */
  756. #ifndef NOSERVER
  757.     if (x_login && !x_logged) {        /* (any combination of options) */
  758.     errpkt((CHAR *)"Login required");
  759.     SERVE;
  760.     } else if ((x = sgetinit(0,1)) < 0) {
  761.     debug(F101,"CKCPRO <serve>O sgetinit fail","",x);
  762.     RESUME;
  763.     } else if (x == 0) {
  764.     debug(F101,"CKCPRO <serve>O sgetinit done","",x);
  765. #ifdef CKSYSLOG
  766.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  767.       cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
  768. #endif /* CKSYSLOG */
  769.     BEGIN ssinit;
  770.     } else {                /* Otherwise stay in this state */
  771.     debug(F101,"CKCPRO <serve>O sgetinit TBC","",x);
  772.     ack();
  773.     BEGIN ropkt;
  774.     }
  775. #endif /* NOSERVER */
  776. }
  777.     break;
  778. case 24:
  779.     {
  780. #ifndef NOSERVER
  781.     if (x_login && !x_logged) {        /* (any combination of options) */
  782.     errpkt((CHAR *)"Login required");
  783.     SERVE;
  784.     } else if ((x = sgetinit(0,1)) < 0) {
  785.     debug(F101,"CKCPRO <ropkt>O sgetinit fail","",x);
  786.     RESUME;
  787.     } else if (x == 0) {
  788.     debug(F101,"CKCPRO <ropkt>O sgetinit done","",x);
  789. #ifdef CKSYSLOG
  790.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  791.       cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
  792. #endif /* CKSYSLOG */
  793.     BEGIN ssinit;
  794.     } else {                /* Otherwise stay in this state */
  795.     debug(F101,"CKCPRO <ropkt>O sgetinit TBC","",x);
  796.     ack();
  797.     }
  798. #endif /* NOSERVER */
  799. }
  800.     break;
  801. case 25:
  802.     {                /* Generic server command */
  803. #ifndef NOSERVER
  804.     srvptr = srvcmd;            /* Point to command buffer */
  805.     decode(rdatap,putsrv,0);        /* Decode packet data into it */
  806.     putsrv(NUL);            /* Insert a couple nulls */
  807.     putsrv(NUL);            /* for termination */
  808.     if (srvcmd[0]) {
  809.     sstate = srvcmd[0];        /* Set requested start state */
  810.     if (x_login && !x_logged &&    /* Login required? */
  811.         /* Login, Logout, and Help are allowed when not logged in */
  812.         sstate != 'I' && sstate != 'L' && sstate != 'H') {
  813.         errpkt((CHAR *)"Login required");
  814.         SERVE;
  815.     } else {
  816.         nakstate = 0;        /* Now I'm the sender. */
  817.         what = W_REMO;        /* Doing a REMOTE command. */
  818. #ifdef STREAMING
  819.         if (!streaming)
  820. #endif /* STREAMING */
  821.           if (timint < 1)
  822.         timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
  823.         binary = XYFT_T;        /* Switch to text mode */
  824.         BEGIN generic;        /* Switch to generic command state */
  825.     }
  826.     } else {
  827.     errpkt((CHAR *)"Badly formed server command"); /* report error */
  828.     RESUME;            /* & go back to server command wait */
  829.     }
  830. #endif /* NOSERVER */
  831. }
  832.     break;
  833. case 26:
  834.     {                /* Receive Host command */
  835. #ifndef NOSERVER
  836.     if (x_login && !x_logged) {
  837.     errpkt((CHAR *)"Login required");
  838.     SERVE;
  839.     } else if (!ENABLED(en_hos)) {
  840.     errpkt((CHAR *)"REMOTE HOST disabled");
  841.     RESUME;
  842.     } else if (nopush) {
  843.     errpkt((CHAR *)"HOST commands not available");
  844.     RESUME;
  845.     } else {
  846.     srvptr = srvcmd;        /* Point to command buffer */
  847.     decode(rdatap,putsrv,0);    /* Decode command packet into it */
  848.     putsrv(NUL);            /* Null-terminate */
  849.     nakstate = 0;            /* Now sending, not receiving */
  850.     binary = XYFT_T;        /* Switch to text mode */
  851.     if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */
  852.         what = W_REMO;        /* Doing a REMOTE command. */
  853. #ifdef STREAMING
  854.         if (!streaming)
  855. #endif /* STREAMING */
  856.           if (timint < 1)
  857.         timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
  858. #ifdef CKSYSLOG
  859.         if (ckxsyslog >= SYSLG_PR && ckxlogging)
  860.           cksyslog(SYSLG_PR, 1, "server", "REMOTE HOST", (char *)srvcmd);
  861. #endif /* CKSYSLOG */
  862.         BEGIN ssinit;        /* If OK, send back its output */
  863.     } else {            /* Otherwise */
  864.         errpkt((CHAR *)"Can't do system command"); /* report error */
  865.         RESUME;            /* & go back to server command wait */
  866.     }
  867.     }
  868. #endif /* NOSERVER */
  869. }
  870.     break;
  871. case 27:
  872.     {                /* Interrupted or connection lost */
  873.     rc = srv_timeout();
  874.     debug(F101,"srv_timeout","",rc);
  875.     if (rc > -1) return(rc);        /* (see below) */
  876. }
  877.     break;
  878. case 28:
  879.     {                /* Server got a NAK in command-wait */
  880. #ifndef NOSERVER
  881.     errpkt((CHAR *)"Did you say RECEIVE instead of GET?");
  882.     RESUME;
  883. #endif /* NOSERVER */
  884. }
  885.     break;
  886. case 29:
  887.     {                /* Any other command in this state */
  888. #ifndef NOSERVER
  889.     if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */
  890.       errpkt((CHAR *)"Unimplemented server function");
  891.     /* If we answer an E with an E, we get an infinite loop. */
  892.     /* A Y (ACK) can show up here if we sent back a short-form reply to */
  893.     /* a G packet and it was echoed.  ACKs can be safely ignored here. */
  894.     RESUME;                /* Go back to server command wait. */
  895. #endif /* NOSERVER */
  896. }
  897.     break;
  898. case 30:
  899.     {                /* Login/Out */
  900.     rc = srv_login();
  901.     debug(F101,"<generic>I srv_login","",rc);
  902.     if (rc > -1) return(rc);        /* (see below) */
  903. }
  904.     break;
  905. case 31:
  906.     {                /* Got REMOTE CD command */
  907. #ifndef NOSERVER
  908. #ifdef CKSYSLOG
  909.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  910.       cksyslog(SYSLG_PR, 1, "server", "REMOTE CD", (char *)srvcmd);
  911. #endif /* CKSYSLOG */
  912.     if (!ENABLED(en_cwd)) {
  913.     errpkt((CHAR *)"REMOTE CD disabled");
  914.     RESUME;
  915.     } else {
  916.     char * p = NULL;
  917.     x = cwd((char *)(srvcmd+1));    /* Try to change directory */
  918. #ifdef IKSDB
  919.     if (ikdbopen) slotstate(what,"REMOTE CD", (char *)(srvcmd+2), "");
  920. #endif /* IKSDB */
  921.     if (!x) {            /* Failed */
  922.         errpkt((CHAR *)"Can't change directory");
  923.         RESUME;            /* Back to server command wait */
  924.     } else if (x == 2) {        /* User wants message */
  925.         if (!ENABLED(en_typ)) {    /* Messages (REMOTE TYPE) disabled? */
  926.         errpkt((CHAR *)"REMOTE TYPE disabled");
  927.         RESUME;
  928.         } else {            /* TYPE is enabled */
  929.         int i;
  930.         for (i = 0; i < 8; i++) {
  931.             if (zchki(cdmsgfile[i]) > -1) {
  932.             break;
  933.             }
  934.         }
  935.         binary = XYFT_T;    /* Use text mode for this. */
  936.         if (i < 8 && sndtype(cdmsgfile[i])) { /* Have readme file? */
  937.             BEGIN ssinit;    /* OK */
  938.         } else {        /* not OK */
  939.             p = zgtdir();
  940.             if (!p) p = "";
  941.             success = (*p) ? 1 : 0;
  942.             ack1((CHAR *)p);    /* ACK with new directory name */
  943.             success = 1;
  944.             RESUME;        /* wait for next server command */
  945.         }
  946.         }
  947.     } else {            /* User doesn't want message */
  948.         p =zgtdir();
  949.         if (!p) p = "";
  950.         success = (*p) ? 1 : 0;
  951.         ack1((CHAR *)p);
  952.         success = 1;
  953.         RESUME;            /* Wait for next server command */
  954.     }
  955.     }
  956. #endif /* NOSERVER */
  957. }
  958.     break;
  959. case 32:
  960.     {                /* Got REMOTE PWD command */
  961. #ifndef NOSERVER
  962. #ifdef CKSYSLOG
  963.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  964.       cksyslog(SYSLG_PR, 1, "server", "REMOTE PWD", NULL);
  965. #endif /* CKSYSLOG */
  966.     if (!ENABLED(en_cwd)) {
  967.     errpkt((CHAR *)"REMOTE CD disabled");
  968.     RESUME;
  969.     } else {
  970.     if (encstr((CHAR *)zgtdir()) > -1) { /* Encode current directory */
  971.         ack1(data);            /* If it fits, send it back in ACK */
  972.         success = 1;
  973.     } else {            /* Failed */
  974.         ack();            /* Send empty ACK */
  975.         success = 0;        /* and indicate failure locally */
  976.     }
  977.     RESUME;                /* Back to server command wait */
  978.     }
  979. #endif /* NOSERVER */
  980. }
  981.     break;
  982. case 33:
  983.     {                /* REMOTE DIRECTORY command */
  984. #ifndef NOSERVER
  985.     char *n2;
  986. #ifdef CKSYSLOG
  987.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  988.       cksyslog(SYSLG_PR, 1, "server", "REMOTE DIRECTORY", (char *)srvcmd);
  989. #endif /* CKSYSLOG */
  990.     if (!ENABLED(en_dir)) {        /* If DIR is disabled, */
  991.     errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */
  992.     RESUME;
  993.     } else {                /* DIR is enabled. */
  994. #ifdef IKSDB
  995.     if (ikdbopen) slotstate(what,"REMOTE DIR", (char *)(srvcmd+2), "");
  996. #endif /* IKSDB */
  997.     if (!ENABLED(en_cwd)) {        /* But CWD is disabled */
  998.         zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
  999.         if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
  1000.         errpkt((CHAR *)"Access denied");
  1001.         RESUME;            /* Remember, this is not a goto! */
  1002.         }
  1003.     }
  1004.     if (state == generic) {            /* It's OK to go ahead. */
  1005. #ifdef COMMENT
  1006.         n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2;
  1007.         if (syscmd(n2,(char *)(srvcmd+2)))  /* If it can be done */
  1008. #else
  1009.         int x;
  1010.         if ((x = snddir((char*)(srvcmd+2))) > 0)
  1011. #endif /* COMMENT */
  1012.         {
  1013.         BEGIN ssinit;        /* send the results back; */
  1014.         } else {            /* otherwise */
  1015.         if (x < 0)
  1016.           errpkt((CHAR *)"No files match");
  1017.         else
  1018.           errpkt((CHAR *)"Can't list directory");
  1019.         RESUME;            /* return to server command wait */
  1020.         }
  1021.     }
  1022.     }
  1023. #endif /* NOSERVER */
  1024. }
  1025.     break;
  1026. case 34:
  1027.     {                /* REMOTE DELETE (Erase) */
  1028. #ifndef NOSERVER
  1029.     char *n2;
  1030. #ifdef CKSYSLOG
  1031.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1032.       cksyslog(SYSLG_PR, 1, "server", "REMOTE DELETE", (char *)srvcmd);
  1033. #endif /* CKSYSLOG */
  1034.     if (!ENABLED(en_del)) {
  1035.     errpkt((CHAR *)"REMOTE DELETE disabled");
  1036.     RESUME;
  1037.     } else {                /* DELETE is enabled */
  1038. #ifdef IKSDB
  1039.     if (ikdbopen) slotstate(what,"REMOTE DELETE", (char *)(srvcmd+2), "");
  1040. #endif /* IKSDB */
  1041.     if (!ENABLED(en_cwd)) {        /* but CWD is disabled */
  1042.         zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
  1043.         if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
  1044.         errpkt((CHAR *)"Access denied");
  1045.         RESUME;            /* Remember, this is not a goto! */
  1046.         }
  1047.     } else if (isdir((char *)(srvcmd+2))) { /* A directory name? */
  1048.         errpkt((CHAR *)"It's a directory");
  1049.         RESUME;
  1050.     }
  1051.     if (state == generic) {        /* It's OK to go ahead. */
  1052.         int x;
  1053.         if ((x = snddel((char*)(srvcmd+2))) > 0) {
  1054.         BEGIN ssinit;        /* If OK send results back */
  1055.         } else {            /* otherwise */
  1056.         if (x < 0)
  1057.           errpkt((CHAR *)"File not found"); /* report failure */
  1058.         else
  1059.           errpkt((CHAR *)"DELETE failed");
  1060.         RESUME;            /* & return to server command wait */
  1061.         }
  1062.     }
  1063.     }
  1064. #endif /* NOSERVER */
  1065. }
  1066.     break;
  1067. case 35:
  1068.     {                /* FINISH */
  1069. #ifndef NOSERVER
  1070. #ifdef CKSYSLOG
  1071.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1072.       cksyslog(SYSLG_PR, 1, "server", "FINISH", NULL);
  1073. #endif /* CKSYSLOG */
  1074. #ifdef IKSDB
  1075.     if (ikdbopen) slotstate(what,"SERVER FINISH", "", "");
  1076. #endif /* IKSDB */
  1077.     if (!ENABLED(en_fin)) {
  1078.     errpkt((CHAR *)"FINISH disabled");
  1079.     RESUME;
  1080.     } else {
  1081.     ack();                /* Acknowledge */
  1082.     xxscreen(SCR_TC,0,0L,"");    /* Display */
  1083.     success = 1;
  1084.     return(0);            /* Done */
  1085.     }
  1086. #endif /* NOSERVER */
  1087. }
  1088.     break;
  1089. case 36:
  1090.     {                /* EXIT */
  1091. #ifndef NOSERVER
  1092. #ifdef CKSYSLOG
  1093.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1094.       cksyslog(SYSLG_PR, 1, "server", "REMOTE EXIT", NULL);
  1095. #endif /* CKSYSLOG */
  1096. #ifdef IKSDB
  1097.     if (ikdbopen) slotstate(what,"REMOTE EXIT", "", "");
  1098. #endif /* IKSDB */
  1099.     if (!ENABLED(en_xit)) {
  1100.     errpkt((CHAR *)"EXIT disabled");
  1101.     RESUME;
  1102.     } else {
  1103.     ack();                /* Acknowledge */
  1104.     xxscreen(SCR_TC,0,0L,"");    /* Display */
  1105.     doexit(GOOD_EXIT,xitsta);
  1106.     }
  1107. #endif /* NOSERVER */
  1108. }
  1109.     break;
  1110. case 37:
  1111.     {                /* BYE (Logout) */
  1112. #ifndef NOSERVER
  1113. #ifdef CKSYSLOG
  1114.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1115.       cksyslog(SYSLG_PR, 1, "server", "BYE", NULL);
  1116. #endif /* CKSYSLOG */
  1117. #ifdef IKSDB
  1118.     if (ikdbopen) slotstate(what,"SERVER BYE", "", "");
  1119. #endif /* IKSDB */
  1120.     if (!ENABLED(en_bye)) {
  1121.     errpkt((CHAR *)"BYE disabled");
  1122.     RESUME;
  1123.     } else {
  1124.     ack();                /* Acknowledge */
  1125.     success = 1;
  1126.     msleep(750);            /* Give the ACK time to get out */
  1127.     if (local)
  1128.       ttres();            /* Reset the terminal */
  1129.     xxscreen(SCR_TC,0,0L,"");    /* Display */
  1130.     doclean(1);            /* Clean up files, etc */
  1131. #ifdef DEBUG
  1132.     debug(F100,"C-Kermit BYE - Loggin out...","",0);
  1133.     zclose(ZDFILE);
  1134. #endif /* DEBUG */
  1135. #ifdef IKSD
  1136. #ifdef CK_LOGIN
  1137.     if (inserver)
  1138.       ckxlogout();
  1139.     else
  1140. #endif /* CK_LOGIN */
  1141. #endif /* IKSD */
  1142. #ifdef TCPSOCKET
  1143. #ifndef NOLISTEN
  1144.       if (network && tcpsrfd > 0 && !inserver)
  1145.         doexit(GOOD_EXIT,xitsta);
  1146.     else
  1147. #endif /* NOLISTEN */
  1148. #endif /* TCPSOCKET */
  1149.       return(zkself());        /* Try to log self out */
  1150.     }
  1151. #endif /* NOSERVER */
  1152. }
  1153.     break;
  1154. case 38:
  1155.     {                /* REMOTE HELP */
  1156. #ifdef CKSYSLOG
  1157.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1158.       cksyslog(SYSLG_PR, 1, "server", "REMOTE HELP", NULL);
  1159. #endif /* CKSYSLOG */
  1160. #ifdef IKSDB
  1161.     if (ikdbopen) slotstate(what,"REMOTE HELP", "", "");
  1162. #endif /* IKSDB */
  1163. #ifndef NOSERVER
  1164.     if (sndhlp()) {
  1165.     BEGIN ssinit;            /* try to send it */
  1166.     } else {                /* If not ok, */
  1167.     errpkt((CHAR *)"Can't send help"); /* send error message instead */
  1168.     RESUME;                /* and return to server command wait */
  1169.     }
  1170. #endif /* NOSERVER */
  1171. }
  1172.     break;
  1173. case 39:
  1174.     {                            /* REMOTE RENAME */
  1175.     rc = srv_rename();
  1176.     debug(F101,"srv_rename","",rc);
  1177.     if (rc > -1) return(rc);        /* (see below) */
  1178. }
  1179.     break;
  1180. case 40:
  1181.     {                            /* REMOTE COPY */
  1182.     rc = srv_copy();
  1183.     debug(F101,"srv_copy","",rc);
  1184.     if (rc > -1) return(rc);        /* (see below) */
  1185. }
  1186.     break;
  1187. case 41:
  1188.     {                /* REMOTE SET */
  1189. #ifdef CKSYSLOG
  1190.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1191.       cksyslog(SYSLG_PR, 1, "server", "REMOTE SET", (char *)srvcmd);
  1192. #endif /* CKSYSLOG */
  1193. #ifndef NOSERVER
  1194. #ifdef IKSDB
  1195.     if (ikdbopen) slotstate(what,"REMOTE SET", (char *)(srvcmd+1), "");
  1196. #endif /* IKSDB */
  1197.     if (!ENABLED(en_set)) {
  1198.     errpkt((CHAR *)"REMOTE SET disabled");
  1199.     RESUME;
  1200.     } else {
  1201.     if (remset((char *)(srvcmd+1))) { /* Try to do what they ask */
  1202.         success = 1;
  1203.         ack();            /* If OK, then acknowledge */
  1204.     } else                /* Otherwise */
  1205.       errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */
  1206.     RESUME;                /* Return to server command wait */
  1207.     }
  1208. #endif /* NOSERVER */
  1209. }
  1210.     break;
  1211. case 42:
  1212.     {                /* REMOTE TYPE */
  1213. #ifndef NOSERVER
  1214.     char *n2;
  1215. #ifdef CKSYSLOG
  1216.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1217.       cksyslog(SYSLG_PR, 1, "server", "REMOTE TYPE", (char *)srvcmd);
  1218. #endif /* CKSYSLOG */
  1219.     if (!ENABLED(en_typ)) {
  1220.     errpkt((CHAR *)"REMOTE TYPE disabled");
  1221.     RESUME;
  1222.     } else {
  1223. #ifdef IKSDB
  1224.     if (ikdbopen) slotstate(what,"REMOTE TYPE", (char *)(srvcmd+2), "");
  1225. #endif /* IKSDB */
  1226.     if (!ENABLED(en_cwd)) {        /* If CWD disabled */
  1227.         zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
  1228.         if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
  1229.         errpkt((CHAR *)"Access denied");
  1230.         RESUME;            /* Remember, this is not a goto! */
  1231.         }
  1232.     }
  1233.     if (state == generic) {        /* It's OK to go ahead. */
  1234.         binary = XYFT_T;        /* Use text mode for this. */
  1235.         if (            /* (RESUME didn't change state) */
  1236. #ifdef COMMENT
  1237.           syscmd(TYPCMD,(char *)(srvcmd+2))    /* Old way */
  1238. #else
  1239.           sndtype((char *)(srvcmd+2)) /* New way */
  1240. #endif /* COMMENT */
  1241.         )
  1242.           BEGIN ssinit;        /* OK */
  1243.         else {            /* not OK */
  1244.         errpkt((CHAR *)"Can't type file"); /* give error message */
  1245.         RESUME;            /* wait for next server command */
  1246.         }
  1247.     }
  1248.     }
  1249. #endif /* NOSERVER */
  1250. }
  1251.     break;
  1252. case 43:
  1253.     {                /* REMOTE MKDIR */
  1254. #ifndef NOSERVER
  1255. #ifdef CK_MKDIR
  1256. #ifdef CKSYSLOG
  1257.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1258.       cksyslog(SYSLG_PR, 1, "server", "REMOTE MKDIR", (char *)srvcmd);
  1259. #endif /* CKSYSLOG */
  1260. #ifdef IKSDB
  1261.     if (ikdbopen) slotstate(what,"REMOTE MKDIR", (char *)(srvcmd+2), "");
  1262. #endif /* IKSDB */
  1263.     if (!ENABLED(en_mkd)) {
  1264.     errpkt((CHAR *)"REMOTE MKDIR disabled");
  1265.     RESUME;
  1266.     } else if (!ENABLED(en_cwd)) {    /* If CWD disabled */
  1267.     errpkt((CHAR *)"Directory access restricted");
  1268.     RESUME;                /* Remember, this is not a goto! */
  1269.     }
  1270.     if (state == generic) {        /* OK to go ahead. */
  1271.     char *p = NULL;
  1272.     x = ckmkdir(0,(char *)(srvcmd+2),&p,0,1); /* Make the directory */
  1273.     if (!p) p = "";
  1274.     if (x > -1) {
  1275.         encstr((CHAR *)p);        /* OK - encode the name */
  1276.         ack1(data);            /* Send short-form response */
  1277.         success = 1;
  1278.         RESUME;
  1279.     } else {            /* not OK */
  1280.         if (!*p) p = "Directory creation failure";
  1281.         errpkt((CHAR *)p);        /* give error message */
  1282.         RESUME;            /* Wait for next server command */
  1283.     }
  1284.     }
  1285. #else
  1286.     errpkt((CHAR *)"REMOTE MKDIR not available");
  1287.     RESUME;
  1288. #endif /* CK_MKDIR */
  1289. #endif /* NOSERVER */
  1290. }
  1291.     break;
  1292. case 44:
  1293.     {                /* REMOTE RMDIR */
  1294. #ifndef NOSERVER
  1295. #ifdef CK_MKDIR
  1296. #ifdef CKSYSLOG
  1297.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1298.       cksyslog(SYSLG_PR, 1, "server", "REMOTE RMDIR", (char *)srvcmd);
  1299. #endif /* CKSYSLOG */
  1300. #ifdef IKSDB
  1301.     if (ikdbopen) slotstate(what,"REMOTE RMDIR", (char *)(srvcmd+2), "");
  1302. #endif /* IKSDB */
  1303.     if (!ENABLED(en_rmd)) {
  1304.     errpkt((CHAR *)"REMOTE RMDIR disabled");
  1305.     RESUME;
  1306.     } else if (!ENABLED(en_cwd)) {    /* If CWD disabled */
  1307.     errpkt((CHAR *)"Directory access restricted");
  1308.     RESUME;                /* Remember, this is not a goto! */
  1309.     }
  1310.     if (state == generic) {        /* OK to go ahead. */
  1311.     char *p = NULL;
  1312.     x = ckmkdir(1,(char *)(srvcmd+2),&p,0,1);
  1313.     if (!p) p = "";
  1314.     if (x > -1) {
  1315.         encstr((CHAR *)p);        /* OK - encode the name */
  1316.         ack1(data);            /* Send short-form response */
  1317.         success = 1;
  1318.         RESUME;
  1319.     } else {            /* not OK */
  1320.         if (!*p) p = "Directory removal failure";
  1321.         errpkt((CHAR *)p);        /* give error message */
  1322.         RESUME;            /* Wait for next server command */
  1323.     }
  1324.     }
  1325. #else
  1326.     errpkt((CHAR *)"REMOTE RMDIR not available");
  1327.     RESUME;
  1328. #endif /* CK_MKDIR */
  1329. #endif /* NOSERVER */
  1330. }
  1331.     break;
  1332. case 45:
  1333.     {                /* REMOTE SPACE */
  1334. #ifndef NOSERVER
  1335. #ifdef CKSYSLOG
  1336.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1337.       cksyslog(SYSLG_PR, 1, "server", "REMOTE SPACE", (char *)srvcmd);
  1338. #endif /* CKSYSLOG */
  1339.     if (!ENABLED(en_spa)) {
  1340.     errpkt((CHAR *)"REMOTE SPACE disabled");
  1341.     RESUME;
  1342.     } else {
  1343.     x = srvcmd[1];            /* Get area to check */
  1344.     x = ((x == NUL) || (x == SP)
  1345. #ifdef OS2
  1346.          || (x == '!') || (srvcmd[3] == ':')
  1347. #endif /* OS2 */
  1348.          );
  1349. #ifdef IKSDB
  1350.     if (ikdbopen) slotstate(what,
  1351.                   "REMOTE SPACE",
  1352.                   (x ? "" : (char *)srvcmd),
  1353.                   ""
  1354.                   );
  1355. #endif /* IKSDB */
  1356.     if (!x && !ENABLED(en_cwd)) {    /* CWD disabled */
  1357.         errpkt((CHAR *)"Access denied"); /* and non-default area given, */
  1358.         RESUME;            /* refuse. */
  1359.     } else {
  1360. #ifdef OS2
  1361. _PROTOTYP(int sndspace,(int));
  1362.         if (sndspace(x ? toupper(srvcmd[2]) : 0)) {
  1363.         BEGIN ssinit;        /* send the report. */
  1364.         } else {            /* If not ok, */
  1365.         errpkt((CHAR *)"Can't send space"); /* send error message */
  1366.         RESUME;            /* and return to server command wait */
  1367.         }
  1368. #else
  1369.             if (nopush)
  1370.               x = 0;
  1371.             else
  1372.               x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2)));
  1373.         if (x) {            /* If we got the info */
  1374.         BEGIN ssinit;        /* send it */
  1375.         } else {            /* otherwise */
  1376.         errpkt((CHAR *)"Can't check space"); /* send error message */
  1377.         RESUME;            /* and await next server command */
  1378.         }
  1379. #endif /* OS2 */
  1380.     }
  1381.     }
  1382. #endif /* NOSERVER */
  1383. }
  1384.     break;
  1385. case 46:
  1386.     {                /* REMOTE WHO */
  1387. #ifndef NOSERVER
  1388. #ifdef CKSYSLOG
  1389.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1390.       cksyslog(SYSLG_PR, 1, "server", "REMOTE WHO", (char *)srvcmd);
  1391. #endif /* CKSYSLOG */
  1392. #ifdef IKSDB
  1393.     if (ikdbopen) slotstate(what,"REMOTE WHO", (char *)(srvcmd+2), "");
  1394. #endif /* IKSDB */
  1395.     if (!ENABLED(en_who)) {
  1396.     errpkt((CHAR *)"REMOTE WHO disabled");
  1397.     RESUME;
  1398.     } else {
  1399. #ifdef OS2
  1400. _PROTOTYP(int sndwho,(char *));
  1401.         if (sndwho((char *)(srvcmd+2))) {
  1402.         BEGIN ssinit;        /* try to send it */
  1403.         } else {            /* If not ok, */
  1404.         errpkt((CHAR *)"Can't do who command"); /* send error msg */
  1405.         RESUME;            /* and return to server command wait */
  1406.         }
  1407. #else
  1408.     if (syscmd(WHOCMD,(char *)(srvcmd+2))) {
  1409.         BEGIN ssinit;
  1410.     } else {
  1411.         errpkt((CHAR *)"Can't do who command");
  1412.         RESUME;
  1413.     }
  1414. #endif /* OS2 */
  1415.     }
  1416. #endif /* NOSERVER */
  1417. }
  1418.     break;
  1419. case 47:
  1420.     {                /* Variable query or set */
  1421.     rc = srv_query();
  1422.     debug(F101,"srv_query","",rc);
  1423.     if (rc > -1) return(rc);
  1424. }
  1425.     break;
  1426. case 48:
  1427.     {                /* REMOTE MESSAGE command */
  1428. #ifndef NOSERVER
  1429.     debug(F110,"RMSG",(char *)srvcmd+2,0);
  1430.     xxscreen(SCR_MS,0,0L,(char *)(srvcmd+2));
  1431.     ack();
  1432.     RESUME;
  1433. #endif    /* NOSERVER */
  1434. }
  1435.     break;
  1436. case 49:
  1437.     {                /* Interrupted or connection lost */
  1438. #ifndef NOSERVER
  1439.     if (fatalio) {            /* Connection lost */
  1440. #ifdef CKSYSLOG
  1441.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1442.       cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
  1443. #endif /* CKSYSLOG */
  1444.     success = 0;
  1445.     xitsta |= (what & W_KERMIT);
  1446.     QUIT;
  1447.     } else if (interrupted) {
  1448.     if (!ENABLED(en_fin)) {        /* Ctrl-C typed */
  1449.         errpkt((CHAR *)"QUIT disabled");
  1450.         RESUME;
  1451.     } else {
  1452. #ifdef CKSYSLOG
  1453.         if (ckxsyslog >= SYSLG_PR && ckxlogging)
  1454.           cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
  1455. #endif /* CKSYSLOG */
  1456.         success = 0;
  1457.         xitsta |= (what & W_KERMIT);
  1458.         QUIT;
  1459.     }
  1460.     } else {                /* Shouldn't happen */
  1461.     debug(F100,"SERVER (generic) GOT UNEXPECTED 'q'","",0);
  1462.     QUIT;
  1463.     }
  1464. #endif /* NOSERVER */
  1465. }
  1466.     break;
  1467. case 50:
  1468.     {                /* Anything else in this state... */
  1469. #ifndef NOSERVER
  1470.     errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */
  1471.     RESUME;                /* and return to server command wait */
  1472. #endif /* NOSERVER */
  1473. }
  1474.     break;
  1475. case 51:
  1476.     {                /* Sent BYE and connection broken */
  1477.     if (bye_active && ttchk() < 0) {
  1478.     msleep(500);
  1479.     bye_active = 0;
  1480.     ttclos(0);            /* Close our end of the connection */
  1481.     clsof(0);
  1482.     return(success = 1);
  1483.     } else {                /* Other generic command */
  1484.     return(success = 0);        /* or connection not broken */
  1485.     }
  1486. }
  1487.     break;
  1488. case 52:
  1489.     {                /* Short-Form reply */
  1490.     rc = rcv_shortreply();
  1491.     debug(F101,"<rgen>Y rcv_shortreply","",rc);
  1492.     if (rc > -1) return(rc);
  1493. }
  1494.     break;
  1495. case 53:
  1496.     {                /* File header */
  1497.     /* char *n2; */
  1498.     extern int rsn;
  1499.     debug(F101,"<rfile>F winlo 1","",winlo);
  1500.     xflg = 0;                /* Not screen data */
  1501.     if (!czseen)
  1502.       cancel = 0;            /* Reset cancellation counter */
  1503. #ifdef CALIBRATE
  1504.     if (dest == DEST_N)
  1505.       calibrate = 1;
  1506. #endif /* CALIBRATE */
  1507.     if (!rcvfil(filnam)) {        /* Figure out local filename */
  1508.     errpkt((CHAR *)rf_err);        /* Trouble */
  1509.     RESUME;
  1510.     } else {                /* Real file, OK to receive */
  1511.     char * fnp;
  1512.     debug(F111,"<rfile>F winlo 2",fspec,winlo);
  1513.     if (filcnt == 1)        /* rcvfil set this to 1 for 1st file */
  1514.       crc16 = 0L;            /* Clear file CRC */
  1515.     fnp = fspec;            /* This is the full path */
  1516.     if (server && !ENABLED(en_cwd) || /* if DISABLE CD */
  1517.         !fackpath              /* or F-ACK-PATH OFF */
  1518.         ) {
  1519.         zstrip(fspec,&fnp);        /* don't send back full path */
  1520.     }
  1521.     encstr((CHAR *)fnp);
  1522.     if (fackbug)
  1523.       ack();
  1524.     else
  1525.       ack1(data);            /* Send it back in ACK */
  1526.     initattr(&iattr);        /* Clear file attribute structure */
  1527.     streamon();
  1528.     if (window(wslotn) < 0) {    /* Allocate negotiated window slots */
  1529.         errpkt((CHAR *)"Can't open window");
  1530.         RESUME;
  1531.     }
  1532. #ifdef IKSDB
  1533.     if (ikdbopen) slotstate(what,
  1534.                   server ? "SERVER" : "",
  1535.                   "RECEIVE",
  1536.                   fspec
  1537.                   );
  1538. #endif /* IKSDB */
  1539.     BEGIN rattr;            /* Now expect Attribute packets */
  1540.     }
  1541. }
  1542.     break;
  1543. case 54:
  1544.     {                /* X-packet instead of file header */
  1545.     xflg = 1;                /* Screen data */
  1546.     if (!czseen)
  1547.       cancel = 0;            /* Reset cancellation counter */
  1548.     ack();                /* Acknowledge the X-packet */
  1549.     initattr(&iattr);            /* Initialize attribute structure */
  1550.     streamon();
  1551.     if (window(wslotn) < 0) {        /* allocate negotiated window slots */
  1552.     errpkt((CHAR *)"Can't open window");
  1553.     RESUME;
  1554.     }
  1555. #ifndef NOSPL
  1556.     if (query) {            /* If this is the response to */
  1557.     qbufp = querybuf;        /* a query that we sent, initialize */
  1558.     qbufn = 0;            /* the response buffer */
  1559.     querybuf[0] = NUL;
  1560.     }
  1561. #endif /* NOSPL */
  1562.     what = W_REMO;            /* we're doing a REMOTE command */
  1563. #ifdef IKSDB
  1564.     if (ikdbopen) slotstate(what,
  1565.               server ? "SERVER" : "",
  1566.               "RECEIVE",
  1567.               fspec
  1568.               );
  1569. #endif /* IKSDB */
  1570.     BEGIN rattr;            /* Expect Attribute packets */
  1571. }
  1572.     break;
  1573. case 55:
  1574.     {                /* Attribute packet */
  1575.     if (gattr(rdatap,&iattr) == 0) {    /* Read into attribute structure */
  1576. #ifdef CK_RESEND
  1577.     ack1((CHAR *)iattr.reply.val);    /* Reply with data */
  1578. #else
  1579.     ack();                /* If OK, acknowledge */
  1580. #endif /* CK_RESEND */
  1581.     } else {                /* Otherwise */
  1582.     extern long fsize;
  1583.     char *r;
  1584.     r = getreason(iattr.reply.val);
  1585.     ack1((CHAR *)iattr.reply.val);    /* refuse to accept the file */
  1586.     xxscreen(SCR_ST,ST_REFU,0L,r);    /* reason */
  1587. #ifdef TLOG
  1588.     if (tralog && !tlogfmt)
  1589.       doxlog(what,filnam,fsize,binary,1,r);
  1590. #endif /* TLOG */
  1591.     }
  1592. }
  1593.     break;
  1594. case 56:
  1595.     {                /* First data packet */
  1596.     debug(F100,"<rattr> D firstdata","",0);
  1597.     rc = rcv_firstdata();
  1598.     debug(F101,"rcv_firstdata rc","",rc);
  1599.     if (rc > -1) return(rc);        /* (see below) */
  1600. }
  1601.     break;
  1602. case 57:
  1603.     {                /* EOT, no more files */
  1604.     ack();                /* Acknowledge the B packet */
  1605.     reot();                /* Do EOT things */
  1606. #ifdef CK_TMPDIR
  1607. /* If we were cd'd temporarily to another device or directory ... */
  1608.     if (f_tmpdir) {
  1609.     int x;
  1610.     x = zchdir((char *) savdir);    /* ... restore previous directory */
  1611.     f_tmpdir = 0;            /* and remember we did it. */
  1612.     debug(F111,"ckcpro.w B tmpdir restoring",savdir,x);
  1613.     }
  1614. #endif /* CK_TMPDIR */
  1615.     RESUME;                /* and quit */
  1616. }
  1617.     break;
  1618. case 58:
  1619.     {                /* Got Data packet */
  1620.     debug(F101,"<rdpkt>D cxseen","",cxseen);
  1621.     debug(F101,"<rdpkt>D czseen","",czseen);
  1622.     if (cxseen || czseen || discard) {    /* If file or group interruption */
  1623.     CHAR * msg;
  1624.     msg = czseen ? (CHAR *)"Z" : (CHAR *)"X";
  1625. #ifdef STREAMING
  1626.     if (streaming) {        /* Need to cancel */
  1627.         debug(F111,"<rdpkt>D streaming cancel",msg,cancel);
  1628.         if (cancel++ == 0) {    /* Only do this once */
  1629.         ack1(msg);        /* Put "X" or "Z" in ACK */
  1630.         } else if (czseen) {
  1631.         errpkt((CHAR *)"User canceled");
  1632.         RESUME;
  1633.         } else {
  1634.         fastack();
  1635.         }
  1636.     } else
  1637. #endif /* STREAMING */
  1638.       ack1(msg);
  1639.     } else {                /* No interruption */
  1640.     int rc, qf;
  1641. #ifndef NOSPL
  1642.     qf = query;
  1643. #else
  1644.     qf = 0;
  1645. #endif /* NOSPL */
  1646. #ifdef CKTUNING
  1647.     rc = (binary && !parity) ?
  1648.       bdecode(rdatap,putfil):
  1649.         decode(rdatap, qf ? puttrm : putfil, 1);
  1650. #else
  1651.     rc = decode(rdatap, qf ? puttrm : putfil, 1);
  1652. #endif /* CKTUNING */
  1653.     if (rc < 0) {
  1654.         discard = (keep == 0 || (keep == SET_AUTO && binary != XYFT_T));
  1655.         errpkt((CHAR *)"Error writing data"); /* If failure, */
  1656.         RESUME;
  1657.     } else                /* Data written OK, send ACK */
  1658. #ifdef STREAMING
  1659.       if (streaming)
  1660.         fastack();
  1661.     else
  1662. #endif /* STREAMING */
  1663.       ack();
  1664.     }
  1665. }
  1666.     break;
  1667. case 59:
  1668.     {                /* EOF immediately after A-Packet. */
  1669.     rf_err = "Can't create file";
  1670.     timint = s_timint;
  1671.     if (discard) {            /* Discarding a real file... */
  1672.     x = 1;
  1673.     } else if (xflg) {            /* If screen data */
  1674.     if (remfile) {            /* redirected to file */
  1675.         if (rempipe)        /* or pipe */
  1676.           x = openc(ZOFILE,remdest); /* Pipe: start command */
  1677.         else
  1678.           x = opena(remdest,&iattr); /* File: open with attributes */
  1679.     } else {            /* otherwise */
  1680.         x = opent(&iattr);        /* "open" the screen */
  1681.     }
  1682. #ifdef CALIBRATE
  1683.     } else if (calibrate) {        /* If calibration run */
  1684.     x = ckopenx(&iattr);        /* do this */
  1685. #endif /* CALIBRATE */
  1686.     } else {                /* otherwise */
  1687.     x = opena(filnam,&iattr);    /* open the file, with attributes */
  1688.     if (x == -17) {            /* REGET skipped because same size */
  1689.         discard = 1;
  1690.         rejection = 1;
  1691.     }
  1692.     }
  1693.     if (!x || reof(filnam, &iattr) < 0) { /* Close output file */
  1694.     errpkt((CHAR *) rf_err);    /* If problem, send error msg */
  1695.     RESUME;                /* and quit */
  1696.     } else {                /* otherwise */
  1697.     if (x == -17)
  1698.       xxscreen(SCR_ST,ST_SKIP,SKP_RES,"");
  1699.     ack();                /* acknowledge the EOF packet */
  1700.     BEGIN rfile;            /* and await another file */
  1701.     }
  1702. }
  1703.     break;
  1704. case 60:
  1705.     {                  /* Ctrl-C or connection loss. */
  1706.     timint = s_timint;
  1707.     window(1);                /* Set window size back to 1... */
  1708.     cxseen = 1;
  1709.     x = clsof(1);            /* Close file */
  1710.     return(success = 0);        /* Failed */
  1711. }
  1712.     break;
  1713. case 61:
  1714.     {                /* End Of File (EOF) Packet */
  1715. /*  wslots = 1;    */            /* (don't set) Window size back to 1 */
  1716. #ifndef COHERENT /* Coherent compiler blows up on this switch() statement. */
  1717.     x = reof(filnam, &iattr);        /* Handle the EOF packet */
  1718.     switch (x) {            /* reof() sets the success flag */
  1719.       case -5:                /* Handle problems */
  1720.     errpkt((CHAR *)"RENAME failed"); /* Fatal */
  1721.     RESUME;
  1722.     break;
  1723.       case -4:
  1724.     errpkt((CHAR *)"MOVE failed");    /* Fatal */
  1725.     RESUME;
  1726.     break;
  1727.       case -3:                /* If problem, send error msg */
  1728.     errpkt((CHAR *)"Can't print file"); /* Fatal */
  1729.     RESUME;
  1730.     break;
  1731.       case -2:
  1732.     errpkt((CHAR *)"Can't mail file"); /* Fatal */
  1733.     RESUME;
  1734.     break;
  1735.       case 2:                /* Not fatal */
  1736.       case 3:
  1737.     xxscreen(SCR_EM,0,0L,"Receiver can't delete temp file");
  1738.     RESUME;
  1739.     break;
  1740.       default:
  1741.     if (x < 0) {            /* Fatal */
  1742.         errpkt((CHAR *)"Can't close file");
  1743.         RESUME;
  1744.     } else {            /* Success */
  1745. #ifndef NOSPL
  1746.         if (query)            /* Query reponses generally */
  1747.           conoll("");        /* don't have line terminators */
  1748. #endif /* NOSPL */
  1749.         if (czseen) {        /* Batch canceled? */
  1750.         if (cancel++ == 0) {    /* If we haven't tried this yet */
  1751.             ack1((CHAR *)"Z");    /* Try it once */
  1752.         } else {        /* Otherwise */
  1753.             errpkt((CHAR *)"User canceled"); /* quite with Error */
  1754.             RESUME;
  1755.         }
  1756.         } else
  1757.           ack();            /* Acknowledge the EOF packet */
  1758.         BEGIN rfile;        /* and await another file */
  1759.     }
  1760.     }
  1761. #else
  1762.     if (reof(filnam, &iattr) < 0) {    /* Close the file */
  1763.     errpkt((CHAR *)"Error at end of file");
  1764.     RESUME;
  1765.     } else {                /* reof() sets success flag */
  1766.     ack();
  1767.     BEGIN rfile;
  1768.     }
  1769. #endif /* COHERENT */
  1770. }
  1771.     break;
  1772. case 62:
  1773.     {                /* ACK for Send-Init */
  1774.     spar(rdatap);            /* set parameters from it */
  1775.     cancel = 0;
  1776.     bctu = bctr;            /* switch to agreed-upon block check */
  1777.     bctl = (bctu == 4) ? 2 : bctu;    /* Set block-check length */
  1778. #ifdef CK_RESEND
  1779.     if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */
  1780.     errpkt((CHAR *) "RESEND capabilities not negotiated");
  1781.     RESUME;
  1782.     } else {
  1783. #endif /* CK_RESEND */
  1784.     what = W_SEND;            /* Remember we're sending */
  1785.     lastxfer = W_SEND;
  1786.     x = sfile(xflg);        /* Send X or F header packet */
  1787.     cancel = 0;            /* Reset cancellation counter */
  1788.     if (x) {            /* If the packet was sent OK */
  1789.         if (!xflg && filcnt == 1)    /* and it's a real file */
  1790.           crc16 = 0L;        /* Clear the file CRC */
  1791.         resetc();            /* reset per-transaction counters */
  1792.         rtimer();            /* reset timers */
  1793. #ifdef GFTIMER
  1794.         rftimer();
  1795. #endif /* GFTIMER */
  1796.         streamon();            /* turn on streaming */
  1797. #ifdef IKSDB
  1798.         if (ikdbopen) slotstate(what,
  1799.                   (server ? "SERVER" : ""),
  1800.                   "SEND",
  1801.                   filnam
  1802.                   );
  1803. #endif /* IKSDB */
  1804.         BEGIN ssfile;        /* and switch to receive-file state */
  1805.     } else {            /* otherwise send error msg & quit */
  1806.         s = xflg ? "Can't execute command" : (char *)epktmsg;
  1807.         if (!*s) s = "Can't open file";
  1808.         errpkt((CHAR *)s);
  1809.         RESUME;
  1810.     }
  1811. #ifdef CK_RESEND
  1812.     }
  1813. #endif /* CK_RESEND */
  1814. }
  1815.     break;
  1816. case 63:
  1817.     {                /* R packet was retransmitted. */
  1818.     xsinit();                /* Resend packet 0 */
  1819. }
  1820.     break;
  1821. case 64:
  1822.     {                /* Same deal if G packet comes again */
  1823.     xsinit();
  1824. }
  1825.     break;
  1826. case 65:
  1827.     {                /* Same deal if C packet comes again */
  1828.     xsinit();
  1829. }
  1830.     break;
  1831. case 66:
  1832.     {                /* ACK for F or X packet */
  1833.     srvptr = srvcmd;            /* Point to string buffer */
  1834.     decode(rdatap,putsrv,0);        /* Decode data field, if any */
  1835.     putsrv(NUL);            /* Terminate with null */
  1836.     ffc = 0L;                /* Reset file byte counter */
  1837.     debug(F101,"<ssfile>Y cxseen","",cxseen);
  1838.     if (*srvcmd) {            /* If remote name was recorded */
  1839.         if (sendmode != SM_RESEND) {
  1840.         if (fdispla == XYFD_C || fdispla == XYFD_S)
  1841.           xxscreen(SCR_AN,0,0L,(char *)srvcmd);
  1842.         tlog(F110," remote name:",(char *) srvcmd,0L);
  1843.         makestr(&psrfspec,(char *)srvcmd);
  1844.         }
  1845.     }
  1846.     if (cxseen||czseen) {        /* Interrupted? */
  1847.     debug(F101,"<ssfile>Y canceling","",0);
  1848.     x = clsif();            /* Close input file */
  1849.     sxeof(1);            /* Send EOF(D) */
  1850.     BEGIN sseof;            /* and switch to EOF state. */
  1851.     } else if (atcapu) {        /* If attributes are to be used */
  1852.     if (sattr(xflg | stdinf, 1) < 0) { /* send them */
  1853.         errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */
  1854.         RESUME;            /* and quit */
  1855.     } else BEGIN ssattr;        /* if ok, switch to attribute state */
  1856.     } else {                /* Attributes not negotiated */
  1857.     if (window(wslotn) < 0) {    /* Open window */
  1858.         errpkt((CHAR *)"Can't open window");
  1859.         RESUME;
  1860.     } else if ((x = sdata()) == -2) { /* Send first data packet data */
  1861.         window(1);            /* Connection lost, reset window */
  1862.         x = clsif();        /* Close input file */
  1863.         return(success = 0);    /* Return failure */
  1864.     } else if (x == -9) {        /* User interrupted */
  1865.         errpkt((CHAR *)"User cancelled"); /* Send Error packet */
  1866.         window(1);            /* Set window size back to 1... */
  1867.         timint = s_timint;        /* Restore timeout */
  1868.         return(success = 0);    /* Failed */
  1869.     } else if (x < 0) {        /* EOF (empty file) or interrupted */
  1870.         window(1);            /* put window size back to 1, */
  1871.         debug(F101,"<ssfile>Y cxseen","",cxseen);
  1872.         x = clsif();        /* If not ok, close input file, */
  1873.         if (x < 0)            /* treating failure as interruption */
  1874.           cxseen = 1;        /* Send EOF packet */
  1875.         seof(cxseen||czseen);
  1876.         BEGIN sseof;        /* and switch to EOF state. */
  1877.     } else {            /* First data sent OK */
  1878.         BEGIN ssdata;        /* All ok, switch to send-data state */
  1879.     }
  1880.     }
  1881. }
  1882.     break;
  1883. case 67:
  1884.     {                /* Got ACK to A packet */
  1885.     ffc = 0L;                /* Reset file byte counter */
  1886.     debug(F101,"<ssattr>Y cxseen","",cxseen);
  1887.     if (cxseen||czseen) {        /* Interrupted? */
  1888.     debug(F101,"<sattr>Y canceling","",0);
  1889.     x = clsif();            /* Close input file */
  1890.     sxeof(1);            /* Send EOF(D) */
  1891.     BEGIN sseof;            /* and switch to EOF state. */
  1892.     } else if (rsattr(rdatap) < 0) {    /* Was the file refused? */
  1893.     discard = 1;            /* Set the discard flag */
  1894.     clsif();            /* Close the file */
  1895.     sxeof(1);            /* send EOF with "discard" code */
  1896.     BEGIN sseof;            /* switch to send-EOF state */
  1897.     } else if ((x = sattr(xflg | stdinf, 0)) < 0) { /* Send more? */
  1898.     errpkt((CHAR *)"Can't send attributes"); /* Trouble... */
  1899.     RESUME;
  1900.     } else if (x == 0) {        /* No more to send so now the data */
  1901.     if (window(wslotn) < 0) {    /* Allocate negotiated window slots */
  1902.         errpkt((CHAR *)"Can't open window");
  1903.         RESUME;
  1904.     }
  1905.     if ((x = sdata()) == -2) {    /* File accepted, send first data */
  1906.         window(1);            /* Connection broken */
  1907.         x = clsif();        /* Close file */
  1908.         return(success = 0);    /* Return failure */
  1909.     } else if (x == -9) {        /* User interrupted */
  1910.         errpkt((CHAR *)"User cancelled"); /* Send Error packet */
  1911.         window(1);            /* Set window size back to 1... */
  1912.         timint = s_timint;        /* Restore timeout */
  1913.         return(success = 0);    /* Failed */
  1914.     } else if (x < 0) {        /* If data was not sent */
  1915.         window(1);            /* put window size back to 1, */
  1916.         debug(F101,"<ssattr>Y cxseen","",cxseen);
  1917.         if (clsif() < 0)        /* Close input file */
  1918.           cxseen = 1;        /* Send EOF packet */
  1919.         seof(cxseen||czseen);
  1920.         BEGIN sseof;        /* and switch to EOF state. */
  1921.     } else {
  1922.         BEGIN ssdata;        /* All ok, switch to send-data state */
  1923.     }
  1924.     }
  1925. }
  1926.     break;
  1927. case 68:
  1928.     {                  /* Ctrl-C or connection loss. */
  1929.     window(1);                /* Set window size back to 1... */
  1930.     cxseen = 1;                /* To indicate interruption */
  1931.     x = clsif();            /* Close file */
  1932.     return(success = 0);        /* Failed */
  1933. }
  1934.     break;
  1935. case 69:
  1936.     {                /* Got ACK to Data packet */
  1937.     canned(rdatap);            /* Check if file transfer cancelled */
  1938.     debug(F111,"<ssdata>Y cxseen",rdatap,cxseen);
  1939.     debug(F111,"<ssdata>Y czseen",rdatap,czseen);
  1940.     if ((x = sdata()) == -2) {        /* Try to send next data */
  1941.     window(1);            /* Connection lost, reset window */
  1942.     x = clsif();            /* Close file */
  1943.     return(success = 0);        /* Failed */
  1944.     } else if (x == -9) {        /* User interrupted */
  1945.     errpkt((CHAR *)"User cancelled"); /* Send Error packet */
  1946.     window(1);            /* Set window size back to 1... */
  1947.     timint = s_timint;        /* Restore original timeout */
  1948.     return(success = 0);        /* Failed */
  1949.     } else if (x < 0) {            /* EOF - finished sending data */
  1950.     debug(F101,"<ssdata>Y cxseen","",cxseen);
  1951.     window(1);            /* Set window size back to 1... */
  1952.     if (clsif() < 0)        /* Close input file */
  1953.       cxseen = 1;            /* Send EOF packet */
  1954.     debug(F101,"<ssdata>Y CALLING SEOF()","",cxseen);
  1955.     seof(cxseen||czseen);
  1956.     BEGIN sseof;            /* and enter send-eof state */
  1957.     }
  1958.     /* NOTE: If x == 0 it means we're draining: see sdata()! */
  1959. }
  1960.     break;
  1961. case 70:
  1962.     {                /* Got ACK to EOF */
  1963.     int g, xdiscard;
  1964.     canned(rdatap);            /* Check if file transfer cancelled */
  1965.     debug(F111,"<sseof>Y cxseen",rdatap,cxseen);
  1966.     debug(F111,"<sseof>Y czseen",rdatap,czseen);
  1967.     debug(F111,"<sseof>Y discard",rdatap,discard);
  1968.     xdiscard = discard;
  1969.     discard = 0;
  1970.     success = (cxseen == 0 && czseen == 0); /* Transfer status... */
  1971.     debug(F101,"<sseof>Y success","",success);
  1972.     if (success && rejection > 0)        /* If rejected, succeed if */
  1973.       if (rejection != '#' &&            /* reason was date */
  1974.       rejection != 1 && rejection != '?') /* or name; */
  1975.     success = 0;                /* fail otherwise. */
  1976.     cxseen = 0;                /* This goes back to zero. */
  1977.     if (success) {            /* Only if transfer succeeded... */
  1978.     xxscreen(SCR_ST,ST_OK,0L,"");
  1979.     if (!xdiscard) {
  1980.         makestr(&sfspec,psfspec);    /* Record filenames for WHERE */
  1981.         makestr(&srfspec,psrfspec);
  1982.     }
  1983.     if (moving) {            /* If MOVE'ing */
  1984.         x = zdelet(filnam);        /* Try to delete the source file */
  1985. #ifdef TLOG
  1986.         if (tralog) {
  1987.         if (x > -1) {
  1988.             tlog(F110," deleted",filnam,0);
  1989.         } else {
  1990.             tlog(F110," delete failed:",ck_errstr(),0);
  1991.         }
  1992.         }
  1993. #endif /* TLOG */
  1994.     } else if (snd_move) {        /* Or move it */
  1995.         int x;
  1996.         x = zrename(filnam,snd_move);
  1997. #ifdef TLOG
  1998.         if (tralog) {
  1999.         if (x > -1) {
  2000.             tlog(F110," moved to ",snd_move,0);
  2001.         } else {
  2002.             tlog(F110," move failed:",ck_errstr(),0);
  2003.         }
  2004.         }
  2005. #endif /* TLOG */
  2006.     } else if (snd_rename) {    /* Or rename it */
  2007.         char *s = snd_rename;    /* Renaming string */
  2008. #ifndef NOSPL
  2009.         int y;            /* Pass it thru the evaluator */
  2010.         extern int cmd_quoting;    /* for \v(filename) */
  2011.         if (cmd_quoting) {        /* But only if cmd_quoting is on */
  2012.         y = MAXRP;
  2013.         s = (char *)srvcmd;
  2014.         zzstring(snd_rename,&s,&y);
  2015.         s = (char *)srvcmd;
  2016.         }
  2017. #endif /* NOSPL */
  2018.         if (s) if (*s) {
  2019.         int x;
  2020.         x = zrename(filnam,s);
  2021. #ifdef TLOG
  2022.         if (tralog) {
  2023.         if (x > -1) {
  2024.             tlog(F110," renamed to",s,0);
  2025.         } else {
  2026.             tlog(F110," rename failed:",ck_errstr(),0);
  2027.         }
  2028.         }
  2029. #endif /* TLOG */
  2030. #ifdef COMMENT
  2031.         *s = NUL;
  2032. #endif /* COMMENT */
  2033.         }
  2034.     }
  2035.     }
  2036.     if (czseen) {            /* Check group interruption flag */
  2037.     g = 0;                /* No more files if interrupted */
  2038.     } else {                /* Otherwise... */
  2039. #ifdef COMMENT
  2040.     /* This code makes any open error fatal to a file-group transfer. */
  2041.     g = gnfile();
  2042.     debug(F111,"<sseof>Y gnfile",filnam,g);
  2043.     if (g > 0) {            /* Any more files to send? */
  2044.         if (sfile(xflg))        /* Yes, try to send next file header */
  2045.           BEGIN ssfile;        /* if ok, enter send-file state */
  2046.         else {            /* otherwise */
  2047.         s = xflg ? "Can't execute command" : (char *)epktmsg;
  2048.         if (!*s) s = "Can't open file";
  2049.         errpkt((CHAR *)s);    /* send error message */
  2050.         RESUME;            /* and quit */
  2051.         }
  2052.     } else {            /* No next file */
  2053.         tsecs = gtimer();        /* get statistics timers */
  2054. #ifdef GFTIMER
  2055.         fptsecs = gftimer();
  2056. #endif /* GFTIMER */
  2057.         seot();            /* send EOT packet */
  2058.         BEGIN sseot;        /* enter send-eot state */
  2059.     }
  2060. #else  /* COMMENT */
  2061.     while (1) {            /* Keep trying... */
  2062.         g = gnfile();        /* Get next file */
  2063.         debug(F111,"<sseof>Y gnfile",filnam,g);
  2064.         if (g == 0 && gnferror == 0) /* No more, stop trying */
  2065.           break;
  2066.         if (g > 0) {        /* Have one */
  2067.         if (sfile(xflg)) {    /* Try to open and send F packet */
  2068.             BEGIN ssfile;    /* If OK, enter send-file state */
  2069.             break;        /* and break out of loop. */
  2070.         }
  2071.         } /* Otherwise keep trying to get one we can send... */
  2072.     }
  2073.     }
  2074.     if (g == 0) {
  2075.     debug(F101,"<sseof>Y no more files","",czseen);
  2076.     tsecs = gtimer();        /* Get statistics timers */
  2077. #ifdef GFTIMER
  2078.     fptsecs = gftimer();
  2079. #endif /* GFTIMER */
  2080.     seot();                /* Send EOT packet */
  2081.     BEGIN sseot;            /* Enter send-eot state */
  2082.     }
  2083. #endif /* COMMENT */
  2084. }
  2085.     break;
  2086. case 71:
  2087.     {                /* Got ACK to EOT */
  2088.     debug(F101,"sseot justone","",justone);
  2089.     RESUME;                /* All done, just quit */
  2090. }
  2091.     break;
  2092. case 72:
  2093.     {                    /* Got Error packet, in any state */
  2094.     char *s = "";
  2095.     window(1);                /* Close window */
  2096.     timint = s_timint;            /* Restore original timeout */
  2097.     if (*epktmsg)            /* Message from Error packet */
  2098.       s = (char *)epktmsg;
  2099.     if (!*s) {                /* If not there then maybe here */
  2100.     s = (char *)rdatap;
  2101.     ckstrncpy((char *)epktmsg,(char *)rdatap,PKTMSGLEN);
  2102.     }
  2103.     if (!*s)                /* Hopefully we'll never see this. */
  2104.       s = "Unknown error";
  2105.     success = 0;            /* For IF SUCCESS/FAIL. */
  2106.     debug(F101,"ckcpro.w justone at E pkt","",justone);
  2107.  
  2108.     success = 0;            /* Transfer failed */
  2109.     xferstat = success;            /* Remember transfer status */
  2110.     if (!epktsent) {
  2111.     x = quiet; quiet = 1;        /* Close files silently, */
  2112.     epktrcvd = 1;            /* Prevent messages from clsof() */
  2113.     clsif();
  2114.     clsof(1);             /* discarding any output file. */
  2115.     ermsg(s);            /* Issue the message (calls screen). */
  2116.     quiet = x;            /* Restore quiet state */
  2117.     }
  2118.     tstats();                /* Get stats */
  2119. /*
  2120.   If we are executing commands from a command file or macro, let the command
  2121.   file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR.
  2122. */
  2123.     if (
  2124. #ifndef NOICP
  2125.     !xcmdsrc &&
  2126. #endif /* NOICP */
  2127.     backgrd && !server)
  2128.       fatal("Protocol error");
  2129.     xitsta |= (what & W_KERMIT);    /* Save this for doexit(). */
  2130. #ifdef CK_TMPDIR
  2131. /* If we were cd'd temporarily to another device or directory ... */
  2132.     if (f_tmpdir) {
  2133.     int x;
  2134.     x = zchdir((char *) savdir);    /* ... restore previous directory */
  2135.     f_tmpdir = 0;            /* and remember we did it. */
  2136.     debug(F111,"ckcpro.w E tmpdir restored",savdir,x);
  2137.     }
  2138. #endif /* CK_TMPDIR */
  2139. #ifdef IKSDB
  2140.     if (ikdbopen) slotstate(what,"ERROR", (char *)epktmsg, "");
  2141. #endif /* IKSDB */
  2142.     RESUME;
  2143. }
  2144.     break;
  2145. case 73:
  2146.     { success = 0; QUIT; }
  2147.     break;
  2148. case 74:
  2149.     {                    /* Anything not accounted for above */
  2150.     errpkt((CHAR *)"Unexpected packet type"); /* Give error message */
  2151.     window(1);
  2152.     xitsta |= (what & W_KERMIT);    /* Save this for doexit(). */
  2153.     RESUME;                /* and quit */
  2154. }
  2155.     break;
  2156.  
  2157.         }
  2158.     }
  2159. }
  2160.  
  2161. char tbl[] = {
  2162.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2163.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2164.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2165.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2166.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2167.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2168.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2169.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2170.  74, 74, 74, 74, 74, 15, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2171.  74, 74, 74, 74, 74, 74, 74, 74, 74, 13, 74, 74, 74, 74, 74, 74,
  2172.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2173.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2174.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2175.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2176.  74, 74, 57, 74, 74, 72, 53, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2177.  74, 74, 74, 74, 74, 74, 74, 74, 54, 74, 74, 74, 74, 74, 74, 74,
  2178.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2179.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2180.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2181.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2182.  74, 55, 74, 74, 56, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2183.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 59, 74, 74, 74, 74, 74,
  2184.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2185.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2186.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2187.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2188.  74, 74, 74, 74, 58, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2189.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 61, 74, 74, 74, 74, 74,
  2190.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2191.  74, 60,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2192.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2193.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2194.  74, 74, 74, 65, 74, 72, 74, 64, 74, 74, 74, 74, 74, 74, 74, 74,
  2195.  74, 74, 63, 74, 74, 74, 74, 74, 74, 62, 74, 74, 74, 74, 74, 74,
  2196.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2197.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2198.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2199.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2200.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2201.  74, 74, 74, 74, 74, 74, 74, 74, 74, 66, 74, 74, 74, 74, 74, 74,
  2202.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2203.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2204.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2205.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2206.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2207.  74, 74, 74, 74, 74, 74, 74, 74, 74, 67, 74, 74, 74, 74, 74, 74,
  2208.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2209.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2210.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2211.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2212.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2213.  74, 74, 74, 74, 74, 74, 74, 74, 74, 69, 74, 74, 74, 74, 74, 74,
  2214.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2215.  74, 68,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2216.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2217.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2218.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2219.  74, 74, 74, 74, 74, 74, 74, 74, 74, 70, 74, 74, 74, 74, 74, 74,
  2220.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2221.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2222.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2223.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2224.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2225.  74, 74, 74, 74, 74, 74, 74, 74, 74, 71, 74, 74, 74, 74, 74, 74,
  2226.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2227.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2228.  -1, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
  2229.  29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
  2230.  29, 29, 29, 26, 29, 29, 29, 25, 19, 17, 22, 29, 29, 29, 28, 23,
  2231.  29, 29, 18, 12, 29, 29, 20, 21, 29, 29, 29, 29, 29, 29, 29, 29,
  2232.  29, 11, 29,  7, 29, 29, 29,  9,  4, 29,  5,  8, 29, 29, 29,  6,
  2233.  29, 27,  3,  1, 29, 29,  2, 29, 10, 29, 29, 29, 29, 29, 29, 29,
  2234.  -1, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
  2235.  50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,
  2236.  50, 32, 50, 31, 33, 34, 35, 50, 38, 30, 50, 40, 37, 48, 50, 50,
  2237.  50, 50, 39, 41, 42, 45, 47, 46, 36, 50, 50, 50, 50, 50, 50, 50,
  2238.  50, 11, 50,  7, 44, 50, 50,  9,  4, 50,  5,  8, 50, 43, 50,  6,
  2239.  50, 49,  3,  1, 50, 50,  2, 50, 10, 50, 50, 50, 50, 50, 50, 50,
  2240.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2241.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2242.  74, 74, 74, 74, 74, 72, 74, 74, 74, 17, 74, 74, 74, 74, 74, 74,
  2243.  74, 74, 74, 12, 74, 74, 74, 74, 74, 16, 74, 74, 74, 74, 74, 74,
  2244.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2245.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2246.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2247.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2248.  74, 74, 74, 74, 74, 72, 53, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2249.  74, 74, 74, 12, 74, 74, 74, 74, 54, 52, 74, 74, 74, 74, 74, 74,
  2250.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2251.  74, 51,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2252.  -1, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2253.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2254.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2255.  74, 74, 74, 74, 74, 74, 74, 74, 74, 14, 74, 74, 74, 74, 74, 74,
  2256.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2257.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74, 74,
  2258.   0, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2259.  74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2260.  74, 74, 74, 74, 74, 72, 74, 74, 74, 74, 74, 74, 74, 74, 74, 24,
  2261.  74, 74, 74, 12, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74,
  2262.  74, 11, 74,  7, 74, 74, 74,  9,  4, 74,  5,  8, 74, 74, 74,  6,
  2263.  74, 73,  3,  1, 74, 74,  2, 74, 10, 74, 74, 74, 74, 74, 74,74
  2264. };
  2265.  
  2266.  
  2267. /*
  2268.   From here down to proto() are routines that were moved out of the state
  2269.   table switcher because the resulting switch() had become too large.
  2270.   To move the contents of a state-table case to a routine:
  2271.     1. Add a prototype to the list above the state table switcher.
  2272.     2. Make a routine with an appropriate name, returning int.
  2273.     3. Move the code into it.
  2274.     4. Put a call to the new routine in the former spot:
  2275.          rc = name_of_routine();
  2276.          if (rc > -1) return(rc);
  2277.     5. Add "return(-1);" after every RESUME, SERVE, or BEGIN macro and
  2278.        at the end if the code is open-ended.
  2279. */
  2280. static int
  2281. rcv_firstdata() {
  2282.     extern int dispos;
  2283.     debug(F101,"rcv_firstdata","",dispos);
  2284.  
  2285.     if (discard) {            /* if we're discarding the file */
  2286.     ack1((CHAR *)"X");        /* just ack the data like this. */
  2287.     cancel++;            /* and count it */
  2288.     BEGIN rdpkt;            /* and wait for more data packets. */
  2289.     return(-1);
  2290.     } else {                /* Not discarding. */
  2291.     rf_err = "Can't open file";
  2292.     if (xflg) {            /* If screen data */
  2293.         if (remfile) {        /* redirected to file */
  2294.         if (rempipe)        /* or pipe */
  2295.           x = openc(ZOFILE,remdest); /* Pipe: start command */
  2296.         else
  2297.           x = opena(remdest,&iattr); /* File: open with attributes */
  2298.         } else {            /* otherwise */
  2299.         x = opent(&iattr);    /* "open" the screen */
  2300.         }
  2301.     } else {            /* otherwise */
  2302. #ifdef CALIBRATE
  2303.         if (calibrate) {        /* If calibration run */
  2304.         x = ckopenx(&iattr);    /* open nothing */
  2305. #ifdef STREAMING
  2306.         if (streaming)        /* Streaming */
  2307.           fastack();        /* ACK without ACKing. */
  2308.         else
  2309. #endif /* STREAMING */
  2310.           ack();        /* Send real ACK */
  2311.         BEGIN rdpkt;        /* Proceed to next state */
  2312.         return(-1);
  2313.         } else
  2314. #endif /* CALIBRATE */
  2315. #ifdef UNIX
  2316. /*
  2317.   In UNIX we can pipe the file data into the mail program, which is to be
  2318.   preferred to writing it out to a temp file and then mailing it afterwards.
  2319.   This depends rather heavily on all UNIXes having a mail command that
  2320.   accepts '-s "subject"' on the command line.  MAILCMD (e.g. mail, Mail, mailx)
  2321.   is defined in ckufio.c.
  2322. */
  2323.         if (dispos == 'M') {    /* Mail... */
  2324.         char *s;
  2325.         char * tmp = NULL;
  2326.         int n = 0;
  2327.         extern char *MAILCMD;
  2328.         s = iattr.disp.val + 1;
  2329.         n = (int)strlen(MAILCMD) +    /* Mail command */
  2330.           (int)strlen(s) +          /* address */
  2331.           (int)strlen(ofilnam) + 32;  /* subject */
  2332.         if (tmp = (char *)malloc(n)) {
  2333.             ckmakxmsg(tmp,n,
  2334.                   MAILCMD," -s \"",ofilnam,"\" ",s,
  2335.                   NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  2336.             debug(F111,"rcv_firsdata mail",tmp,(int)strlen(tmp));
  2337.             x = openc(ZOFILE,(char *)tmp);
  2338.             free(tmp);
  2339.         } else
  2340.           x = 0;
  2341.         } else if (dispos == 'P') { /* Ditto for print */
  2342.         char * tmp = NULL;
  2343.         int n;
  2344.         extern char *PRINTCMD;
  2345.         n = (int)strlen(PRINTCMD) + (int)strlen(iattr.disp.val+1) + 4;
  2346.         if (tmp = (char *)malloc(n)) {
  2347.             sprintf(tmp,    /* safe (prechecked) */
  2348.                 "%s %s", PRINTCMD, iattr.disp.val + 1);
  2349.             x = openc(ZOFILE,(char *)tmp);
  2350.             free(tmp);
  2351.         } else
  2352.           x = 0;
  2353.         } else
  2354. #endif /* UNIX */
  2355.           x = opena(filnam,&iattr);    /* open the file, with attributes */
  2356.     }
  2357.     if (x) {            /* If file was opened ok */
  2358.         int rc, qf;
  2359. #ifndef NOSPL
  2360.         qf = query;
  2361. #else
  2362.         qf = 0;
  2363. #endif /* NOSPL */
  2364.  
  2365. #ifdef CKTUNING
  2366.         rc = (binary && !parity) ?
  2367.           bdecode(rdatap,putfil):
  2368.            decode(rdatap, qf ? puttrm : putfil, 1);
  2369. #else
  2370.         rc = decode(rdatap, qf ? puttrm : putfil, 1);
  2371. #endif /* CKTUNING */
  2372.         if (rc < 0) {
  2373.         errpkt((CHAR *)"Error writing data");
  2374.         RESUME;
  2375.         return(-1);
  2376.         }
  2377. #ifdef STREAMING
  2378.         if (streaming)        /* Streaming was negotiated */
  2379.           fastack();        /* ACK without ACKing. */
  2380.         else
  2381. #endif /* STREAMING */
  2382.           ack();            /* acknowledge it */
  2383.         BEGIN rdpkt;        /* and switch to receive-data state */
  2384.         return(-1);
  2385.     } else {            /* otherwise */
  2386.         errpkt((CHAR *) rf_err);    /* send error packet */
  2387.             RESUME;            /* and quit. */
  2388.         return(-1);
  2389.     }
  2390.     }
  2391. }
  2392.  
  2393. static int
  2394. rcv_shortreply() {
  2395. #ifdef PKTZEROHACK
  2396.     success = 0;
  2397.     debug(F111,"rcv_shortreply",rdatap,ipktlen);
  2398.     if (ipktack[0] && !strncmp(ipktack,(char *)rdatap,ipktlen)) {
  2399.     /* No it's the ACK to the I packet again */
  2400.     x = scmd(vcmd,(CHAR *)cmarg);    /* So send the REMOTE command again */
  2401.     /* Maybe this should be resend() */
  2402.     debug(F110,"IPKTZEROHACK",ipktack,x);
  2403.     if (x < 0) {
  2404.         errpkt((CHAR *)srimsg);
  2405.         RESUME;
  2406.         return(-1);
  2407.     }
  2408.     } else {
  2409.     ipktack[0] = NUL;
  2410. #endif /* PKTZEROHACK */
  2411.     urserver = 1;
  2412. #ifndef NOSERVER
  2413. #ifndef NOSPL
  2414.     if (query) {            /* If to query, */
  2415.         qbufp = querybuf;        /*  initialize query response buffer */
  2416.         qbufn = 0;
  2417.         querybuf[0] = NUL;
  2418.     }
  2419. #endif /* NOSPL */
  2420.     x = 1;
  2421.     if (remfile) {            /* Response redirected to file */
  2422.         rf_err = "Can't open file";
  2423.         if (rempipe)        /* or pipe */
  2424.           x =
  2425. #ifndef NOPUSH
  2426.         zxcmd(ZOFILE,remdest)    /* Pipe: Start command */
  2427. #else
  2428.         0
  2429. #endif /* NOPUSH */
  2430.         ;
  2431.         else
  2432.           x = opena(remdest,&iattr); /* File: Open with attributes */
  2433.         debug(F111,"rcv_shortreply remfile",remdest,x);
  2434.     } else {
  2435.         x = opent(&iattr);        /* "open" the screen */
  2436.     }
  2437.     if (x) {            /* If file was opened ok */
  2438.         if (decode(rdatap,
  2439. #ifndef NOSPL
  2440.                (query || !remfile) ? puttrm :
  2441. #else
  2442.                !remfile ? puttrm :
  2443. #endif /* NOSPL */
  2444.                zputfil, 1) < 0) { /* Note: zputfil, not putfil. */
  2445.         errpkt((CHAR *)"Error writing data");
  2446.         RESUME;
  2447.         return(-1);
  2448.         } else {
  2449.         if (rdatap)        /* If we had data */
  2450.           if (*rdatap)        /* add a line terminator */
  2451.             if (remfile) {    /* to file */
  2452.             zsoutl(ZOFILE,"");
  2453.             } else {        /* or to screen. */
  2454. #ifndef NOICP
  2455.             if (!query || !xcmdsrc)
  2456. #endif /* NOICP */
  2457.               if (!(quiet && rcdactive))
  2458.                 conoll("");
  2459.             }
  2460.         if (bye_active && network) { /* I sent BYE or REMOTE LOGOUT */
  2461.             msleep(500);    /* command and got the ACK... */
  2462.             bye_active = 0;
  2463.             ttclos(0);
  2464.         }
  2465.         clsof(0);
  2466.         if (!epktsent && !epktrcvd) /* If no error packet... */
  2467.           success = 1;        /* success. */
  2468.         RESUME;
  2469.         return(-1);
  2470.         }
  2471.     } else {            /* File not opened OK */
  2472.         errpkt((CHAR *) rf_err);    /* send error message */
  2473.         RESUME;            /* and quit. */
  2474.         return(-1);
  2475.     }
  2476. #endif /* NOSERVER */
  2477. #ifdef PKTZEROHACK
  2478.     }
  2479. #endif /* PKTZEROHACK */
  2480.     debug(F101,"rcv_shortreply fallthru","",success);
  2481.     return(-1);
  2482. }
  2483.  
  2484.  
  2485. static int
  2486. srv_query() {
  2487. #ifndef NOSERVER
  2488. #ifndef NOSPL
  2489.     char c;
  2490. #ifdef CKSYSLOG
  2491.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2492.       cksyslog(SYSLG_PR, 1, "server", "REMOTE QUERY", (char *)srvcmd);
  2493. #endif /* CKSYSLOG */
  2494. #ifdef IKSDB
  2495.     if (ikdbopen) slotstate(what,"REMOTE QUERY", (char *)(srvcmd+2), "");
  2496. #endif /* IKSDB */
  2497.     c = *(srvcmd+2);            /* Q = Query, S = Set */
  2498.     if (c == 'Q') {            /* Query */
  2499.     if (!ENABLED(en_que)) { /* Security */
  2500.         errpkt((CHAR *)"REMOTE QUERY disabled");
  2501.         RESUME;
  2502.         return(-1);
  2503.     } else {            /* Query allowed */
  2504.         int n; char *p, *q;
  2505.         qbufp = querybuf;        /* Wipe out old stuff */
  2506.         qbufn = 0;
  2507.         querybuf[0] = NUL;
  2508.         p = (char *) srvcmd + 3;    /* Pointer for making wrapper */
  2509.         n = strlen((char *)srvcmd);    /* Position of end */
  2510.         c = *(srvcmd+4);        /* Which type of variable */
  2511.  
  2512.         if (*(srvcmd+6) == CMDQ) {    /* Starts with command quote? */
  2513.         p = (char *) srvcmd + 6; /* Take it literally */
  2514.         if (*p == CMDQ) p++;
  2515.         } else {            /* They played by the rules */
  2516.         if (c == 'K') {        /* Kermit variable */
  2517.             int k;
  2518.             k = (int) strlen(p);
  2519.             if (k > 0 && p[k-1] == ')') {
  2520.             p = (char *)(srvcmd + 4);
  2521.             *(srvcmd+4) = CMDQ;
  2522.             *(srvcmd+5) = 'f'; /* Function, so make it \f...() */
  2523.             } else {
  2524.             *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
  2525.             *(srvcmd+4) = 'v';  /* Variable, so make it \v(...) */
  2526.             *(srvcmd+5) = '(';  /* around variable name */
  2527.             *(srvcmd+n) = ')';
  2528.             *(srvcmd+n+1) = NUL;
  2529.             }
  2530.         } else {
  2531.             *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
  2532.             *(srvcmd+4) = 'v'; /*  Variable, so make it \v(...) */
  2533.             *(srvcmd+5) = '(';    /* around variable name */
  2534.             *(srvcmd+n) = ')';
  2535.             *(srvcmd+n+1) = NUL;
  2536.             if (c == 'S') {    /* System variable */
  2537.             *(srvcmd+4) = '$'; /*  so it's \$(...) */
  2538.             } else if (c == 'G') { /* Non-\ Global variable */
  2539.             *(srvcmd+4) = 'm'; /*  so wrap it in \m(...) */
  2540.             }
  2541.         }
  2542.         }                /* Now evaluate it */
  2543.         n = QBUFL;            /* Max length */
  2544.         q = querybuf;        /* Where to put it */
  2545.         if (zzstring(p,&q,&n) < 0) {
  2546.         errpkt((n > 0) ? (CHAR *)"Can't get value"
  2547.                        : (CHAR *)"Value too long"
  2548.                );
  2549.         RESUME;
  2550.         return(-1);
  2551.         } else {
  2552.         if (encstr((CHAR *)querybuf) > -1) { /* Encode it */
  2553.             ack1(data);        /* If it fits, send it back in ACK */
  2554.             success = 1;
  2555.             RESUME;
  2556.             return(-1);
  2557.         } else if (sndstring(querybuf)) { /* Long form response */
  2558.             BEGIN ssinit;
  2559.             return(-1);
  2560.         } else {        /* sndhlp() fails */
  2561.             errpkt((CHAR *)"Can't send value");
  2562.             RESUME;
  2563.             return(-1);
  2564.         }
  2565.         }
  2566.     }
  2567.     } else if (c == 'S') {        /* Set (assign) */
  2568.     if (!ENABLED(en_asg)) {        /* Security */
  2569.         errpkt((CHAR *)"REMOTE ASSIGN disabled");
  2570.         RESUME;
  2571.         return(-1);
  2572.     } else {            /* OK */
  2573.         int n;
  2574.         n = xunchar(*(srvcmd+3));    /* Length of name */
  2575.         n = 3 + n + 1;        /* Position of length of value */
  2576.         *(srvcmd+n) = NUL;        /* Don't need it */
  2577.         if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0)
  2578.           errpkt((CHAR *)"REMOTE ASSIGN failed");
  2579.         else {
  2580.         ack();
  2581.         success = 1;
  2582.         }
  2583.         RESUME;
  2584.         return(-1);
  2585.     }
  2586.     } else {
  2587.     errpkt((CHAR *)"Badly formed server command");
  2588.     RESUME;
  2589.     return(-1);
  2590.     }
  2591. #else
  2592.     errpkt((CHAR *)"Variable query/set not available");
  2593.     RESUME;
  2594.     return(-1);
  2595. #endif /* NOSPL */
  2596. #endif /* NOSERVER */
  2597. }
  2598.  
  2599. static int
  2600. srv_copy() {
  2601. #ifndef NOSERVER
  2602. #ifdef CKSYSLOG
  2603.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2604.       cksyslog(SYSLG_PR, 1, "server", "REMOTE COPY", (char *)srvcmd);
  2605. #endif /* CKSYSLOG */
  2606. #ifdef ZCOPY
  2607.     if (!ENABLED(en_cpy)) {
  2608.     errpkt((CHAR *)"REMOTE COPY disabled");
  2609.     RESUME;
  2610.     return(-1);
  2611.     } else {
  2612.     char *str1, *str2, f1[256], f2[256];
  2613.     int  len1, len2;
  2614.         len1 = xunchar(srvcmd[1]);    /* Separate the parameters */
  2615.         len2 = xunchar(srvcmd[2+len1]);
  2616.         strncpy(f1,(char *)(srvcmd+2),len1);
  2617.         f1[len1] = NUL;
  2618.         strncpy(f2,(char *)(srvcmd+3+len1),len2);
  2619.         f2[len2] = NUL;
  2620. #ifdef IKSDB
  2621.     if (ikdbopen) slotstate(what,"REMOTE COPY", f1, f2);
  2622. #endif /* IKSDB */
  2623.     if (!ENABLED(en_cwd)) {        /* If CWD is disabled */
  2624.         zstrip(f1,&str1);        /* and they included a pathname, */
  2625.             zstrip(f2,&str2);
  2626.         if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */
  2627.         errpkt((CHAR *)"Access denied");
  2628.         RESUME;            /* Remember, this is not a goto! */
  2629.         return(-1);
  2630.         }
  2631.     }
  2632.     if (state == generic) {        /* It's OK to go ahead. */
  2633.             if (zcopy(f1,f2)) {        /* Try */
  2634.         errpkt((CHAR *)"Can't copy file"); /* give error message */
  2635.         } else {
  2636.         success = 1;
  2637.         ack();
  2638.         }
  2639.             RESUME;            /* wait for next server command */
  2640.         return(-1);
  2641.     }
  2642.     }
  2643.     return(-1);
  2644. #else /* no ZCOPY */
  2645.     errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */
  2646.     RESUME;                /* wait for next server command */
  2647.     return(-1);
  2648. #endif /* ZCOPY */
  2649. #endif /* NOSERVER */
  2650. }
  2651.  
  2652. static int
  2653. srv_rename() {
  2654. #ifndef NOSERVER
  2655. #ifdef CKSYSLOG
  2656.     if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2657.       cksyslog(SYSLG_PR, 1, "server", "REMOTE RENAME", (char *)srvcmd);
  2658. #endif /* CKSYSLOG */
  2659. #ifdef ZRENAME
  2660.     if (!ENABLED(en_ren)) {
  2661.     errpkt((CHAR *)"REMOTE RENAME disabled");
  2662.     RESUME;
  2663.     return(-1);
  2664.     } else {                /* RENAME is enabled */
  2665.     char *str1, *str2, f1[256], f2[256];
  2666.     int len1, len2;
  2667.     len1 = xunchar(srvcmd[1]);    /* Separate the parameters */
  2668.     len2 = xunchar(srvcmd[2+len1]);
  2669.     strncpy(f1,(char *)(srvcmd+2),len1);
  2670.     f1[len1] = NUL;
  2671.     strncpy(f2,(char *)(srvcmd+3+len1),len2);
  2672.     f2[len2] = NUL;
  2673.     len2 = xunchar(srvcmd[2+len1]);
  2674.     strncpy(f1,(char *)(srvcmd+2),len1);
  2675.     f1[len1] = NUL;
  2676.     strncpy(f2,(char *)(srvcmd+3+len1),len2);
  2677.     f2[len2] = NUL;
  2678. #ifdef IKSDB
  2679.     if (ikdbopen) slotstate(what,"REMOTE RENAME", f1, f2);
  2680. #endif /* IKSDB */
  2681.     if (!ENABLED(en_cwd)) {        /* If CWD is disabled */
  2682.         zstrip(f1,&str1);        /* and they included a pathname, */
  2683.         zstrip(f2,&str2);
  2684.         if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */
  2685.         errpkt((CHAR *)"Access denied");
  2686.         RESUME;            /* Remember, this is not a goto! */
  2687.         return(-1);
  2688.         }
  2689.     }
  2690.     if (state == generic) {        /* It's OK to go ahead. */
  2691.         if (zrename(f1,f2)) {    /* Try */
  2692.         errpkt((CHAR *)"Can't rename file"); /* Give error msg */
  2693.         } else {
  2694.         success = 1;
  2695.         ack();
  2696.         }
  2697.         RESUME;            /* Wait for next server command */
  2698.         return(-1);
  2699.     }
  2700.     }
  2701.     return(-1);
  2702. #else /* no ZRENAME */
  2703.     /* Give error message */
  2704.     errpkt((CHAR *)"REMOTE RENAME not available");
  2705.     RESUME;                /* Wait for next server command */
  2706.     return(-1);
  2707. #endif /* ZRENAME */
  2708. #endif /* NOSERVER */
  2709. }
  2710.  
  2711. static int
  2712. srv_login() {
  2713. #ifndef NOSERVER
  2714.     char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1];
  2715.     CHAR *p;
  2716.     int len, i;
  2717.  
  2718.     debug(F101,"REMOTE LOGIN x_login","",x_login);
  2719.     debug(F101,"REMOTE LOGIN x_logged","",x_logged);
  2720.  
  2721.     f1[0] = NUL; f2[0] = NUL; f3[0] = NUL;
  2722.     len = 0;
  2723.     if (srvcmd[1])            /* First length field */
  2724.       len = xunchar(srvcmd[1]);        /* Separate the parameters */
  2725.  
  2726.     if (x_login) {            /* Login required */
  2727.     if (x_logged) {            /* And already logged in */
  2728.         if (len > 0) {        /* Logging in again */
  2729.         errpkt((CHAR *)"Already logged in.");
  2730.         } else {            /* Logging out */
  2731.         debug(F101,"REMOTE LOGOUT","",x_logged);
  2732. #ifdef CKSYSLOG
  2733.         if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2734.           cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGOUT", NULL);
  2735. #endif /* CKSYSLOG */
  2736. #ifdef IKSDB
  2737.         if (ikdbopen) slotstate(what,"REMOTE LOGOUT", "", "");
  2738. #endif /* IKSDB */
  2739.         tlog(F110,"Logged out",x_user,0);
  2740.         ack1((CHAR *)"Logged out");
  2741.         success = 1;
  2742.         msleep(500);
  2743. #ifdef CK_LOGIN
  2744.         x_logged = 0;
  2745. #ifdef IKSD
  2746.         if (inserver)
  2747.           ckxlogout();
  2748. #endif /* IKSD */
  2749. #endif /* CK_LOGIN */
  2750.         }
  2751.     } else {            /* Not logged in yet */
  2752.         debug(F101,"REMOTE LOGIN len","",len);
  2753.         if (len > 0) {        /* Have username */
  2754. #ifdef CKSYSLOG
  2755.         if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2756.           cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGIN", NULL);
  2757. #endif /* CKSYSLOG */
  2758.         if (len > LOGINLEN) {
  2759.             errpkt((CHAR *)"Username too long");
  2760.         }
  2761.         p = srvcmd + 2;        /* Point to it */
  2762.         for (i = 0; i < len; i++) /* Copy it */
  2763.           f1[i] = p[i];
  2764.         f1[len] = NUL;        /* Terminate it */
  2765.         p += len;        /* Point to next length field */
  2766.         if (*p) {        /* If we have one */
  2767.             len = xunchar(*p++); /* decode it */
  2768.             if (len > 0 && len <= LOGINLEN) {
  2769.             for (i = 0; i < len; i++) /* Same deal for password */
  2770.               f2[i] = p[i];
  2771.             f2[len] = NUL;
  2772.             p += len;    /* And account */
  2773.             if (*p) {
  2774.                 len = xunchar(*p++);
  2775.                 if (len > 0 && len <= LOGINLEN) {
  2776.                 for (i = 0; i < len; i++)
  2777.                   f3[i] = p[i];    /* Set but never used */
  2778.                 f3[len] = NUL; /* (because account not used) */
  2779.                 }
  2780.             }
  2781.             }
  2782.         }
  2783.         debug(F101,"REMOTE LOGIN 1","",x_logged);
  2784. #ifdef IKSD
  2785. #ifdef CK_LOGIN
  2786.         if (inserver) {        /* Log in to system for real */
  2787.             x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
  2788.             debug(F101,"REMOTE LOGIN 2","",x_logged);
  2789.             if (x_logged) {    /* Count attempts */
  2790.             logtries = 0;
  2791.             justone = 1;
  2792.             } else {
  2793.             logtries++;
  2794.             sleep(logtries);
  2795.             }
  2796.         } else
  2797. #endif /* CK_LOGIN */
  2798. #endif /* IKSD */
  2799.           if (x_user && x_passwd) { /* User and password must match */
  2800.               if (!strcmp(x_user,f1)) /* SET SERVER LOGIN */
  2801.             if (!strcmp(x_passwd,f2))
  2802.               x_logged = 1;
  2803.               debug(F101,"REMOTE LOGIN 3","",x_logged);
  2804.           } else if (x_user) {    /* Only username given, no password */
  2805.               if (!strcmp(x_user,f1)) /* so only username must match */
  2806.             x_logged = 1;
  2807.               debug(F101,"REMOTE LOGIN 4","",x_logged);
  2808.           }
  2809. #ifdef CK_LOGIN 
  2810.                 else {
  2811.             x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
  2812.             debug(F101,"REMOTE LOGIN 5","",x_logged);
  2813.                 }
  2814. #endif /* CK_LOGIN */
  2815.         if (x_logged) {        /* Logged in? */
  2816.             tlog(F110,"Logged in", x_user, 0);
  2817.             if (isguest)
  2818.               ack1((CHAR *)"Logged in as guest - restrictions apply");
  2819.             else
  2820.               ack1((CHAR *)"Logged in");
  2821.             success = 1;
  2822.         } else {
  2823.             tlog(F110,"Login failed", f1, 0);
  2824.             errpkt((CHAR *)"Access denied.");
  2825. #ifdef IKSD
  2826. #ifdef CK_LOGIN
  2827.             if (inserver && logtries > 2)
  2828.               ckxlogout();
  2829. #endif /* CK_LOGIN */
  2830. #endif /* IKSD */
  2831.         }
  2832.         } else {            /* LOGOUT */
  2833.         errpkt((CHAR *)"Logout ignored");
  2834.         }
  2835.     }
  2836.     } else {                /* Login not required */
  2837.     if (len > 0)
  2838.       errpkt((CHAR *)"Login ignored.");
  2839.     else
  2840.       errpkt((CHAR *)"Logout ignored.");
  2841.     }
  2842. #endif /* NOSERVER */
  2843.     RESUME;
  2844.     return(-1);
  2845. }
  2846.  
  2847. static int
  2848. srv_timeout() {
  2849.     /* K95 does this its own way */
  2850.     if (idletmo) {
  2851. #ifdef IKSD
  2852.         if (inserver) {
  2853.            printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", srvidl);
  2854.            doexit(GOOD_EXIT,xitsta);
  2855.         }
  2856. #endif /* IKSD */
  2857.     idletmo = 0;
  2858.     printf("\r\nSERVER IDLE TIMEOUT: %d sec\r\n", srvidl);
  2859.     xitsta |= (what & W_KERMIT);
  2860.     QUIT;
  2861.     }
  2862. #ifndef NOSERVER
  2863.     else if (fatalio) {            /* Connection lost */
  2864. #ifdef CKSYSLOG
  2865.       if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2866.         cksyslog(SYSLG_PR, 1, "server", "Connection lost", NULL);
  2867. #endif /* CKSYSLOG */
  2868. #ifdef IKSDB
  2869.       if (ikdbopen) slotstate(what,"SERVER DISCONNECT",(char *)srvcmd, "");
  2870. #endif /* IKSDB */
  2871.     xitsta |= what;
  2872.     QUIT;
  2873.     } else if (interrupted) {        /* Interrupted by hand */
  2874.     if (!ENABLED(en_fin)) {
  2875.         errpkt((CHAR *)"QUIT disabled");
  2876.         RESUME;
  2877.         return(-1);
  2878.     } else {
  2879.         if (what == W_SEND || what == W_RECV || what == W_REMO) {
  2880.         success = 0;
  2881. #ifdef CKSYSLOG
  2882.         if (ckxsyslog >= SYSLG_PR && ckxlogging)
  2883.           cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
  2884. #endif /* CKSYSLOG */
  2885.         } else if (what == W_NOTHING && filcnt == 0) {
  2886.         success = 1;
  2887.         } /* Otherwise leave success alone */
  2888.         xitsta |= (what & W_KERMIT);
  2889.         QUIT;
  2890.     }
  2891.     } else {                /* Shouldn't happen */
  2892.     debug(F100,"SERVER (top) GOT UNEXPECTED 'q'","",0);
  2893.     QUIT;
  2894.     }
  2895. #endif /* NOSERVER */
  2896. }
  2897.  
  2898. static int
  2899. rcv_s_pkt() {
  2900. #ifndef NOSERVER
  2901.     if (state == rgen)
  2902.       urserver = 1;
  2903.     if (/* state == serve && */ x_login && !x_logged) {
  2904.     errpkt((CHAR *)"Login required");
  2905.     SERVE;
  2906.     } else
  2907. #endif /* NOSERVER */
  2908.       if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */
  2909.     errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */
  2910.     RESUME;
  2911.     return(-1);
  2912.     } else {                /* OK to go ahead. */
  2913. #ifdef CK_TMPDIR
  2914.     if (dldir && !f_tmpdir) {    /* If they have a download directory */
  2915.         debug(F110,"receive download dir",dldir,0);
  2916.         if (s = zgtdir()) {        /* Get current directory */
  2917.         debug(F110,"receive current dir",s,0);
  2918.         if (zchdir(dldir)) {    /* Change to download directory */
  2919.             debug(F100,"receive zchdir ok","",0);
  2920.             ckstrncpy(savdir,s,TMPDIRLEN);
  2921.             f_tmpdir = 1;    /* Remember that we did this */
  2922.         } else
  2923.           debug(F100,"receive zchdir failed","",0);
  2924.         }
  2925.     }
  2926. #endif /* CK_TMPDIR */
  2927.     nakstate = 1;            /* Can send NAKs from here. */
  2928.     rinit(rdatap);            /* Set parameters */
  2929.     bctu = bctr;            /* Switch to agreed-upon block check */
  2930.     bctl = (bctu == 4) ? 2 : bctu;    /* Set block-check length */
  2931.     what = W_RECV;            /* Remember we're receiving */
  2932.     lastxfer = W_RECV;
  2933.     resetc();            /* Reset counters */
  2934.     rtimer();            /* Reset timer */
  2935. #ifdef GFTIMER
  2936.     rftimer();
  2937. #endif /* GFTIMER */
  2938.     streamon();
  2939.     BEGIN rfile;            /* Go into receive-file state */
  2940.     }
  2941.     return(-1);
  2942. }
  2943.  
  2944.  
  2945. /* END OF ROUTINES MOVED OUT OF STATE MACHINE */
  2946.  
  2947.  
  2948. /*  P R O T O  --  Protocol entry function  */
  2949.  
  2950. static int is_tn = 0;            /* It's a Telnet connection */
  2951.  
  2952. #ifdef CK_SPEED
  2953. int f_ctlp = 0;                /* Control-character prefix table */
  2954. #ifdef COMMENT
  2955. short s_ctlp[256];
  2956. #endif /* COMMENT */
  2957. #endif /* CK_SPEED */
  2958.  
  2959. /*
  2960.   This is simply a wrapper for the real protocol function just below,
  2961.   that saves any items that might be changed automatically by protocol
  2962.   negotiations and then restores them upon exit from protocol mode.
  2963. */
  2964. VOID
  2965. proto() {
  2966.     extern int b_save, f_save, c_save, ss_save, slostart, reliable, urclear;
  2967. #ifndef NOCSETS
  2968.     extern int fcharset, fcs_save, tcharset, tcs_save;
  2969. #endif /* NOCSETS */
  2970.  
  2971. #ifdef PIPESEND
  2972.     extern int pipesend;
  2973. #endif /* PIPESEND */
  2974. #ifndef NOLOCAL
  2975. #ifdef OS2
  2976.     extern int cursorena[], cursor_save, term_io;
  2977.     extern BYTE vmode;
  2978.     extern int display_demo;
  2979.     int term_io_save;
  2980. #endif /* OS2 */
  2981. #endif /* NOLOCAL */
  2982. #ifdef TNCODE
  2983.     int _u_bin=0, _me_bin = 0;
  2984. #ifdef IKS_OPTION
  2985.     int /* _u_start=0, */ _me_start = 0;
  2986. #endif /* IKS_OPTION */
  2987. #endif /* TNCODE */
  2988. #ifdef PATTERNS
  2989.     int pa_save;
  2990.     int i;
  2991. #endif /* PATTERNS */
  2992.     int scan_save;
  2993.  
  2994. #ifdef PATTERNS
  2995.     pa_save = patterns;
  2996. #endif /* PATTERNS */
  2997.     scan_save = filepeek;
  2998.  
  2999.     myjob = sstate;
  3000.  
  3001. #ifdef CK_LOGIN
  3002.     if (isguest) {            /* If user is anonymous */
  3003.     en_pri = 0;            /* disable printing */
  3004.     en_mai = 0;            /* and disable email */
  3005.     en_del = 0;            /* and file deletion */
  3006.     }
  3007. #endif /* CK_LOGIN */
  3008.  
  3009. #ifndef NOLOCAL
  3010. #ifdef OS2
  3011.     cursor_save = cursorena[vmode];
  3012.     cursorena[vmode] = 0;
  3013.     term_io_save = term_io;
  3014.     term_io = 0;
  3015. #endif /* OS2 */
  3016. #endif /* NOLOCAL */
  3017.     b_save = binary;            /* SET FILE TYPE */
  3018.     f_save = fncnv;            /* SET FILE NAMES */
  3019.     c_save = bctr;
  3020.     p_save = fnspath;
  3021.     r_save = recursive;
  3022.     s_timint = timint;
  3023.     ss_save = slostart;
  3024. #ifndef NOCSETS
  3025.     fcs_save = fcharset;
  3026.     tcs_save = tcharset;
  3027. #endif /* NOCSETS */
  3028.  
  3029. #ifdef COMMENT
  3030. /* Don't do this because then user can never find out what happened. */
  3031. #ifdef CK_SPEED
  3032.     for (i = 0; i < 256; i++)
  3033.       s_ctlp[i] = ctlp[i];
  3034.     f_ctlp = 1;
  3035. #endif /* CK_SPEED */
  3036. #endif /* COMMENT */
  3037.     if (reliable == SET_ON)
  3038.       slostart = 0;
  3039.     is_tn = (!local && sstelnet)
  3040. #ifdef TNCODE
  3041.       || (local && network && ttnproto == NP_TELNET)
  3042. #endif /* TNCODE */
  3043.     ;
  3044. #ifdef TNCODE
  3045.     if (is_tn) {
  3046.         if (tn_b_xfer && !(sstelnet || inserver)) {
  3047.         /* Save the current state of Telnet Binary */
  3048.         _u_bin = TELOPT_U(TELOPT_BINARY);
  3049.         _me_bin = TELOPT_ME(TELOPT_BINARY);
  3050.  
  3051.         /* If either direction is not Binary attempt to negotiate it */
  3052.         if (!_u_bin && TELOPT_U_MODE(TELOPT_BINARY) != TN_NG_RF) {
  3053.         tn_sopt(DO,TELOPT_BINARY);
  3054.         TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1;
  3055.         }
  3056.         if (!_me_bin && TELOPT_ME_MODE(TELOPT_BINARY) != TN_NG_RF) {
  3057.         tn_sopt(WILL,TELOPT_BINARY);
  3058.         TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1;
  3059.         }
  3060.         if (!(_me_bin && _u_bin))
  3061.           tn_wait("proto set binary mode");
  3062.         }
  3063. #ifdef IKS_OPTION
  3064. #ifdef CK_XYZ
  3065.         if (protocol != PROTO_K) {    /* Non-Kermit protocol selected */
  3066.             if (TELOPT_U(TELOPT_KERMIT) &&
  3067.                 TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
  3068.                 iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
  3069.         /* _u_start = 1; */
  3070.             }
  3071.             if (TELOPT_ME(TELOPT_KERMIT) &&
  3072.                 TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
  3073.                 tn_siks(KERMIT_STOP);    /* I'm not servering */
  3074.          TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
  3075.         _me_start = 1;
  3076.             }
  3077.         } else
  3078. #endif /* CK_XYZ */
  3079.         if (sstate == 'x' || sstate == 'v') { /* Responding to a request */
  3080.             if (!inserver && TELOPT_U(TELOPT_KERMIT) &&
  3081.                 TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
  3082.                 iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
  3083.         /* _u_start = 1; */
  3084.             }
  3085.             if (TELOPT_ME(TELOPT_KERMIT) &&
  3086.                 !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
  3087.                 tn_siks(KERMIT_START);    /* Send Kermit-Server Start */
  3088.          TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1;
  3089.             }
  3090.         } else {            /* Initiating a request */
  3091.             if (TELOPT_ME(TELOPT_KERMIT) &&
  3092.                 TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
  3093.                 tn_siks(KERMIT_STOP);    /* I'm not servering */
  3094.          TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
  3095.         _me_start = 1;
  3096.             }
  3097.             if (TELOPT_U(TELOPT_KERMIT) &&
  3098.             !TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
  3099.         /* Send Req-Server-Start */
  3100.                 if (!iks_wait(KERMIT_REQ_START,0)) {
  3101.                     if (sstate != 's') {
  3102.             success = 0;    /* Other Kermit refused to serve */
  3103.             if (local)
  3104.               printf("A Kermit Server is not available\r\n");
  3105.             debug(F110,"proto()",
  3106.                              "A Kermit Server is not available",0);
  3107.             tlog(F110,"IKS client/server failure",
  3108.                              "A Kermit Server is not available",0);
  3109.             goto xxprotox;
  3110.                     }
  3111.         }
  3112.             }
  3113.         }
  3114. #endif /* IKS_OPTION */
  3115. #ifdef CK_ENCRYPTION
  3116.         if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
  3117.             ck_tn_enc_stop();
  3118.         }
  3119. #endif /* CK_ENCRYPTION */
  3120.     }
  3121. #endif /* TNCODE */
  3122.  
  3123.     if (!xfrint) connoi();
  3124.     xxproto();                /* Call the real protocol function */
  3125.  
  3126. #ifdef IKS_OPTION
  3127.   xxprotox:
  3128. #endif /* IKS_OPTION */
  3129.     xferstat = success;            /* Remember transfer status */
  3130.     kactive = 0;
  3131.  
  3132. #ifdef TNCODE
  3133. #ifdef CK_ENCRYPTION
  3134.         if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
  3135.             ck_tn_enc_start();
  3136.         }
  3137. #endif /* CK_ENCRYPTION */
  3138. #ifdef IKS_OPTION
  3139.     if (TELOPT_ME(TELOPT_KERMIT) &&
  3140.         TELOPT_SB(TELOPT_KERMIT).kermit.me_start && !_me_start) {
  3141.         tn_siks(KERMIT_STOP);        /* Server is stopped */
  3142.      TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
  3143.     }
  3144. #endif /* IKS_OPTION */
  3145.     if (is_tn && tn_b_xfer && !(sstelnet || inserver)) {
  3146.         /* if we negotiated Binary mode try to reset it */
  3147.         if (!_u_bin) {
  3148.             /* Check to see if the state changed during the transfer */
  3149.         if (TELOPT_U(TELOPT_BINARY)) {
  3150.         tn_sopt(DONT,TELOPT_BINARY);
  3151.         TELOPT_UNANSWERED_DONT(TELOPT_BINARY) = 1;
  3152.         } else
  3153.           _u_bin = 1;        /* So we don't call tn_wait() */
  3154.         }
  3155.         if (!_me_bin) {
  3156.             /* Check to see if the state changed during the transfer */
  3157.         if (TELOPT_ME(TELOPT_BINARY)) {
  3158.         tn_sopt(WONT,TELOPT_BINARY);
  3159.         TELOPT_UNANSWERED_WONT(TELOPT_BINARY) = 1;
  3160.         } else
  3161.           _me_bin = 1;        /* So we don't call tn_wait() */
  3162.     }
  3163.     if (!(_me_bin && _u_bin))
  3164.       tn_wait("proto reset binary mode");
  3165.     }
  3166. #endif /* TNCODE */
  3167.  
  3168. #ifdef PATTERNS
  3169.     patterns = pa_save;
  3170. #endif /* PATTERNS */
  3171.     filepeek = scan_save;
  3172.  
  3173. #ifdef STREAMING
  3174.     streaming = 0;
  3175.     /* streamok = 0; */
  3176. #endif /* STREAMING */
  3177. #ifdef COMMENT
  3178. #ifdef CK_SPEED
  3179.     for (i = 0; i < 256; i++)
  3180.       ctlp[i] = s_ctlp[i];
  3181.     f_ctlp = 0;
  3182. #endif /* CK_SPEED */
  3183. #endif /* COMMENT */
  3184.     urclear = 0;
  3185.     if (!success) {
  3186.     xitsta |= (what & W_KERMIT);
  3187.     tlog(F110," failed:",(char *)epktmsg,0);
  3188.     }
  3189.     debug(F111,"proto xferstat",epktmsg,xferstat);
  3190.     slostart = ss_save;
  3191.     if (s_timint > -1) {        /* Because of REMOTE SET */
  3192.     timint = s_timint;
  3193.     s_timint = -1;
  3194.     }
  3195.     recursive = r_save;
  3196.     fnspath = p_save;
  3197.     if (c_save > -1) {            /* Because of REMOTE SET */
  3198.     bctr = c_save;
  3199.     c_save = -1;
  3200.     }
  3201.     fncnv   = f_save;
  3202.     binary  = b_save;
  3203. #ifdef PIPESEND
  3204.     pipesend = 0;                /* Next time might not be pipesend */
  3205. #endif /* PIPESEND */
  3206. #ifndef NOLOCAL
  3207. #ifdef OS2
  3208.     cursorena[vmode] = cursor_save;
  3209.     term_io = term_io_save;
  3210.     display_demo = 1;
  3211. #endif /* OS2 */
  3212. #endif /* NOLOCAL */
  3213. }
  3214.  
  3215. static VOID
  3216. xxproto() {
  3217.     int x;
  3218.     long lx;
  3219. #ifdef CK_XYZ
  3220. #ifdef XYZ_INTERNAL
  3221. _PROTOTYP( int pxyz, (int) );
  3222. #endif /* XYZ_INTERNAL */
  3223. #endif /* CK_XYZ */
  3224.  
  3225.     char xss[2];            /* String representation of sstate */
  3226.     xss[0] = sstate;
  3227.     xss[1] = NUL;
  3228.     s_timint = timint;
  3229.  
  3230.     debug(F101,"xxproto entry justone","",justone);
  3231.     success = 0;
  3232.  
  3233.     retrieve = 0;            /* Reset these ... */
  3234.     reget = 0;
  3235.     opkt = 0;
  3236.  
  3237.     if (local && ttchk() < 0) {        /* Giving BYE or FIN */
  3238.     if (bye_active) {        /* but there is no connection */
  3239.         ttclos(0);
  3240.         success = 1;
  3241.         return;
  3242.     }
  3243.     /* Ditto for any REMOTE command */
  3244.     if (sstate == 'g' && cmarg ) {
  3245.         if (*cmarg == 'L' || *cmarg == 'F' || *cmarg == 'X')
  3246.           success = 1;
  3247.         else
  3248.           printf("?No connection\r\n");
  3249.         return;
  3250.     }
  3251.     }
  3252.  
  3253. /* Set up the communication line for file transfer. */
  3254. /* NOTE: All of the xxscreen() calls prior to the wart() invocation */
  3255. /* could just as easily be printf's or, for that matter, hints. */
  3256.  
  3257.     if (local && (speed < 0L) && (network == 0)) {
  3258.     xxscreen(SCR_EM,0,0L,"Sorry, you must 'set speed' first");
  3259.     return;
  3260.     }
  3261.     x = -1;
  3262.     if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) {
  3263.     debug(F111,"failed: proto ttopen local",ttname,local);
  3264.     xxscreen(SCR_EM,0,0L,"Can't open line");
  3265.     return;
  3266.     }
  3267.     if (x > -1) local = x;
  3268.     debug(F111,"proto ttopen local",ttname,local);
  3269.  
  3270.     lx = (local && !network) ? speed : -1;
  3271. #ifdef NETCONN
  3272. #ifdef CK_SPEED
  3273.     if (is_tn) {
  3274.     ctlp[(unsigned)255] = ctlp[CR] = 1;
  3275.     if (parity == 'e' || parity == 'm') ctlp[127] = 1;
  3276.     if (flow == FLO_XONX) {        /* Also watch out for Xon/Xoff */
  3277.         ctlp[17] = ctlp[19] = 1;
  3278.         ctlp[17+128] = ctlp[19+128] = 1;
  3279.     }
  3280.     }
  3281. #endif /* CK_SPEED */
  3282. #endif /* NETCONN */
  3283.     if (ttpkt(lx,flow,parity) < 0) {    /* Put line in packet mode, */
  3284.     xxscreen(SCR_EM,0,0L,"Can't condition line");
  3285.     return;
  3286.     }
  3287.     if (local && !network && carrier != CAR_OFF) {
  3288.     int x;                /* Serial connection */
  3289.     x = ttgmdm();            /* with carrier checking */
  3290.     if (x > -1) {
  3291.         if (!(x & BM_DCD)) {
  3292.         debug(F101,"proto ttgmdm","",0);
  3293.         xxscreen(SCR_EM,0,0L,"Carrier required but not detected");
  3294.         return;
  3295.         }
  3296.     }
  3297.     }
  3298.     /* Send remote side's "receive" or "server" startup string, if any */
  3299.     if (local && ckindex((char *)xss,"srgcjhk",0,0,1)) {
  3300.     char *s = NULL;
  3301.         if (
  3302. #ifdef IKS_OPTION
  3303.         /* Don't send auto-blah string if we know other side is serving */
  3304.         !TELOPT_U(TELOPT_KERMIT) ||
  3305.         !TELOPT_SB(TELOPT_KERMIT).kermit.u_start
  3306. #else
  3307.         1
  3308. #endif /* IKS_OPTION */
  3309.         ) {
  3310.         if (sstate == 's') {    /* Sending file(s) */
  3311.         s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init;
  3312.         } else if (protocol == PROTO_K) { /* Command for server */
  3313.         s = ptab[protocol].h_x_init;
  3314.         }
  3315.     }
  3316. #ifdef CK_SPEED
  3317. #ifndef UNPREFIXZERO
  3318.     if (protocol == PROTO_K)    /* Because of C-strings... */
  3319.       ctlp[0] = 1;
  3320. #endif /* UNPREFIXZERO */
  3321. #endif /* CK_SPEED */
  3322.     if (s) if (*s) {        /* If we have a command to send... */
  3323.         char tmpbuf[356];
  3324.         int tmpbufsiz = 356;
  3325.         int stuff = -1, stuff2 = -1, len = 0;
  3326.         extern int tnlm;
  3327.         if (sstate == 's') {    /* Sending file(s) */
  3328. #ifdef CK_XYZ
  3329.         if (protocol == PROTO_X) {
  3330.             char * s2;
  3331.             s2 = cmarg2[0] ? cmarg2 : cmarg;
  3332.             if ((int)strlen(s) + (int)strlen(s2) + 4 < 356)
  3333.               sprintf(tmpbuf, s, s2);
  3334.             else
  3335.               tmpbuf[0] = NUL;
  3336.         } else {
  3337. #endif /* CK_XYZ */
  3338.             ckmakmsg(tmpbuf, 356, s, NULL, NULL, NULL);
  3339. #ifdef CK_XYZ
  3340.         }
  3341. #endif /* CK_XYZ */
  3342.         } else {            /* Command for server */
  3343.         ckstrncpy(tmpbuf,s,356);
  3344.         }
  3345.         ckstrncat(tmpbuf, "\015",sizeof(tmpbuf));
  3346.         if (tnlm)            /* TERMINAL NEWLINE ON */
  3347.           stuff = LF;        /* Stuff LF */
  3348. #ifdef TNCODE
  3349.         /* TELNET NEWLINE MODE */
  3350.         if (is_tn) {
  3351.         switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) {
  3352.           case TNL_CR:
  3353.             break;
  3354.           case TNL_CRNUL:
  3355.             break;
  3356.           case TNL_CRLF:
  3357.             stuff2 = stuff;
  3358.             stuff = LF;
  3359.             break;
  3360.         }
  3361.         }
  3362. #endif /* TNCODE */
  3363.  
  3364. #ifdef NETCONN
  3365. #ifdef TCPSOCKET
  3366. #ifdef RLOGCODE
  3367.         if (network && ttnproto == NP_RLOGIN) {
  3368.         switch (tn_b_nlm) { /* Always BINARY */
  3369.           case TNL_CR:
  3370.             break;
  3371.           case TNL_CRNUL:
  3372.             stuff2 = stuff;
  3373.             stuff  = NUL;
  3374.             break;
  3375.           case TNL_CRLF:
  3376.             stuff2 = stuff;
  3377.             stuff = LF;
  3378.             break;
  3379.         }
  3380.         }
  3381. #endif /* RLOGCODE */
  3382. #endif /* TCPSOCKET */
  3383. #endif /* NETCONN */
  3384.  
  3385.         len = strlen(tmpbuf);
  3386.         if (stuff >= 0 && len < tmpbufsiz - 1) {
  3387.         tmpbuf[len++] = stuff;
  3388.         if (stuff2 >= 0 && len < tmpbufsiz - 1)
  3389.           tmpbuf[len++] = stuff2;
  3390.         tmpbuf[len] = NUL;
  3391.         }
  3392.         ttol((CHAR *)tmpbuf,len);
  3393.         if (protocol == PROTO_K)    /* Give remote Kermit time to start */
  3394.           msleep(400);
  3395.     }
  3396.     }
  3397.  
  3398. #ifdef CK_XYZ
  3399.     if (protocol != PROTO_K) {        /* Non-Kermit protocol selected */
  3400.     char tmpbuf[356];
  3401.     int tmpbufsiz = 356;
  3402.     char * s = "";
  3403.  
  3404. #ifdef CK_TMPDIR
  3405.     if (sstate == 'v') {        /* If receiving and... */
  3406.         if (dldir && !f_tmpdir) {    /* if they have a download directory */
  3407.         if (s = zgtdir()) {    /* Get current directory */
  3408.             if (zchdir(dldir)) { /* Change to download directory */
  3409.             ckstrncpy(savdir,s,TMPDIRLEN);
  3410.             f_tmpdir = 1;    /* Remember that we did this */
  3411.             }
  3412.         }
  3413.         }
  3414.     }
  3415. #endif /* CK_TMPDIR */
  3416.  
  3417. #ifdef XYZ_INTERNAL            /* Internal */
  3418.     success = !pxyz(sstate);
  3419. #else
  3420. #ifdef CK_REDIR                /* External */
  3421.     switch (sstate) {
  3422.       case 's':            /* 'Tis better to SEND... */
  3423.         s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd;
  3424.         break;
  3425.       case 'v':            /* ... than RECEIVE */
  3426.         s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd;
  3427.         break;
  3428.     }
  3429.     if (!s) s = "";
  3430.     if (*s) {
  3431.         if (sstate == 's') {    /* Sending */
  3432.         extern int xfermode;
  3433.         int k = 0, x = 0, b = binary;
  3434.         /*
  3435.           If just one file we can scan it to set the xfer mode.
  3436.           Otherwise it's up to the external protocol program.
  3437.         */
  3438.         if (patterns && xfermode == XMODE_A && !iswild(fspec)) {
  3439.             extern int nscanfile;
  3440.             k = scanfile(fspec,&x,nscanfile);
  3441.             if (k > -1) {
  3442.             b = (k == FT_BIN) ? XYFT_B : XYFT_T;
  3443.             s = b ?
  3444.                 ptab[protocol].p_b_scmd :
  3445.                 ptab[protocol].p_t_scmd;
  3446.             }
  3447.         }
  3448.         if ((int)strlen(s) + (int)strlen(fspec) < tmpbufsiz) {
  3449.             sprintf(tmpbuf,s,fspec); /* safe (prechecked) */
  3450.             tlog(F110,"Sending",fspec,0L);
  3451.         }
  3452.         } else {            /* Receiving */
  3453.         if ((int)strlen(s) + (int)strlen(cmarg2) < tmpbufsiz) {
  3454.             sprintf(tmpbuf,s,cmarg2); /* safe (prechecked) */
  3455.             tlog(F110,"Receiving",cmarg2,0L);
  3456.         }
  3457.         }
  3458.         tlog(F110," via external protocol:",tmpbuf,0);
  3459.         debug(F110,"ckcpro ttruncmd",tmpbuf,0);
  3460.         success = ttruncmd(tmpbuf);
  3461.         tlog(F110," status:",success ? "OK" : "FAILED", 0);
  3462.     } else {
  3463.         printf("?Sorry, no external protocol defined for %s\r\n",
  3464.            ptab[protocol].p_name
  3465.            );
  3466.     }
  3467. #else
  3468.     printf(
  3469. "Sorry, only Kermit protocol is supported in this version of Kermit\n"
  3470.            );
  3471. #endif /* CK_REDIR */
  3472. #endif /* XYZ_INTERNAL */
  3473.     return;
  3474.     }
  3475. #endif /* CK_XYZ */
  3476.  
  3477. #ifdef NTSIGX
  3478.     conraw();
  3479.     connoi();
  3480. #else
  3481.     if (!local)
  3482.       connoi();                /* No console interrupts if remote */
  3483. #endif /* NTSIG */
  3484.  
  3485.     kactive = 1;
  3486.     if (sstate == 'x') {        /* If entering server mode, */
  3487.     extern int howcalled;
  3488.     server = 1;            /* set flag, */
  3489.     debug(F101,"server backgrd","",backgrd);
  3490.     debug(F101,"server quiet","",quiet);
  3491.     debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0);
  3492.     if (howcalled == I_AM_SSHSUB) {    /* and issue appropriate message. */
  3493.         ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
  3494.     } else if (!local) {
  3495.         if (!quiet && !backgrd
  3496. #ifdef IKS_OPTION
  3497.                 && !TELOPT_ME(TELOPT_KERMIT) /* User was told by negotiation */
  3498. #endif /* IKS_OPTION */
  3499.         ) {
  3500.         conoll(srvtxt);
  3501.         conoll("KERMIT READY TO SERVE...");
  3502.         }
  3503.     } else {
  3504.         conol("Entering server mode on ");
  3505.         conoll(ttname);
  3506.         conoll("Type Ctrl-C to quit.");
  3507.         if (srvdis) intmsg(-1L);
  3508. #ifdef TCPSOCKET
  3509. #ifndef NOLISTEN
  3510.         if (network && tcpsrfd > 0)
  3511.           ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
  3512. #endif /* NOLISTEN */
  3513. #endif /* TCPSOCKET */
  3514.     }
  3515.     } else
  3516.       server = 0;
  3517. #ifdef VMS
  3518.     if (!quiet && !backgrd)    /* So message doesn't overwrite prompt */
  3519.       conoll("");
  3520.     if (local) conres();       /* So Ctrl-C will work */
  3521. #endif /* VMS */
  3522. /*
  3523.   If in remote mode, not shushed, not in background, and at top command level,
  3524.   issue a helpful message telling what to do...
  3525. */
  3526.     if (!local && !quiet && !backgrd) {
  3527.     if (sstate == 'v') {
  3528.         conoll("Return to your local Kermit and give a SEND command.");
  3529.         conoll("");
  3530.         conoll("KERMIT READY TO RECEIVE...");
  3531.     } else if (sstate == 's') {
  3532.         conoll("Return to your local Kermit and give a RECEIVE command.");
  3533.         conoll("");
  3534.         conoll("KERMIT READY TO SEND...");
  3535.     } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' ||
  3536.             sstate == 'j' || sstate == 'c' ) {
  3537.         conoll("Return to your local Kermit and give a SERVER command.");
  3538.         conoll("");
  3539.         conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ?
  3540.            "KERMIT READY TO GET..." :
  3541.            "KERMIT READY TO SEND SERVER COMMAND...");
  3542.     }
  3543.     }
  3544. #ifdef COMMENT
  3545.     if (!local) sleep(1);
  3546. #endif /* COMMENT */
  3547. /*
  3548.   The 'wart()' function is generated by the wart program.  It gets a
  3549.   character from the input() routine and then based on that character and
  3550.   the current state, selects the appropriate action, according to the state
  3551.   table above, which is transformed by the wart program into a big case
  3552.   statement.  The function is active for one transaction.
  3553. */
  3554.     rtimer();                /* Reset elapsed-time timer */
  3555. #ifdef GFTIMER
  3556.     rftimer();
  3557. #endif /* GFTIMER */
  3558.     resetc();                /* & other per-transaction counters. */
  3559.  
  3560.     debug(F101,"proto calling wart, justone","",justone);
  3561.  
  3562.     wart();                /* Enter the state table switcher. */
  3563. /*
  3564.   Note: the following is necessary in case we have just done a remote-mode
  3565.   file transfer, in which case the controlling terminal modes have been
  3566.   changed by ttpkt().  In particular, special characters like Ctrl-C and
  3567.   Ctrl-\ might have been turned off (see ttpkt).  So this call to ttres() is
  3568.   essential.  IMPORTANT: restore interrupt handlers first, otherwise any
  3569.   terminal interrupts that occur before this is done in the normal place
  3570.   later will cause a crash.
  3571. */
  3572. #ifdef OS2
  3573.     ttres();                /* Reset the communication device */
  3574. #else
  3575.     if (!local) {
  3576.     setint();            /* Arm interrupt handlers FIRST */
  3577.     msleep(500);
  3578.     ttres();            /* Then restore terminal. */
  3579.     }
  3580. #endif /* OS2 */
  3581.     xxscreen(SCR_TC,0,0L,"");        /* Transaction complete */
  3582.     x = quiet;
  3583.     quiet=1;
  3584.     clsif();                /* Failsafe in case we missed */
  3585.     clsof(1);                /* a case in the state machine. */
  3586.     quiet = x;
  3587.  
  3588.     if (server) {            /* Back from packet protocol. */
  3589.         if (!quiet && !backgrd
  3590. #ifdef IKSD
  3591.         && !inserver
  3592. #endif /* IKSD */
  3593.         ) {                /* Give appropriate message */
  3594.         conoll("");
  3595.         conoll("C-Kermit server done");
  3596.         }
  3597.         server = 0;            /* Not a server any more */
  3598.     }
  3599. }
  3600.  
  3601. /*  S G E T I N I T  --  Handle incoming GET-Class packets  */
  3602.  
  3603. /*
  3604.   Returns:
  3605.    -1: On error
  3606.     0: GET packet processed OK - ready to Send.
  3607.     1: Extended GET processed OK - wait for another.
  3608. */
  3609. static int
  3610. sgetinit(reget,xget) int reget, xget; {    /* Server end of GET command */
  3611.     char * fs = NULL;            /* Pointer to filespec */
  3612.     int i, n, done = 0;
  3613. #ifdef PIPESEND
  3614.     extern int usepipes, pipesend;
  3615. #endif /* PIPESEND */
  3616.     extern int nolinks;
  3617.  
  3618.     if (!ENABLED(en_get)) {        /* Only if not disabled!  */
  3619.     errpkt((CHAR *)"GET disabled");
  3620.     return(-1);
  3621.     }
  3622.  
  3623.     /* OK to proceed */
  3624.  
  3625.     nolinks = recursive;
  3626.     filcnt = 0;
  3627.  
  3628. #ifdef WHATAMI
  3629.     /* If they are alike this was already done in whoarewe() */
  3630.     debug(F101,"sgetinit whatru","",whatru);
  3631.     if (whatru & WMI_FLAG) {        /* Did we get WHATAMI info? */
  3632.     debug(F101,"sgetinit binary (1)","",binary);
  3633. #ifdef VMS
  3634.     if (binary != XYFT_I && binary != XYFT_L)
  3635. #else
  3636. #ifdef OS2
  3637.       if (binary != XYFT_L)
  3638. #endif /* OS2 */
  3639. #endif /* VMS */
  3640.         binary = (whatru & WMI_FMODE) ? /* Yes, set file type */
  3641.           XYFT_B : XYFT_T;    /* automatically */
  3642.     debug(F101,"sgetinit binary (2)","",binary);
  3643.     if (!wearealike)
  3644.       fncnv = (whatru & WMI_FNAME) ? 1 : 0; /* And name conversion */
  3645.     }
  3646. #endif /* WHATAMI */
  3647.  
  3648.     fs = (char *)srvcmd;
  3649.     srvptr = srvcmd;            /* Point to server command buffer */
  3650.     decode(rdatap,putsrv,0);        /* Decode the GET command into it */
  3651.     /* Accept multiple filespecs */
  3652.     cmarg2 = "";            /* Don't use cmarg2 */
  3653.     cmarg = "";                /* Don't use cmarg */
  3654.  
  3655.     done = 1;                /* Only 1 packet needed... */
  3656.     if (xget) {                /* Special decoding for Extended GET */
  3657.     char L, next, c;        /* PLV items */
  3658.     int len, val;            /* More PLV items */
  3659.     char * p = (char *)srvcmd;    /* String to decode */
  3660.  
  3661.     done = 0;            /* Maybe more packets needed */
  3662.     fs = NULL;            /* We don't know the filespec yet */
  3663.     c = *p++;            /* Get first parameter */
  3664.  
  3665.     while (c) {            /* For all parameters... */
  3666.         debug(F000,"sgetinit c","",c);
  3667.         L = *p++;            /* Get length */
  3668.         if (L >= SP)        /* Decode length */
  3669.           len = xunchar(L);
  3670.         else if (c == '@') {    /* Allow missing EOP length field */
  3671.         len = 0;
  3672.         } else {
  3673.         len = (xunchar(*p++) * 95);
  3674.         len += xunchar(*p++);
  3675.         }
  3676.         debug(F101,"sgetinit len","",len);
  3677.         next = *(p+len);        /* Get next parameter */
  3678.         *(p+len) = NUL;        /* Zero it out to terminal value */
  3679.         debug(F110,"sgetinit p",p,0);
  3680.         switch (c) {        /* Do the parameter */
  3681.           case 'O':            /* GET Options */
  3682.         val = atoi(p);        /* Convert to int */
  3683.         debug(F101,"sgetinit O val","",val);
  3684.         if (val & GOPT_DEL) moving = 1;
  3685.         if (val & GOPT_RES) reget = 1;
  3686.         if (val & GOPT_REC) {
  3687.             recursive = 1;
  3688.             nolinks = 2;
  3689.             if (fnspath == PATH_OFF)
  3690.               fnspath = PATH_REL;
  3691.         }
  3692.         break;
  3693.           case 'M':            /* Transfer Mode */
  3694.         val = atoi(p);
  3695.         debug(F101,"sgetinit M val","",val);
  3696.         if (val < 1)
  3697.           break;
  3698.         patterns = 0;        /* Takes precedence over patterns */
  3699.         filepeek = 0;        /* and FILE SCAN */
  3700.         if (val == GMOD_TXT) binary = XYFT_T; /* Text */
  3701.         if (val == GMOD_BIN) binary = XYFT_B; /* Binary */
  3702.         if (val == GMOD_LBL) binary = XYFT_L; /* Labeled */
  3703.         break;
  3704.           case 'F':            /* Filename */
  3705.         fs = p;
  3706.         debug(F110,"sgetinit filename",fs,0);
  3707.         break;
  3708.           case '@':            /* End Of Parameters */
  3709.         done = 1;
  3710.         debug(F100,"sgetinit EOP","",0);
  3711.         break;
  3712.           default:
  3713.         errpkt((CHAR *)"Unknown GET Parameter");
  3714.         debug(F100,"sgetinit unknown parameter","",0);
  3715.         return(-1);
  3716.         }
  3717.         p += (len + 1);
  3718.         c = next;
  3719.     }
  3720.     }
  3721.     if (!fs) fs = "";            /* A filename is required */
  3722.     if (*fs) {
  3723.     havefs = 1;
  3724.     n = 0;                /* Check for quoted name */
  3725.     if ((n = strlen(fs)) > 1) {
  3726.         /* Note: this does not allow for multiple quoted names */
  3727.         if ((fs[0] == '{' && fs[n-1] == '}') ||
  3728.         (fs[0] == '"' && fs[n-1] == '"')) {
  3729.         fs[n-1] = '\0';
  3730.         fs++;
  3731.         debug(F111,"sgetinit unquoted filename",fs,n);
  3732.         } else
  3733.           n = 0;            /* This means no quoting */
  3734.     }
  3735.  
  3736. #ifdef PIPESEND
  3737.     debug(F111,"sgetinit",fs,usepipes);
  3738.     if (usepipes && ENABLED(en_hos) && *fs == '!') {
  3739.         cmarg = fs + 1;        /* Point past the bang */
  3740.         *fs = NUL;
  3741.         nfils = -1;
  3742.         pipesend = 1;
  3743.         debug(F111,"sgetinit pipesend",cmarg,pipesend);
  3744.     }
  3745.     if (!pipesend) {        /* If it's not a pipe */
  3746. #endif /* PIPESEND */
  3747.         if (n == 0) {        /* If the name was not quoted */
  3748. #ifndef NOMSEND
  3749.         nfils = fnparse(fs);    /* Allow it to be a list of names */
  3750.         debug(F111,"sgetinit A",fs,nfils);
  3751. #ifdef COMMENT
  3752. /* This doesn't work if a GET-PATH is set. */
  3753.         if (nfils == 1 && !iswild(fs)) { /* Single file */
  3754.             char * m;
  3755.             if ((x = zchki(fs)) < 0) { /* Check if it's sendable */
  3756.             switch (x) {
  3757.               case -1: m = "File not found"; break;
  3758.               case -2: m = "Not a regular file"; break;
  3759.               case -3: m = "Read access denied"; break;
  3760.             }
  3761.             errpkt((CHAR *)m);
  3762.             return(-1);
  3763.             }
  3764.         }
  3765. #endif /* COMMENT */
  3766.         } else {            /* If it was quoted */
  3767. #endif /* NOMSEND */
  3768.         nzxopts = 0;
  3769. #ifdef UNIXOROSK
  3770.         if (matchdot)  nzxopts |= ZX_MATCHDOT;
  3771. #endif /* UNIXOROSK */
  3772.         if (recursive) nzxopts |= ZX_RECURSE;
  3773.         /* Treat as a single filespec */
  3774.         nfils = 0 - nzxpand(fs,nzxopts);
  3775.         debug(F111,"sgetinit B",fs,nfils);
  3776.         cmarg = fs;
  3777.         }
  3778. #ifdef PIPESEND
  3779.     }
  3780. #endif /* PIPESEND */
  3781.     }
  3782.     if (!done) {            /* Need more O packets... */
  3783.     debug(F100,"sgetinit O-Packet TBC","",0); /* To Be Continued */
  3784.     return(1);
  3785.     }
  3786.     debug(F100,"sgetinit O-Packet done - havefs","",havefs);
  3787.     if (!havefs) {            /* Done - make sure we have filename */
  3788.     errpkt((CHAR *)"GET without filename");
  3789.     return(-1);
  3790.     }
  3791.     freerpkt(winlo);
  3792.     winlo = 0;                /* Back to packet 0 again. */
  3793.     debug(F101,"sgetinit winlo","",winlo);
  3794.     nakstate = 0;            /* Now I'm the sender! */
  3795.     if (reget) sendmode = SM_RESEND;
  3796.     if (sinit() > 0) {            /* Send Send-Init */
  3797. #ifdef STREAMING
  3798.     if (!streaming)
  3799. #endif /* STREAMING */
  3800.       timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
  3801.     return(0);            /* If successful, switch state */
  3802.     } else return(-1);            /* Else back to server command wait */
  3803. }
  3804.  
  3805. #else  /* NOXFER */
  3806.  
  3807. #include "ckcdeb.h"
  3808.  
  3809. VOID
  3810. proto() {
  3811.     extern int success;
  3812.     success = 0;
  3813. }
  3814. #endif /* NOXFER */
  3815.