From 360ef34c6c0be1dd672fce6d82f167b76f660662 Mon Sep 17 00:00:00 2001 From: Ian Beckwith Date: Wed, 12 May 2010 01:34:35 +0100 Subject: [PATCH] fixed "Loggin" spelling error --- .pc/060_speeling.patch/ckcpro.w | 3591 +++++++++++++++++++++++++++++++++++++ ckcpro.w | 2 +- debian/patches/060_speeling.patch | 29 +- 3 files changed, 3613 insertions(+), 9 deletions(-) create mode 100644 .pc/060_speeling.patch/ckcpro.w diff --git a/.pc/060_speeling.patch/ckcpro.w b/.pc/060_speeling.patch/ckcpro.w new file mode 100644 index 0000000..cd9d1fa --- /dev/null +++ b/.pc/060_speeling.patch/ckcpro.w @@ -0,0 +1,3591 @@ +char *protv = /* -*-C-*- */ +"C-Kermit Protocol Module 8.0.158, 11 Sep 2002"; + +int kactive = 0; /* Kermit protocol is active */ + +#define PKTZEROHACK + +/* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */ +/* + Author: Frank da Cruz , + Columbia University Academic Information Systems, New York City. + + Copyright (C) 1985, 2004, + Trustees of Columbia University in the City of New York. + All rights reserved. See the C-Kermit COPYING.TXT file or the + copyright text in the ckcmai.c module for disclaimer and permissions. +*/ +#ifndef NOXFER +#include "ckcsym.h" +#include "ckcdeb.h" +#include "ckcasc.h" +#include "ckcker.h" +#ifdef OS2 +#ifndef NT +#define INCL_NOPM +#define INCL_VIO /* Needed for ckocon.h */ +#include +#undef COMMENT +#endif /* NT */ +#include "ckocon.h" +#endif /* OS2 */ + +/* + Note -- This file may also be preprocessed by the UNIX Lex program, but + you must indent the above #include statements before using Lex, and then + restore them to the left margin in the resulting C program before compilation. + Also, the invocation of the "wart()" function below must be replaced by an + invocation of the "yylex()" function. It might also be necessary to remove + comments in the (%)(%)...(%)(%) section. +*/ + +/* State definitions for Wart (or Lex) */ +%states ipkt rfile rattr rdpkt ssinit ssfile ssattr ssdata sseof sseot +%states serve generic get rgen ssopkt ropkt + +_PROTOTYP(static VOID xxproto,(void)); +_PROTOTYP(static VOID wheremsg,(void)); +_PROTOTYP(int wart,(void)); +_PROTOTYP(static int sgetinit,(int,int)); +_PROTOTYP(int sndspace,(int)); + +/* External C-Kermit variable declarations */ + extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err; + extern char * rfspec, * sfspec, * srfspec, * rrfspec; + extern char * prfspec, * psfspec, * psrfspec, * prrfspec; + extern char *cdmsgfile[]; + extern char * snd_move, * snd_rename, * srimsg; + extern char filnam[], ofilnam[], fspec[], ttname[], ofn1[]; + extern CHAR sstate, *srvptr, *data; + extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network; + extern int oopts, omode, oname, opath, nopush, isguest, xcmdsrc, rcdactive; + extern int rejection, moving, fncact, bye_active, urserver, fatalio; + extern int protocol, prefixing, filcnt, carrier, fnspath, interrupted; + extern int recursive, inserver, nzxopts, idletmo, srvidl, xfrint; + extern struct ck_p ptab[]; + extern int remfile, rempipe, xferstat, filestatus, wearealike, fackpath; + extern int patterns, filepeek, gnferror; + extern char * remdest; + +#ifdef PKTZEROHACK +#define PKTZEROLEN 32 +static char ipktack[PKTZEROLEN]; +static int ipktlen = 0; +#endif /* PKTZEROHACK */ + +static int s_timint = -1; /* For saving timeout value */ +static int myjob = 0; +static int havefs = 0; +#ifdef CK_LOGIN +static int logtries = 0; +#endif /* CK_LOGIN */ + +static int cancel = 0; +int fackbug = 0; + +#ifdef STREAMING +extern int streaming, streamok; + +static VOID +streamon() { + if (streamok) { + debug(F100,"streamon","",0); + streaming = 1; + timint = 0; /* No timeouts while streaming. */ + } +} + +#ifdef COMMENT /* (not used) */ +static VOID +streamoff() { + if (streaming) { + debug(F100,"streamoff","",0); + streaming = 0; + timint = s_timint; /* Restore timeout */ + } +} +#endif /* COMMENT */ +#else /* STREAMING */ +#define streamon() +#define streamoff() +#endif /* STREAMING */ + +#ifndef NOSPL +_PROTOTYP( int addmac, (char *, char *) ); +_PROTOTYP( int zzstring, (char *, char **, int *) ); +#endif /* NOSPL */ +#ifndef NOICP +_PROTOTYP( int cmdsrc, (void) ); +#endif /* NOICP */ + +#ifndef NOSERVER + extern char * x_user, * x_passwd, * x_acct; + extern int x_login, x_logged; +#endif /* NOSERVER */ + +#include "ckcnet.h" + +#ifdef TNCODE + extern int ttnproto; /* Network protocol */ +#endif /* TNCODE */ + +#ifdef CK_SPEED + extern short ctlp[]; /* Control-character prefix table */ +#endif /* CK_SPEED */ + +#ifdef TNCODE + extern int tn_b_nlm, tn_b_xfer, tn_nlm; +#ifdef CK_ENCRYPTION + extern int tn_no_encrypt_xfer; +#endif /* CK_ENCRYPTION */ +#endif /* TNCODE */ + +#ifdef TCPSOCKET +#ifndef NOLISTEN + extern int tcpsrfd; +#endif /* NOLISTEN */ +#endif /* TCPSOCKET */ + + extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl; + extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo; + extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla; + extern int timef, stdinf, rscapu, sendmode, epktflg, epktrcvd, epktsent; + extern int binary, fncnv; + extern long speed, ffc, crc16, calibrate, dest; +#ifdef COMMENT + extern char *TYPCMD, *DIRCMD, *DIRCM2; +#endif /* COMMENT */ +#ifndef OS2 + extern char *SPACMD, *SPACM2, *WHOCMD; +#endif /* OS2 */ + extern CHAR *rdatap; + extern struct zattr iattr; + +#ifdef VMS + extern int batch; +#endif /* VMS */ + +#ifdef GFTIMER + extern CKFLOAT fptsecs; +#endif /* GFTIMER */ + + extern CHAR *srvcmd; + extern CHAR *epktmsg; + +#ifdef CK_TMPDIR +extern int f_tmpdir; /* Directory changed temporarily */ +extern char savdir[]; /* For saving current directory */ +extern char * dldir; +#endif /* CK_TMPDIR */ + + extern int query; /* Query-active flag */ +#ifndef NOSPL + extern int cmdlvl; + char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */ + char *qbufp = querybuf; /* Pointer to it */ + int qbufn = 0; /* Length of data in it */ +#else + extern int tlevel; +#endif /* NOSPL */ + +#ifndef NOICP + extern int escape; +#endif /* NOICP */ +/* + If the following flag is nonzero when the protocol module is entered, + then server mode persists for exactly one transaction, rather than + looping until BYE or FINISH is received. +*/ +extern int justone; + +static int r_save = -1; +static int p_save = -1; + +/* Function to let remote-mode user know where their file(s) went */ + +int whereflg = 1; /* Unset with SET XFER REPORT */ + +static VOID +wheremsg() { + extern int quiet, filrej; + int n; + n = filcnt - filrej; + debug(F101,"wheremsg n","",n); + + debug(F110,"wheremsg prfspec",prfspec,0); + debug(F110,"wheremsg rfspec",rfspec,0); + debug(F110,"wheremsg psfspec",psfspec,0); + debug(F110,"wheremsg sfspec",sfspec,0); + + debug(F110,"wheremsg prrfspec",prrfspec,0); + debug(F110,"wheremsg rrfspec",rrfspec,0); + debug(F110,"wheremsg psrfspec",psrfspec,0); + debug(F110,"wheremsg srfspec",srfspec,0); + + if (!quiet && !local) { + if (n == 1) { + switch (myjob) { + case 's': + if (sfspec) { + printf(" SENT: [%s]",sfspec); + if (srfspec) + printf(" To: [%s]",srfspec); + printf(" (%s)\n", success ? "OK" : "FAILED"); + } + break; + case 'r': + case 'v': + if (rrfspec) { + printf(" RCVD: [%s]",rrfspec); + if (rfspec) + printf(" To: [%s]",rfspec); + printf(" (%s)\n", success ? "OK" : "FAILED"); + } + } + } else if (n > 1) { + switch (myjob) { + case 's': + if (sfspec) { + printf(" SENT: (%d files)",n); + if (srfspec) + printf(" Last: [%s]",srfspec); + printf(" (%s)\n", success ? "OK" : "FAILED"); + } + break; + case 'r': + case 'v': + if (rrfspec) { + printf(" RCVD: (%d files)",n); + if (rfspec) + printf(" Last: [%s]",rfspec); + printf(" (%s)\n", success ? "OK" : "FAILED"); + } + } + } else if (n == 0) { + if (myjob == 's') + printf(" SENT: (0 files) \n"); + else if (myjob == 'r' || myjob == 'v') + printf(" RCVD: (0 files) \n"); + } + } +} + +static VOID +rdebug() { + if (server) + debug(F111,"RESUME","server=1",justone); + else + debug(F111,"RESUME","server=0",justone); +} + +/* Flags for the ENABLE and DISABLE commands */ +extern int + en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri, + en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit, + en_mkd, en_rmd; +#ifndef NOSPL +extern int en_asg, en_que; +#endif /* NOSPL */ +extern int what, lastxfer; + +/* Global variables declared here */ + + int whatru = 0; /* What are you. */ + int whatru2 = 0; /* What are you, cont'd. */ + +/* Local variables */ + + static char vstate = 0; /* Saved State */ + static char vcmd = 0; /* Saved Command */ + static int reget = 0; /* Flag for executing REGET */ + static int retrieve = 0; /* Flag for executing RETRIEVE */ + static int opkt = 0; /* Send Extended GET packet */ + + static int x; /* General-purpose integer */ + static char *s; /* General-purpose string pointer */ + +/* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */ +/* BEGIN is NOT a GOTO! */ +#define TINIT if (tinit(1) < 0) return(-9) +#define SERVE { TINIT; resetc(); nakstate=1; what=W_NOTHING; cmarg2=""; \ +sendmode=SM_SEND; havefs=0; recursive=r_save; fnspath=p_save; BEGIN serve; } +#define RESUME { rdebug(); if (!server) { wheremsg(); return(0); } else \ +if (justone) { justone=0; wheremsg(); return(0); } else { SERVE; } } + +#ifdef GFTIMER +#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); \ + fptsecs=gftimer(); quiet=x; return(success) +#else +#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \ + return(success) +#endif /* GFTIMER */ + +/* + By late 1999, the big switch() statement generated from the following state + table began choking even gcc, so here we extract the code from the larger + states into static routines to reduce the size of the cases and the + switch() overall. The routines follow the state table; the prototypes are + here. Each of these routines simply contains the text from the + corresponding case, but with return(-1) added in appropriate places; see + instructions after the state table switcher. +*/ +static int rc; /* Return code for these routines */ +static int rcv_s_pkt(); /* Received an S packet */ +static int rcv_firstdata(); /* Received first Data packet */ +static int rcv_shortreply(); /* Short reply to a REMOTE command */ +static int srv_query(); /* Server answers an query */ +static int srv_copy(); /* Server executes REMOTE COPY */ +static int srv_rename(); /* Server executes REMOTE RENAME */ +static int srv_login(); /* Server executes REMOTE LOGIN */ +static int srv_timeout(); /* Server times out */ + +%% + +/* + Protocol entry points, one for each start state (sstate). + The lowercase letters are internal "inputs" from the user interface. + NOTE: The start state letters that appear on the left margin immediately + below can NOT be used as packet types OR as G-packet subcodes. +*/ + +s { TINIT; /* Send file(s) */ + if (sinit() > 0) BEGIN ssinit; + else RESUME; } + +v { TINIT; nakstate = 1; BEGIN get; } /* Receive file(s) */ + +r { /* Client sends a GET command */ + TINIT; + vstate = get; + reget = 0; + retrieve = 0; + opkt = 0; + vcmd = 0; +#ifdef PKTZEROHACK + ipktack[0] = NUL; +#endif /* PKTZEROHACK */ + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} + +h { /* Client sends a RETRIEVE command */ + TINIT; + vstate = get; + reget = 0; + retrieve = 1; + opkt = 0; + vcmd = 0; + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} +j { /* Client sends a REGET command */ + TINIT; + vstate = get; + reget = 1; + retrieve = 0; + opkt = 0; + vcmd = 0; + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} +o { /* Client sends Extended GET Packet */ + TINIT; + vstate = get; + reget = oopts & GOPT_RES; + retrieve = oopts & GOPT_DEL; + opkt = 1; + vcmd = 0; + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} +c { /* Client sends a Host command */ + TINIT; + vstate = rgen; + vcmd = 'C'; + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} +k { TINIT; /* Client sends a Kermit command */ + vstate = rgen; + vcmd = 'K'; + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} +g { /* Client sends a REMOTE command */ + TINIT; + vstate = rgen; + vcmd = 'G'; + if (sipkt('I') >= 0) + BEGIN ipkt; + else + RESUME; +} +x { /* Enter server mode */ + int x; + x = justone; + if (!ENABLED(en_del)) { /* If DELETE is disabled */ + if (fncact == XYFX_B || /* undo any file collision action */ + fncact == XYFX_U || /* that could result in deletion or */ + fncact == XYFX_A || /* modification of existing files. */ + fncact == XYFX_X) { +#ifndef NOICP + extern int g_fncact; + g_fncact = fncact; /* Save current setting */ +#endif /* NOICP */ + fncact = XYFX_R; /* Change to RENAME */ + debug(F101,"server DELETE disabled so fncact RENAME","",fncact); + } + } + SERVE; /* tinit() clears justone... */ + justone = x; +#ifdef IKSDB + if (ikdbopen) slotstate(what, "SERVER", "", ""); +#endif /* IKSDB */ +} + +a { + int b1 = 0, b2 = 0; + if (!data) TINIT; /* "ABEND" -- Tell other side. */ +#ifndef pdp11 + if (epktflg) { /* If because of E-PACKET command */ + b1 = bctl; b2 = bctu; /* Save block check type */ + bctl = bctu = 1; /* set it to 1 */ + } +#endif /* pdp11 */ + errpkt((CHAR *)"User cancelled"); /* Send the packet */ +#ifndef pdp11 + if (epktflg) { /* Restore the block check */ + epktflg = 0; + bctl = b1; bctu = b2; + } +#endif /* pdp11 */ + success = 0; + return(0); /* Return from protocol. */ +} + +/* + Dynamic states: input-character { action } + nakstate != 0 means we're in a receiving state, in which we send ACKs & NAKs. +*/ + +S { /* Receive Send-Init packet. */ + rc = rcv_s_pkt(); + cancel = 0; /* Reset cancellation counter */ + debug(F101,"rcv_s_pkt","",rc); + if (rc > -1) return(rc); /* (see below) */ +} + +/* States in which we get replies back from commands sent to a server. */ +/* Complicated because direction of protocol changes, packet number */ +/* stays at zero through I-G-S sequence, and complicated even more by */ +/* sliding windows buffer allocation. */ + +Y { /* Get ack for I-packet */ + int x = 0; +#ifdef PKTZEROHACK + ckstrncpy(ipktack,(char *)rdatap,PKTZEROLEN); /* Save a copy of the ACK */ + ipktlen = strlen(ipktack); +#endif /* PKTZEROHACK */ + spar(rdatap); /* Set parameters */ + cancel = 0; + winlo = 0; /* Set window-low back to zero */ + debug(F101,"Y winlo","",winlo); + urserver = 1; /* So I know I'm talking to a server */ + if (vcmd) { /* If sending a generic command */ + if (tinit(0) < 0) return(-9); /* Initialize many things */ + x = scmd(vcmd,(CHAR *)cmarg); /* Do that */ + if (x >= 0) x = 0; /* (because of O-Packet) */ + debug(F101,"proto G packet scmd","",x); + vcmd = 0; /* and then un-remember it. */ + } else if (vstate == get) { + debug(F101,"REGET sstate","",sstate); + x = srinit(reget, retrieve, opkt); /* GET or REGET, etc */ + } + if (x < 0) { /* If command was too long */ + if (!srimsg) + srimsg = "Error sending string"; + errpkt((CHAR *)srimsg); /* cancel both sides. */ + success = 0; + RESUME; + } else if (x > 0) { /* Need to send more O-Packets */ + BEGIN ssopkt; + } else { + rtimer(); /* Reset the elapsed seconds timer. */ +#ifdef GFTIMER + rftimer(); +#endif /* GFTIMER */ + winlo = 0; /* Window back to 0, again. */ + debug(F101,"Y vstate","",vstate); + nakstate = 1; /* Can send NAKs from here. */ + BEGIN vstate; /* Switch to desired state */ + } +} + +Y { /* Got ACK to O-Packet */ + debug(F100,"CPCPRO Y","",0); + x = sopkt(); + debug(F101,"CPCPRO Y x","",x); + if (x < 0) { /* If error */ + errpkt((CHAR *)srimsg); /* cancel both sides. */ + success = 0; + RESUME; + } else if (x == 0) { /* This was the last O-Packet */ + rtimer(); /* Reset the elapsed seconds timer. */ +#ifdef GFTIMER + rftimer(); +#endif /* GFTIMER */ + winlo = 0; /* Window back to 0, again. */ + debug(F101,"Y winlo","",winlo); + nakstate = 1; /* Can send NAKs from here. */ + BEGIN vstate; /* Switch to desired state */ + } + debug(F101,"CPCPRO Y not changing state","",x); +} + +E { /* Ignore Error reply to I packet */ + int x = 0; + winlo = 0; /* Set window-low back to zero */ + debug(F101,"E winlo","",winlo); + if (vcmd) { /* In case other Kermit doesn't */ + if (tinit(0) < 0) return(-9); + x = scmd(vcmd,(CHAR *)cmarg); /* understand I-packets. */ + if (x >= 0) x = 0; /* (because of O-Packet) */ + vcmd = 0; /* Otherwise act as above... */ + } else if (vstate == get) x = srinit(reget, retrieve, opkt); + if (x < 0) { /* If command was too long */ + errpkt((CHAR *)srimsg); /* cancel both sides. */ + success = 0; + RESUME; + } else if (x > 0) { /* Need to send more O-Packets */ + BEGIN ssopkt; + } else { + freerpkt(winlo); /* Discard the Error packet. */ + debug(F101,"E winlo","",winlo); + winlo = 0; /* Back to packet 0 again. */ + nakstate = 1; /* Can send NAKs from here. */ + BEGIN vstate; + } +} + +Y { /* Resend of previous I-pkt ACK, same seq number */ + freerpkt(0); /* Free the ACK's receive buffer */ + resend(0); /* Send the GET packet again. */ +} + +/* States in which we're being a server */ + +I { /* Get I-packet */ +#ifndef NOSERVER + spar(rdatap); /* Set parameters from it */ + ack1(rpar()); /* Respond with our own parameters */ +#ifdef COMMENT + pktinit(); /* Reinitialize packet numbers */ +#else +#ifdef COMMENT + /* This can't be right - it undoes the stuff we just negotiated */ + x = justone; + tinit(1); /* Reinitialize EVERYTHING */ + justone = x; /* But this... */ +#else + tinit(0); /* Initialize most things */ +#endif /* COMMENT */ +#endif /* COMMENT */ +#endif /* NOSERVER */ + cancel = 0; /* Reset cancellation counter */ +} + +R { /* GET */ +#ifndef NOSERVER + if (x_login && !x_logged) { + errpkt((CHAR *)"Login required"); + SERVE; + } else if (sgetinit(0,0) < 0) { + RESUME; + } else { +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "GET", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } +#endif /* NOSERVER */ +} + +H { /* GET /DELETE (RETRIEVE) */ +#ifndef NOSERVER + if (x_login && !x_logged) { + errpkt((CHAR *)"Login required"); + RESUME; + } else if (!ENABLED(en_del)) { + errpkt((CHAR *)"Deleting files is disabled"); + RESUME; + } else if (sgetinit(0,0) < 0) { + RESUME; + } else { + moving = 1; +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "GET /DELETE", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } +#endif /* NOSERVER */ +} + +V { /* GET /RECURSIVE */ +#ifndef NOSERVER + recursive = 1; /* Set these before sgetinit() */ + if (fnspath == PATH_OFF) + fnspath = PATH_REL; /* Don't worry, they will be */ + if (x_login && !x_logged) { /* reset next time through. */ + errpkt((CHAR *)"Login required"); + RESUME; + } else if (sgetinit(0,0) < 0) { + RESUME; + } else { +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "GET /RECURSIVE", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } +#endif /* NOSERVER */ +} + +W { /* GET /RECURSIVE /DELETE */ +#ifndef NOSERVER + recursive = 1; /* Set these before sgetinit() */ + if (fnspath == PATH_OFF) + fnspath = PATH_REL; /* Don't worry, they will be */ + moving = 1; /* reset next time through. */ + if (x_login && !x_logged) { + errpkt((CHAR *)"Login required"); + RESUME; + } else if (!ENABLED(en_del)) { + errpkt((CHAR *)"Deleting files is disabled"); + RESUME; + } else if (sgetinit(0,0) < 0) { + RESUME; + } else { +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR,1,"server", + "GET /RECURSIVE /DELETE",(char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } +#endif /* NOSERVER */ +} + +J { /* GET /RECOVER (REGET) */ +#ifndef NOSERVER + if (x_login && !x_logged) { + errpkt((CHAR *)"Login required"); + SERVE; + } else if (sgetinit(1,0) < 0) { + RESUME; + } else { +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "GET /RECOVER", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } +#endif /* NOSERVER */ +} + +O { /* Extended GET */ +#ifndef NOSERVER + if (x_login && !x_logged) { /* (any combination of options) */ + errpkt((CHAR *)"Login required"); + SERVE; + } else if ((x = sgetinit(0,1)) < 0) { + debug(F101,"CKCPRO O sgetinit fail","",x); + RESUME; + } else if (x == 0) { + debug(F101,"CKCPRO O sgetinit done","",x); +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } else { /* Otherwise stay in this state */ + debug(F101,"CKCPRO O sgetinit TBC","",x); + ack(); + BEGIN ropkt; + } +#endif /* NOSERVER */ +} + +O { +#ifndef NOSERVER + if (x_login && !x_logged) { /* (any combination of options) */ + errpkt((CHAR *)"Login required"); + SERVE; + } else if ((x = sgetinit(0,1)) < 0) { + debug(F101,"CKCPRO O sgetinit fail","",x); + RESUME; + } else if (x == 0) { + debug(F101,"CKCPRO O sgetinit done","",x); +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; + } else { /* Otherwise stay in this state */ + debug(F101,"CKCPRO O sgetinit TBC","",x); + ack(); + } +#endif /* NOSERVER */ +} + +G { /* Generic server command */ +#ifndef NOSERVER + srvptr = srvcmd; /* Point to command buffer */ + decode(rdatap,putsrv,0); /* Decode packet data into it */ + putsrv(NUL); /* Insert a couple nulls */ + putsrv(NUL); /* for termination */ + if (srvcmd[0]) { + sstate = srvcmd[0]; /* Set requested start state */ + if (x_login && !x_logged && /* Login required? */ + /* Login, Logout, and Help are allowed when not logged in */ + sstate != 'I' && sstate != 'L' && sstate != 'H') { + errpkt((CHAR *)"Login required"); + SERVE; + } else { + nakstate = 0; /* Now I'm the sender. */ + what = W_REMO; /* Doing a REMOTE command. */ +#ifdef STREAMING + if (!streaming) +#endif /* STREAMING */ + if (timint < 1) + timint = chktimo(rtimo,timef); /* Switch to per-packet timer */ + binary = XYFT_T; /* Switch to text mode */ + BEGIN generic; /* Switch to generic command state */ + } + } else { + errpkt((CHAR *)"Badly formed server command"); /* report error */ + RESUME; /* & go back to server command wait */ + } +#endif /* NOSERVER */ +} + +C { /* Receive Host command */ +#ifndef NOSERVER + if (x_login && !x_logged) { + errpkt((CHAR *)"Login required"); + SERVE; + } else if (!ENABLED(en_hos)) { + errpkt((CHAR *)"REMOTE HOST disabled"); + RESUME; + } else if (nopush) { + errpkt((CHAR *)"HOST commands not available"); + RESUME; + } else { + srvptr = srvcmd; /* Point to command buffer */ + decode(rdatap,putsrv,0); /* Decode command packet into it */ + putsrv(NUL); /* Null-terminate */ + nakstate = 0; /* Now sending, not receiving */ + binary = XYFT_T; /* Switch to text mode */ + if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */ + what = W_REMO; /* Doing a REMOTE command. */ +#ifdef STREAMING + if (!streaming) +#endif /* STREAMING */ + if (timint < 1) + timint = chktimo(rtimo,timef); /* Switch to per-packet timer */ +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE HOST", (char *)srvcmd); +#endif /* CKSYSLOG */ + BEGIN ssinit; /* If OK, send back its output */ + } else { /* Otherwise */ + errpkt((CHAR *)"Can't do system command"); /* report error */ + RESUME; /* & go back to server command wait */ + } + } +#endif /* NOSERVER */ +} + +q { /* Interrupted or connection lost */ + rc = srv_timeout(); + debug(F101,"srv_timeout","",rc); + if (rc > -1) return(rc); /* (see below) */ +} + +N { /* Server got a NAK in command-wait */ +#ifndef NOSERVER + errpkt((CHAR *)"Did you say RECEIVE instead of GET?"); + RESUME; +#endif /* NOSERVER */ +} + +. { /* Any other command in this state */ +#ifndef NOSERVER + if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */ + errpkt((CHAR *)"Unimplemented server function"); + /* If we answer an E with an E, we get an infinite loop. */ + /* A Y (ACK) can show up here if we sent back a short-form reply to */ + /* a G packet and it was echoed. ACKs can be safely ignored here. */ + RESUME; /* Go back to server command wait. */ +#endif /* NOSERVER */ +} + +I { /* Login/Out */ + rc = srv_login(); + debug(F101,"I srv_login","",rc); + if (rc > -1) return(rc); /* (see below) */ +} + +C { /* Got REMOTE CD command */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE CD", (char *)srvcmd); +#endif /* CKSYSLOG */ + if (!ENABLED(en_cwd)) { + errpkt((CHAR *)"REMOTE CD disabled"); + RESUME; + } else { + char * p = NULL; + x = cwd((char *)(srvcmd+1)); /* Try to change directory */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE CD", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!x) { /* Failed */ + errpkt((CHAR *)"Can't change directory"); + RESUME; /* Back to server command wait */ + } else if (x == 2) { /* User wants message */ + if (!ENABLED(en_typ)) { /* Messages (REMOTE TYPE) disabled? */ + errpkt((CHAR *)"REMOTE TYPE disabled"); + RESUME; + } else { /* TYPE is enabled */ + int i; + for (i = 0; i < 8; i++) { + if (zchki(cdmsgfile[i]) > -1) { + break; + } + } + binary = XYFT_T; /* Use text mode for this. */ + if (i < 8 && sndtype(cdmsgfile[i])) { /* Have readme file? */ + BEGIN ssinit; /* OK */ + } else { /* not OK */ + p = zgtdir(); + if (!p) p = ""; + success = (*p) ? 1 : 0; + ack1((CHAR *)p); /* ACK with new directory name */ + success = 1; + RESUME; /* wait for next server command */ + } + } + } else { /* User doesn't want message */ + p =zgtdir(); + if (!p) p = ""; + success = (*p) ? 1 : 0; + ack1((CHAR *)p); + success = 1; + RESUME; /* Wait for next server command */ + } + } +#endif /* NOSERVER */ +} + +A { /* Got REMOTE PWD command */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE PWD", NULL); +#endif /* CKSYSLOG */ + if (!ENABLED(en_cwd)) { + errpkt((CHAR *)"REMOTE CD disabled"); + RESUME; + } else { + if (encstr((CHAR *)zgtdir()) > -1) { /* Encode current directory */ + ack1(data); /* If it fits, send it back in ACK */ + success = 1; + } else { /* Failed */ + ack(); /* Send empty ACK */ + success = 0; /* and indicate failure locally */ + } + RESUME; /* Back to server command wait */ + } +#endif /* NOSERVER */ +} + +D { /* REMOTE DIRECTORY command */ +#ifndef NOSERVER + char *n2; +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE DIRECTORY", (char *)srvcmd); +#endif /* CKSYSLOG */ + if (!ENABLED(en_dir)) { /* If DIR is disabled, */ + errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */ + RESUME; + } else { /* DIR is enabled. */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE DIR", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!ENABLED(en_cwd)) { /* But CWD is disabled */ + zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */ + if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */ + errpkt((CHAR *)"Access denied"); + RESUME; /* Remember, this is not a goto! */ + } + } + if (state == generic) { /* It's OK to go ahead. */ +#ifdef COMMENT + n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2; + if (syscmd(n2,(char *)(srvcmd+2))) /* If it can be done */ +#else + int x; + if ((x = snddir((char*)(srvcmd+2))) > 0) +#endif /* COMMENT */ + { + BEGIN ssinit; /* send the results back; */ + } else { /* otherwise */ + if (x < 0) + errpkt((CHAR *)"No files match"); + else + errpkt((CHAR *)"Can't list directory"); + RESUME; /* return to server command wait */ + } + } + } +#endif /* NOSERVER */ +} + +E { /* REMOTE DELETE (Erase) */ +#ifndef NOSERVER + char *n2; +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE DELETE", (char *)srvcmd); +#endif /* CKSYSLOG */ + if (!ENABLED(en_del)) { + errpkt((CHAR *)"REMOTE DELETE disabled"); + RESUME; + } else { /* DELETE is enabled */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE DELETE", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!ENABLED(en_cwd)) { /* but CWD is disabled */ + zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */ + if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */ + errpkt((CHAR *)"Access denied"); + RESUME; /* Remember, this is not a goto! */ + } + } else if (isdir((char *)(srvcmd+2))) { /* A directory name? */ + errpkt((CHAR *)"It's a directory"); + RESUME; + } + if (state == generic) { /* It's OK to go ahead. */ + int x; + if ((x = snddel((char*)(srvcmd+2))) > 0) { + BEGIN ssinit; /* If OK send results back */ + } else { /* otherwise */ + if (x < 0) + errpkt((CHAR *)"File not found"); /* report failure */ + else + errpkt((CHAR *)"DELETE failed"); + RESUME; /* & return to server command wait */ + } + } + } +#endif /* NOSERVER */ +} + +F { /* FINISH */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "FINISH", NULL); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"SERVER FINISH", "", ""); +#endif /* IKSDB */ + if (!ENABLED(en_fin)) { + errpkt((CHAR *)"FINISH disabled"); + RESUME; + } else { + ack(); /* Acknowledge */ + xxscreen(SCR_TC,0,0L,""); /* Display */ + success = 1; + return(0); /* Done */ + } +#endif /* NOSERVER */ +} + +X { /* EXIT */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE EXIT", NULL); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE EXIT", "", ""); +#endif /* IKSDB */ + if (!ENABLED(en_xit)) { + errpkt((CHAR *)"EXIT disabled"); + RESUME; + } else { + ack(); /* Acknowledge */ + xxscreen(SCR_TC,0,0L,""); /* Display */ + doexit(GOOD_EXIT,xitsta); + } +#endif /* NOSERVER */ +} + +L { /* BYE (Logout) */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "BYE", NULL); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"SERVER BYE", "", ""); +#endif /* IKSDB */ + if (!ENABLED(en_bye)) { + errpkt((CHAR *)"BYE disabled"); + RESUME; + } else { + ack(); /* Acknowledge */ + success = 1; + msleep(750); /* Give the ACK time to get out */ + if (local) + ttres(); /* Reset the terminal */ + xxscreen(SCR_TC,0,0L,""); /* Display */ + doclean(1); /* Clean up files, etc */ +#ifdef DEBUG + debug(F100,"C-Kermit BYE - Loggin out...","",0); + zclose(ZDFILE); +#endif /* DEBUG */ +#ifdef IKSD +#ifdef CK_LOGIN + if (inserver) + ckxlogout(); + else +#endif /* CK_LOGIN */ +#endif /* IKSD */ +#ifdef TCPSOCKET +#ifndef NOLISTEN + if (network && tcpsrfd > 0 && !inserver) + doexit(GOOD_EXIT,xitsta); + else +#endif /* NOLISTEN */ +#endif /* TCPSOCKET */ + return(zkself()); /* Try to log self out */ + } +#endif /* NOSERVER */ +} + +H { /* REMOTE HELP */ +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE HELP", NULL); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE HELP", "", ""); +#endif /* IKSDB */ +#ifndef NOSERVER + if (sndhlp(NULL)) { + BEGIN ssinit; /* try to send it */ + } else { /* If not ok, */ + errpkt((CHAR *)"Can't send help"); /* send error message instead */ + RESUME; /* and return to server command wait */ + } +#endif /* NOSERVER */ +} + +R { /* REMOTE RENAME */ + rc = srv_rename(); + debug(F101,"srv_rename","",rc); + if (rc > -1) return(rc); /* (see below) */ +} + +K { /* REMOTE COPY */ + rc = srv_copy(); + debug(F101,"srv_copy","",rc); + if (rc > -1) return(rc); /* (see below) */ +} + +S { /* REMOTE SET */ +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE SET", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifndef NOSERVER +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE SET", (char *)(srvcmd+1), ""); +#endif /* IKSDB */ + if (!ENABLED(en_set)) { + errpkt((CHAR *)"REMOTE SET disabled"); + RESUME; + } else { + if (remset((char *)(srvcmd+1))) { /* Try to do what they ask */ + success = 1; + ack(); /* If OK, then acknowledge */ + } else /* Otherwise */ + errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */ + RESUME; /* Return to server command wait */ + } +#endif /* NOSERVER */ +} + +T { /* REMOTE TYPE */ +#ifndef NOSERVER + char *n2; +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE TYPE", (char *)srvcmd); +#endif /* CKSYSLOG */ + if (!ENABLED(en_typ)) { + errpkt((CHAR *)"REMOTE TYPE disabled"); + RESUME; + } else { +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE TYPE", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!ENABLED(en_cwd)) { /* If CWD disabled */ + zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */ + if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */ + errpkt((CHAR *)"Access denied"); + RESUME; /* Remember, this is not a goto! */ + } + } + if (state == generic) { /* It's OK to go ahead. */ + binary = XYFT_T; /* Use text mode for this. */ + if ( /* (RESUME didn't change state) */ +#ifdef COMMENT + syscmd(TYPCMD,(char *)(srvcmd+2)) /* Old way */ +#else + sndtype((char *)(srvcmd+2)) /* New way */ +#endif /* COMMENT */ + ) + BEGIN ssinit; /* OK */ + else { /* not OK */ + errpkt((CHAR *)"Can't type file"); /* give error message */ + RESUME; /* wait for next server command */ + } + } + } +#endif /* NOSERVER */ +} + +m { /* REMOTE MKDIR */ +#ifndef NOSERVER +#ifdef CK_MKDIR +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE MKDIR", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE MKDIR", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!ENABLED(en_mkd)) { + errpkt((CHAR *)"REMOTE MKDIR disabled"); + RESUME; + } else if (!ENABLED(en_cwd)) { /* If CWD disabled */ + errpkt((CHAR *)"Directory access restricted"); + RESUME; /* Remember, this is not a goto! */ + } + if (state == generic) { /* OK to go ahead. */ + char *p = NULL; + x = ckmkdir(0,(char *)(srvcmd+2),&p,0,1); /* Make the directory */ + if (!p) p = ""; + if (x > -1) { + encstr((CHAR *)p); /* OK - encode the name */ + ack1(data); /* Send short-form response */ + success = 1; + RESUME; + } else { /* not OK */ + if (!*p) p = "Directory creation failure"; + errpkt((CHAR *)p); /* give error message */ + RESUME; /* Wait for next server command */ + } + } +#else + errpkt((CHAR *)"REMOTE MKDIR not available"); + RESUME; +#endif /* CK_MKDIR */ +#endif /* NOSERVER */ +} + +d { /* REMOTE RMDIR */ +#ifndef NOSERVER +#ifdef CK_MKDIR +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE RMDIR", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE RMDIR", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!ENABLED(en_rmd)) { + errpkt((CHAR *)"REMOTE RMDIR disabled"); + RESUME; + } else if (!ENABLED(en_cwd)) { /* If CWD disabled */ + errpkt((CHAR *)"Directory access restricted"); + RESUME; /* Remember, this is not a goto! */ + } + if (state == generic) { /* OK to go ahead. */ + char *p = NULL; + x = ckmkdir(1,(char *)(srvcmd+2),&p,0,1); + if (!p) p = ""; + if (x > -1) { + encstr((CHAR *)p); /* OK - encode the name */ + ack1(data); /* Send short-form response */ + success = 1; + RESUME; + } else { /* not OK */ + if (!*p) p = "Directory removal failure"; + errpkt((CHAR *)p); /* give error message */ + RESUME; /* Wait for next server command */ + } + } +#else + errpkt((CHAR *)"REMOTE RMDIR not available"); + RESUME; +#endif /* CK_MKDIR */ +#endif /* NOSERVER */ +} + +U { /* REMOTE SPACE */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE SPACE", (char *)srvcmd); +#endif /* CKSYSLOG */ + if (!ENABLED(en_spa)) { + errpkt((CHAR *)"REMOTE SPACE disabled"); + RESUME; + } else { + x = srvcmd[1]; /* Get area to check */ + x = ((x == NUL) || (x == SP) +#ifdef OS2 + || (x == '!') || (srvcmd[3] == ':') +#endif /* OS2 */ + ); +#ifdef IKSDB + if (ikdbopen) slotstate(what, + "REMOTE SPACE", + (x ? "" : (char *)srvcmd), + "" + ); +#endif /* IKSDB */ + if (!x && !ENABLED(en_cwd)) { /* CWD disabled */ + errpkt((CHAR *)"Access denied"); /* and non-default area given, */ + RESUME; /* refuse. */ + } else { +#ifdef OS2 +_PROTOTYP(int sndspace,(int)); + if (sndspace(x ? toupper(srvcmd[2]) : 0)) { + BEGIN ssinit; /* send the report. */ + } else { /* If not ok, */ + errpkt((CHAR *)"Can't send space"); /* send error message */ + RESUME; /* and return to server command wait */ + } +#else + if (nopush) + x = 0; + else + x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2))); + if (x) { /* If we got the info */ + BEGIN ssinit; /* send it */ + } else { /* otherwise */ + errpkt((CHAR *)"Can't check space"); /* send error message */ + RESUME; /* and await next server command */ + } +#endif /* OS2 */ + } + } +#endif /* NOSERVER */ +} + +W { /* REMOTE WHO */ +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE WHO", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE WHO", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + if (!ENABLED(en_who)) { + errpkt((CHAR *)"REMOTE WHO disabled"); + RESUME; + } else { +#ifdef OS2 +_PROTOTYP(int sndwho,(char *)); + if (sndwho((char *)(srvcmd+2))) { + BEGIN ssinit; /* try to send it */ + } else { /* If not ok, */ + errpkt((CHAR *)"Can't do who command"); /* send error msg */ + RESUME; /* and return to server command wait */ + } +#else + if (syscmd(WHOCMD,(char *)(srvcmd+2))) { + BEGIN ssinit; + } else { + errpkt((CHAR *)"Can't do who command"); + RESUME; + } +#endif /* OS2 */ + } +#endif /* NOSERVER */ +} + +V { /* Variable query or set */ + rc = srv_query(); + debug(F101,"srv_query","",rc); + if (rc > -1) return(rc); +} + +q { /* Interrupted or connection lost */ +#ifndef NOSERVER + if (fatalio) { /* Connection lost */ +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL); +#endif /* CKSYSLOG */ + success = 0; + xitsta |= (what & W_KERMIT); + QUIT; + } else if (interrupted) { + if (!ENABLED(en_fin)) { /* Ctrl-C typed */ + errpkt((CHAR *)"QUIT disabled"); + RESUME; + } else { +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL); +#endif /* CKSYSLOG */ + success = 0; + xitsta |= (what & W_KERMIT); + QUIT; + } + } else { /* Shouldn't happen */ + debug(F100,"SERVER (generic) GOT UNEXPECTED 'q'","",0); + QUIT; + } +#endif /* NOSERVER */ +} + +. { /* Anything else in this state... */ +#ifndef NOSERVER + errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */ + RESUME; /* and return to server command wait */ +#endif /* NOSERVER */ +} + +q { /* Sent BYE and connection broken */ + if (bye_active && ttchk() < 0) { + msleep(500); + bye_active = 0; + ttclos(0); /* Close our end of the connection */ + clsof(0); + return(success = 1); + } else { /* Other generic command */ + return(success = 0); /* or connection not broken */ + } +} + +Y { /* Short-Form reply */ + rc = rcv_shortreply(); + debug(F101,"Y rcv_shortreply","",rc); + if (rc > -1) return(rc); +} + +F { /* File header */ + /* char *n2; */ + extern int rsn; + debug(F101,"F winlo 1","",winlo); + xflg = 0; /* Not screen data */ + if (!czseen) + cancel = 0; /* Reset cancellation counter */ +#ifdef CALIBRATE + if (dest == DEST_N) + calibrate = 1; +#endif /* CALIBRATE */ + if (!rcvfil(filnam)) { /* Figure out local filename */ + errpkt((CHAR *)rf_err); /* Trouble */ + RESUME; + } else { /* Real file, OK to receive */ + char * fnp; + debug(F111,"F winlo 2",fspec,winlo); + if (filcnt == 1) /* rcvfil set this to 1 for 1st file */ + crc16 = 0L; /* Clear file CRC */ + fnp = fspec; /* This is the full path */ + if (server && !ENABLED(en_cwd) || /* if DISABLE CD */ + !fackpath /* or F-ACK-PATH OFF */ + ) { + zstrip(fspec,&fnp); /* don't send back full path */ + } + encstr((CHAR *)fnp); + if (fackbug) + ack(); + else + ack1(data); /* Send it back in ACK */ + initattr(&iattr); /* Clear file attribute structure */ + streamon(); + if (window(wslotn) < 0) { /* Allocate negotiated window slots */ + errpkt((CHAR *)"Can't open window"); + RESUME; + } +#ifdef IKSDB + if (ikdbopen) slotstate(what, + server ? "SERVER" : "", + "RECEIVE", + fspec + ); +#endif /* IKSDB */ + BEGIN rattr; /* Now expect Attribute packets */ + } +} + +X { /* X-packet instead of file header */ + xflg = 1; /* Screen data */ + if (!czseen) + cancel = 0; /* Reset cancellation counter */ + ack(); /* Acknowledge the X-packet */ + initattr(&iattr); /* Initialize attribute structure */ + streamon(); + if (window(wslotn) < 0) { /* allocate negotiated window slots */ + errpkt((CHAR *)"Can't open window"); + RESUME; + } +#ifndef NOSPL + if (query) { /* If this is the response to */ + qbufp = querybuf; /* a query that we sent, initialize */ + qbufn = 0; /* the response buffer */ + querybuf[0] = NUL; + } +#endif /* NOSPL */ + what = W_REMO; /* we're doing a REMOTE command */ +#ifdef IKSDB + if (ikdbopen) slotstate(what, + server ? "SERVER" : "", + "RECEIVE", + fspec + ); +#endif /* IKSDB */ + BEGIN rattr; /* Expect Attribute packets */ +} + +A { /* Attribute packet */ + if (gattr(rdatap,&iattr) == 0) { /* Read into attribute structure */ +#ifdef CK_RESEND + ack1((CHAR *)iattr.reply.val); /* Reply with data */ +#else + ack(); /* If OK, acknowledge */ +#endif /* CK_RESEND */ + } else { /* Otherwise */ + extern long fsize; + char *r; + r = getreason(iattr.reply.val); + ack1((CHAR *)iattr.reply.val); /* refuse to accept the file */ + xxscreen(SCR_ST,ST_REFU,0L,r); /* reason */ +#ifdef TLOG + if (tralog && !tlogfmt) + doxlog(what,filnam,fsize,binary,1,r); +#endif /* TLOG */ + } +} + +D { /* First data packet */ + debug(F100," D firstdata","",0); + rc = rcv_firstdata(); + debug(F101,"rcv_firstdata rc","",rc); + if (rc > -1) return(rc); /* (see below) */ +} + +B { /* EOT, no more files */ + ack(); /* Acknowledge the B packet */ + reot(); /* Do EOT things */ +#ifdef CK_TMPDIR +/* If we were cd'd temporarily to another device or directory ... */ + if (f_tmpdir) { + int x; + x = zchdir((char *) savdir); /* ... restore previous directory */ + f_tmpdir = 0; /* and remember we did it. */ + debug(F111,"ckcpro.w B tmpdir restoring",savdir,x); + } +#endif /* CK_TMPDIR */ + RESUME; /* and quit */ +} + +D { /* Got Data packet */ + debug(F101,"D cxseen","",cxseen); + debug(F101,"D czseen","",czseen); + if (cxseen || czseen || discard) { /* If file or group interruption */ + CHAR * msg; + msg = czseen ? (CHAR *)"Z" : (CHAR *)"X"; +#ifdef STREAMING + if (streaming) { /* Need to cancel */ + debug(F111,"D streaming cancel",msg,cancel); + if (cancel++ == 0) { /* Only do this once */ + ack1(msg); /* Put "X" or "Z" in ACK */ + } else if (czseen) { + errpkt((CHAR *)"User canceled"); + RESUME; + } else { + fastack(); + } + } else +#endif /* STREAMING */ + ack1(msg); + } else { /* No interruption */ + int rc, qf; +#ifndef NOSPL + qf = query; +#else + qf = 0; +#endif /* NOSPL */ +#ifdef CKTUNING + rc = (binary && !parity) ? + bdecode(rdatap,putfil): + decode(rdatap, qf ? puttrm : putfil, 1); +#else + rc = decode(rdatap, qf ? puttrm : putfil, 1); +#endif /* CKTUNING */ + if (rc < 0) { + discard = (keep == 0 || (keep == SET_AUTO && binary != XYFT_T)); + errpkt((CHAR *)"Error writing data"); /* If failure, */ + RESUME; + } else /* Data written OK, send ACK */ +#ifdef STREAMING + if (streaming) + fastack(); + else +#endif /* STREAMING */ + ack(); + } +} + +Z { /* EOF immediately after A-Packet. */ + rf_err = "Can't create file"; + timint = s_timint; + if (discard) { /* Discarding a real file... */ + x = 1; + } else if (xflg) { /* If screen data */ + if (remfile) { /* redirected to file */ + if (rempipe) /* or pipe */ + x = openc(ZOFILE,remdest); /* Pipe: start command */ + else + x = opena(remdest,&iattr); /* File: open with attributes */ + } else { /* otherwise */ + x = opent(&iattr); /* "open" the screen */ + } +#ifdef CALIBRATE + } else if (calibrate) { /* If calibration run */ + x = ckopenx(&iattr); /* do this */ +#endif /* CALIBRATE */ + } else { /* otherwise */ + x = opena(filnam,&iattr); /* open the file, with attributes */ + if (x == -17) { /* REGET skipped because same size */ + discard = 1; + rejection = 1; + } + } + if (!x || reof(filnam, &iattr) < 0) { /* Close output file */ + errpkt((CHAR *) rf_err); /* If problem, send error msg */ + RESUME; /* and quit */ + } else { /* otherwise */ + if (x == -17) + xxscreen(SCR_ST,ST_SKIP,SKP_RES,""); + ack(); /* acknowledge the EOF packet */ + BEGIN rfile; /* and await another file */ + } +} + +q { /* Ctrl-C or connection loss. */ + timint = s_timint; + window(1); /* Set window size back to 1... */ + cxseen = 1; + x = clsof(1); /* Close file */ + return(success = 0); /* Failed */ +} + +Z { /* End Of File (EOF) Packet */ +/* wslots = 1; */ /* (don't set) Window size back to 1 */ +#ifndef COHERENT /* Coherent compiler blows up on this switch() statement. */ + x = reof(filnam, &iattr); /* Handle the EOF packet */ + switch (x) { /* reof() sets the success flag */ + case -5: /* Handle problems */ + errpkt((CHAR *)"RENAME failed"); /* Fatal */ + RESUME; + break; + case -4: + errpkt((CHAR *)"MOVE failed"); /* Fatal */ + RESUME; + break; + case -3: /* If problem, send error msg */ + errpkt((CHAR *)"Can't print file"); /* Fatal */ + RESUME; + break; + case -2: + errpkt((CHAR *)"Can't mail file"); /* Fatal */ + RESUME; + break; + case 2: /* Not fatal */ + case 3: + xxscreen(SCR_EM,0,0L,"Receiver can't delete temp file"); + RESUME; + break; + default: + if (x < 0) { /* Fatal */ + errpkt((CHAR *)"Can't close file"); + RESUME; + } else { /* Success */ +#ifndef NOSPL + if (query) /* Query reponses generally */ + conoll(""); /* don't have line terminators */ +#endif /* NOSPL */ + if (czseen) { /* Batch canceled? */ + if (cancel++ == 0) { /* If we haven't tried this yet */ + ack1((CHAR *)"Z"); /* Try it once */ + } else { /* Otherwise */ + errpkt((CHAR *)"User canceled"); /* quite with Error */ + RESUME; + } + } else + ack(); /* Acknowledge the EOF packet */ + BEGIN rfile; /* and await another file */ + } + } +#else + if (reof(filnam, &iattr) < 0) { /* Close the file */ + errpkt((CHAR *)"Error at end of file"); + RESUME; + } else { /* reof() sets success flag */ + ack(); + BEGIN rfile; + } +#endif /* COHERENT */ +} + +Y { /* ACK for Send-Init */ + spar(rdatap); /* set parameters from it */ + cancel = 0; + bctu = bctr; /* switch to agreed-upon block check */ + bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */ +#ifdef CK_RESEND + if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */ + errpkt((CHAR *) "RESEND capabilities not negotiated"); + RESUME; + } else { +#endif /* CK_RESEND */ + what = W_SEND; /* Remember we're sending */ + lastxfer = W_SEND; + x = sfile(xflg); /* Send X or F header packet */ + cancel = 0; /* Reset cancellation counter */ + if (x) { /* If the packet was sent OK */ + if (!xflg && filcnt == 1) /* and it's a real file */ + crc16 = 0L; /* Clear the file CRC */ + resetc(); /* reset per-transaction counters */ + rtimer(); /* reset timers */ +#ifdef GFTIMER + rftimer(); +#endif /* GFTIMER */ + streamon(); /* turn on streaming */ +#ifdef IKSDB + if (ikdbopen) slotstate(what, + (server ? "SERVER" : ""), + "SEND", + filnam + ); +#endif /* IKSDB */ + BEGIN ssfile; /* and switch to receive-file state */ + } else { /* otherwise send error msg & quit */ + s = xflg ? "Can't execute command" : (char *)epktmsg; + if (!*s) s = "Can't open file"; + errpkt((CHAR *)s); + RESUME; + } +#ifdef CK_RESEND + } +#endif /* CK_RESEND */ +} + +/* + These states are necessary to handle the case where we get a server command + packet (R, G, or C) reply with an S packet, but the client retransmits the + command packet. The input() function doesn't catch this because the packet + number is still zero. +*/ +R { /* R packet was retransmitted. */ + xsinit(); /* Resend packet 0 */ +} + +G { /* Same deal if G packet comes again */ + xsinit(); +} + +/* should probably add cases for O, W, V, H, J, ... */ + +C { /* Same deal if C packet comes again */ + xsinit(); +} + +Y { /* ACK for F or X packet */ + srvptr = srvcmd; /* Point to string buffer */ + decode(rdatap,putsrv,0); /* Decode data field, if any */ + putsrv(NUL); /* Terminate with null */ + ffc = 0L; /* Reset file byte counter */ + debug(F101,"Y cxseen","",cxseen); + if (*srvcmd) { /* If remote name was recorded */ + if (sendmode != SM_RESEND) { + if (fdispla == XYFD_C || fdispla == XYFD_S) + xxscreen(SCR_AN,0,0L,(char *)srvcmd); + tlog(F110," remote name:",(char *) srvcmd,0L); + makestr(&psrfspec,(char *)srvcmd); + } + } + if (cxseen||czseen) { /* Interrupted? */ + debug(F101,"Y canceling","",0); + x = clsif(); /* Close input file */ + sxeof(1); /* Send EOF(D) */ + BEGIN sseof; /* and switch to EOF state. */ + } else if (atcapu) { /* If attributes are to be used */ + if (sattr(xflg | stdinf, 1) < 0) { /* send them */ + errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */ + RESUME; /* and quit */ + } else BEGIN ssattr; /* if ok, switch to attribute state */ + } else { /* Attributes not negotiated */ + if (window(wslotn) < 0) { /* Open window */ + errpkt((CHAR *)"Can't open window"); + RESUME; + } else if ((x = sdata()) == -2) { /* Send first data packet data */ + window(1); /* Connection lost, reset window */ + x = clsif(); /* Close input file */ + return(success = 0); /* Return failure */ + } else if (x == -9) { /* User interrupted */ + errpkt((CHAR *)"User cancelled"); /* Send Error packet */ + window(1); /* Set window size back to 1... */ + timint = s_timint; /* Restore timeout */ + return(success = 0); /* Failed */ + } else if (x < 0) { /* EOF (empty file) or interrupted */ + window(1); /* put window size back to 1, */ + debug(F101,"Y cxseen","",cxseen); + x = clsif(); /* If not ok, close input file, */ + if (x < 0) /* treating failure as interruption */ + cxseen = 1; /* Send EOF packet */ + seof(cxseen||czseen); + BEGIN sseof; /* and switch to EOF state. */ + } else { /* First data sent OK */ + BEGIN ssdata; /* All ok, switch to send-data state */ + } + } +} + +Y { /* Got ACK to A packet */ + ffc = 0L; /* Reset file byte counter */ + debug(F101,"Y cxseen","",cxseen); + if (cxseen||czseen) { /* Interrupted? */ + debug(F101,"Y canceling","",0); + x = clsif(); /* Close input file */ + sxeof(1); /* Send EOF(D) */ + BEGIN sseof; /* and switch to EOF state. */ + } else if (rsattr(rdatap) < 0) { /* Was the file refused? */ + discard = 1; /* Set the discard flag */ + clsif(); /* Close the file */ + sxeof(1); /* send EOF with "discard" code */ + BEGIN sseof; /* switch to send-EOF state */ + } else if ((x = sattr(xflg | stdinf, 0)) < 0) { /* Send more? */ + errpkt((CHAR *)"Can't send attributes"); /* Trouble... */ + RESUME; + } else if (x == 0) { /* No more to send so now the data */ + if (window(wslotn) < 0) { /* Allocate negotiated window slots */ + errpkt((CHAR *)"Can't open window"); + RESUME; + } + if ((x = sdata()) == -2) { /* File accepted, send first data */ + window(1); /* Connection broken */ + x = clsif(); /* Close file */ + return(success = 0); /* Return failure */ + } else if (x == -9) { /* User interrupted */ + errpkt((CHAR *)"User cancelled"); /* Send Error packet */ + window(1); /* Set window size back to 1... */ + timint = s_timint; /* Restore timeout */ + return(success = 0); /* Failed */ + } else if (x < 0) { /* If data was not sent */ + window(1); /* put window size back to 1, */ + debug(F101,"Y cxseen","",cxseen); + if (clsif() < 0) /* Close input file */ + cxseen = 1; /* Send EOF packet */ + seof(cxseen||czseen); + BEGIN sseof; /* and switch to EOF state. */ + } else { + BEGIN ssdata; /* All ok, switch to send-data state */ + } + } +} + +q { /* Ctrl-C or connection loss. */ + window(1); /* Set window size back to 1... */ + cxseen = 1; /* To indicate interruption */ + x = clsif(); /* Close file */ + return(success = 0); /* Failed */ +} + +Y { /* Got ACK to Data packet */ + canned(rdatap); /* Check if file transfer cancelled */ + debug(F111,"Y cxseen",rdatap,cxseen); + debug(F111,"Y czseen",rdatap,czseen); + if ((x = sdata()) == -2) { /* Try to send next data */ + window(1); /* Connection lost, reset window */ + x = clsif(); /* Close file */ + return(success = 0); /* Failed */ + } else if (x == -9) { /* User interrupted */ + errpkt((CHAR *)"User cancelled"); /* Send Error packet */ + window(1); /* Set window size back to 1... */ + timint = s_timint; /* Restore original timeout */ + return(success = 0); /* Failed */ + } else if (x < 0) { /* EOF - finished sending data */ + debug(F101,"Y cxseen","",cxseen); + window(1); /* Set window size back to 1... */ + if (clsif() < 0) /* Close input file */ + cxseen = 1; /* Send EOF packet */ + debug(F101,"Y CALLING SEOF()","",cxseen); + seof(cxseen||czseen); + BEGIN sseof; /* and enter send-eof state */ + } + /* NOTE: If x == 0 it means we're draining: see sdata()! */ +} + +Y { /* Got ACK to EOF */ + int g, xdiscard; + canned(rdatap); /* Check if file transfer cancelled */ + debug(F111,"Y cxseen",rdatap,cxseen); + debug(F111,"Y czseen",rdatap,czseen); + debug(F111,"Y discard",rdatap,discard); + xdiscard = discard; + discard = 0; + success = (cxseen == 0 && czseen == 0); /* Transfer status... */ + debug(F101,"Y success","",success); + if (success && rejection > 0) /* If rejected, succeed if */ + if (rejection != '#' && /* reason was date */ + rejection != 1 && rejection != '?') /* or name; */ + success = 0; /* fail otherwise. */ + cxseen = 0; /* This goes back to zero. */ + if (success) { /* Only if transfer succeeded... */ + xxscreen(SCR_ST,ST_OK,0L,""); + if (!xdiscard) { + makestr(&sfspec,psfspec); /* Record filenames for WHERE */ + makestr(&srfspec,psrfspec); + } + if (moving) { /* If MOVE'ing */ + x = zdelet(filnam); /* Try to delete the source file */ +#ifdef TLOG + if (tralog) { + if (x > -1) { + tlog(F110," deleted",filnam,0); + } else { + tlog(F110," delete failed:",ck_errstr(),0); + } + } +#endif /* TLOG */ + } else if (snd_move) { /* Or move it */ + int x; + x = zrename(filnam,snd_move); +#ifdef TLOG + if (tralog) { + if (x > -1) { + tlog(F110," moved to ",snd_move,0); + } else { + tlog(F110," move failed:",ck_errstr(),0); + } + } +#endif /* TLOG */ + } else if (snd_rename) { /* Or rename it */ + char *s = snd_rename; /* Renaming string */ +#ifndef NOSPL + int y; /* Pass it thru the evaluator */ + extern int cmd_quoting; /* for \v(filename) */ + if (cmd_quoting) { /* But only if cmd_quoting is on */ + y = MAXRP; + s = (char *)srvcmd; + zzstring(snd_rename,&s,&y); + s = (char *)srvcmd; + } +#endif /* NOSPL */ + if (s) if (*s) { + int x; + x = zrename(filnam,s); +#ifdef TLOG + if (tralog) { + if (x > -1) { + tlog(F110," renamed to",s,0); + } else { + tlog(F110," rename failed:",ck_errstr(),0); + } + } +#endif /* TLOG */ +#ifdef COMMENT + *s = NUL; +#endif /* COMMENT */ + } + } + } + if (czseen) { /* Check group interruption flag */ + g = 0; /* No more files if interrupted */ + } else { /* Otherwise... */ +#ifdef COMMENT + /* This code makes any open error fatal to a file-group transfer. */ + g = gnfile(); + debug(F111,"Y gnfile",filnam,g); + if (g > 0) { /* Any more files to send? */ + if (sfile(xflg)) /* Yes, try to send next file header */ + BEGIN ssfile; /* if ok, enter send-file state */ + else { /* otherwise */ + s = xflg ? "Can't execute command" : (char *)epktmsg; + if (!*s) s = "Can't open file"; + errpkt((CHAR *)s); /* send error message */ + RESUME; /* and quit */ + } + } else { /* No next file */ + tsecs = gtimer(); /* get statistics timers */ +#ifdef GFTIMER + fptsecs = gftimer(); +#endif /* GFTIMER */ + seot(); /* send EOT packet */ + BEGIN sseot; /* enter send-eot state */ + } +#else /* COMMENT */ + while (1) { /* Keep trying... */ + g = gnfile(); /* Get next file */ + debug(F111,"Y gnfile",filnam,g); + if (g == 0 && gnferror == 0) /* No more, stop trying */ + break; + if (g > 0) { /* Have one */ + if (sfile(xflg)) { /* Try to open and send F packet */ + BEGIN ssfile; /* If OK, enter send-file state */ + break; /* and break out of loop. */ + } + } /* Otherwise keep trying to get one we can send... */ + } + } + if (g == 0) { + debug(F101,"Y no more files","",czseen); + tsecs = gtimer(); /* Get statistics timers */ +#ifdef GFTIMER + fptsecs = gftimer(); +#endif /* GFTIMER */ + seot(); /* Send EOT packet */ + BEGIN sseot; /* Enter send-eot state */ + } +#endif /* COMMENT */ +} + +Y { /* Got ACK to EOT */ + debug(F101,"sseot justone","",justone); + RESUME; /* All done, just quit */ +} + +E { /* Got Error packet, in any state */ + char *s = ""; + window(1); /* Close window */ + timint = s_timint; /* Restore original timeout */ + if (*epktmsg) /* Message from Error packet */ + s = (char *)epktmsg; + if (!*s) { /* If not there then maybe here */ + s = (char *)rdatap; + ckstrncpy((char *)epktmsg,(char *)rdatap,PKTMSGLEN); + } + if (!*s) /* Hopefully we'll never see this. */ + s = "Unknown error"; + success = 0; /* For IF SUCCESS/FAIL. */ + debug(F101,"ckcpro.w justone at E pkt","",justone); + + success = 0; /* Transfer failed */ + xferstat = success; /* Remember transfer status */ + if (!epktsent) { + x = quiet; quiet = 1; /* Close files silently, */ + epktrcvd = 1; /* Prevent messages from clsof() */ + clsif(); + clsof(1); /* discarding any output file. */ + ermsg(s); /* Issue the message (calls screen). */ + quiet = x; /* Restore quiet state */ + } + tstats(); /* Get stats */ +/* + If we are executing commands from a command file or macro, let the command + file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR. +*/ + if ( +#ifndef NOICP + !xcmdsrc && +#endif /* NOICP */ + backgrd && !server) + fatal("Protocol error"); + xitsta |= (what & W_KERMIT); /* Save this for doexit(). */ +#ifdef CK_TMPDIR +/* If we were cd'd temporarily to another device or directory ... */ + if (f_tmpdir) { + int x; + x = zchdir((char *) savdir); /* ... restore previous directory */ + f_tmpdir = 0; /* and remember we did it. */ + debug(F111,"ckcpro.w E tmpdir restored",savdir,x); + } +#endif /* CK_TMPDIR */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"ERROR", (char *)epktmsg, ""); +#endif /* IKSDB */ + RESUME; +} + +q { success = 0; QUIT; } /* Ctrl-C or connection loss. */ + +. { /* Anything not accounted for above */ + errpkt((CHAR *)"Unexpected packet type"); /* Give error message */ + window(1); + xitsta |= (what & W_KERMIT); /* Save this for doexit(). */ + RESUME; /* and quit */ +} + +%% + +/* + From here down to proto() are routines that were moved out of the state + table switcher because the resulting switch() had become too large. + To move the contents of a state-table case to a routine: + 1. Add a prototype to the list above the state table switcher. + 2. Make a routine with an appropriate name, returning int. + 3. Move the code into it. + 4. Put a call to the new routine in the former spot: + rc = name_of_routine(); + if (rc > -1) return(rc); + 5. Add "return(-1);" after every RESUME, SERVE, or BEGIN macro and + at the end if the code is open-ended. +*/ +static int +rcv_firstdata() { + extern int dispos; + debug(F101,"rcv_firstdata","",dispos); + + if (discard) { /* if we're discarding the file */ + ack1((CHAR *)"X"); /* just ack the data like this. */ + cancel++; /* and count it */ + BEGIN rdpkt; /* and wait for more data packets. */ + return(-1); + } else { /* Not discarding. */ + rf_err = "Can't open file"; + if (xflg) { /* If screen data */ + if (remfile) { /* redirected to file */ + if (rempipe) /* or pipe */ + x = openc(ZOFILE,remdest); /* Pipe: start command */ + else + x = opena(remdest,&iattr); /* File: open with attributes */ + } else { /* otherwise */ + x = opent(&iattr); /* "open" the screen */ + } + } else { /* otherwise */ +#ifdef CALIBRATE + if (calibrate) { /* If calibration run */ + x = ckopenx(&iattr); /* open nothing */ +#ifdef STREAMING + if (streaming) /* Streaming */ + fastack(); /* ACK without ACKing. */ + else +#endif /* STREAMING */ + ack(); /* Send real ACK */ + BEGIN rdpkt; /* Proceed to next state */ + return(-1); + } else +#endif /* CALIBRATE */ +#ifdef UNIX +/* + In UNIX we can pipe the file data into the mail program, which is to be + preferred to writing it out to a temp file and then mailing it afterwards. + This depends rather heavily on all UNIXes having a mail command that + accepts '-s "subject"' on the command line. MAILCMD (e.g. mail, Mail, mailx) + is defined in ckufio.c. +*/ + if (dispos == 'M') { /* Mail... */ + char *s; + char * tmp = NULL; + int n = 0; + extern char *MAILCMD; + s = iattr.disp.val + 1; + n = (int)strlen(MAILCMD) + /* Mail command */ + (int)strlen(s) + /* address */ + (int)strlen(ofilnam) + 32; /* subject */ + if (tmp = (char *)malloc(n)) { + ckmakxmsg(tmp,n, + MAILCMD," -s \"",ofilnam,"\" ",s, + NULL,NULL,NULL,NULL,NULL,NULL,NULL); + debug(F111,"rcv_firsdata mail",tmp,(int)strlen(tmp)); + x = openc(ZOFILE,(char *)tmp); + free(tmp); + } else + x = 0; + } else if (dispos == 'P') { /* Ditto for print */ + char * tmp = NULL; + int n; + extern char *PRINTCMD; + n = (int)strlen(PRINTCMD) + (int)strlen(iattr.disp.val+1) + 4; + if (tmp = (char *)malloc(n)) { + sprintf(tmp, /* safe (prechecked) */ + "%s %s", PRINTCMD, iattr.disp.val + 1); + x = openc(ZOFILE,(char *)tmp); + free(tmp); + } else + x = 0; + } else +#endif /* UNIX */ + x = opena(filnam,&iattr); /* open the file, with attributes */ + } + if (x) { /* If file was opened ok */ + int rc, qf; +#ifndef NOSPL + qf = query; +#else + qf = 0; +#endif /* NOSPL */ + +#ifdef CKTUNING + rc = (binary && !parity) ? + bdecode(rdatap,putfil): + decode(rdatap, qf ? puttrm : putfil, 1); +#else + rc = decode(rdatap, qf ? puttrm : putfil, 1); +#endif /* CKTUNING */ + if (rc < 0) { + errpkt((CHAR *)"Error writing data"); + RESUME; + return(-1); + } +#ifdef STREAMING + if (streaming) /* Streaming was negotiated */ + fastack(); /* ACK without ACKing. */ + else +#endif /* STREAMING */ + ack(); /* acknowledge it */ + BEGIN rdpkt; /* and switch to receive-data state */ + return(-1); + } else { /* otherwise */ + errpkt((CHAR *) rf_err); /* send error packet */ + RESUME; /* and quit. */ + return(-1); + } + } +} + +static int +rcv_shortreply() { +#ifdef PKTZEROHACK + success = 0; + debug(F111,"rcv_shortreply",rdatap,ipktlen); + if (ipktack[0] && !strncmp(ipktack,(char *)rdatap,ipktlen)) { + /* No it's the ACK to the I packet again */ + x = scmd(vcmd,(CHAR *)cmarg); /* So send the REMOTE command again */ + /* Maybe this should be resend() */ + debug(F110,"IPKTZEROHACK",ipktack,x); + if (x < 0) { + errpkt((CHAR *)srimsg); + RESUME; + return(-1); + } + } else { + ipktack[0] = NUL; +#endif /* PKTZEROHACK */ + urserver = 1; +#ifndef NOSERVER +#ifndef NOSPL + if (query) { /* If to query, */ + qbufp = querybuf; /* initialize query response buffer */ + qbufn = 0; + querybuf[0] = NUL; + } +#endif /* NOSPL */ + x = 1; + if (remfile) { /* Response redirected to file */ + rf_err = "Can't open file"; + if (rempipe) /* or pipe */ + x = +#ifndef NOPUSH + zxcmd(ZOFILE,remdest) /* Pipe: Start command */ +#else + 0 +#endif /* NOPUSH */ + ; + else + x = opena(remdest,&iattr); /* File: Open with attributes */ + debug(F111,"rcv_shortreply remfile",remdest,x); + } else { + x = opent(&iattr); /* "open" the screen */ + } + if (x) { /* If file was opened ok */ + if (decode(rdatap, +#ifndef NOSPL + (query || !remfile) ? puttrm : +#else + !remfile ? puttrm : +#endif /* NOSPL */ + zputfil, 1) < 0) { /* Note: zputfil, not putfil. */ + errpkt((CHAR *)"Error writing data"); + RESUME; + return(-1); + } else { + if (rdatap) /* If we had data */ + if (*rdatap) /* add a line terminator */ + if (remfile) { /* to file */ + zsoutl(ZOFILE,""); + } else { /* or to screen. */ +#ifndef NOICP + if (!query || !xcmdsrc) +#endif /* NOICP */ + if (!(quiet && rcdactive)) + conoll(""); + } + if (bye_active && network) { /* I sent BYE or REMOTE LOGOUT */ + msleep(500); /* command and got the ACK... */ + bye_active = 0; + ttclos(0); + } + clsof(0); + if (!epktsent && !epktrcvd) /* If no error packet... */ + success = 1; /* success. */ + RESUME; + return(-1); + } + } else { /* File not opened OK */ + errpkt((CHAR *) rf_err); /* send error message */ + RESUME; /* and quit. */ + return(-1); + } +#endif /* NOSERVER */ +#ifdef PKTZEROHACK + } +#endif /* PKTZEROHACK */ + debug(F101,"rcv_shortreply fallthru","",success); + return(-1); +} + + +static int +srv_query() { +#ifndef NOSERVER +#ifndef NOSPL + char c; +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE QUERY", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE QUERY", (char *)(srvcmd+2), ""); +#endif /* IKSDB */ + c = *(srvcmd+2); /* Q = Query, S = Set */ + if (c == 'Q') { /* Query */ + if (!ENABLED(en_que)) { /* Security */ + errpkt((CHAR *)"REMOTE QUERY disabled"); + RESUME; + return(-1); + } else { /* Query allowed */ + int n; char *p, *q; + qbufp = querybuf; /* Wipe out old stuff */ + qbufn = 0; + querybuf[0] = NUL; + p = (char *) srvcmd + 3; /* Pointer for making wrapper */ + n = strlen((char *)srvcmd); /* Position of end */ + c = *(srvcmd+4); /* Which type of variable */ + + if (*(srvcmd+6) == CMDQ) { /* Starts with command quote? */ + p = (char *) srvcmd + 6; /* Take it literally */ + if (*p == CMDQ) p++; + } else { /* They played by the rules */ + if (c == 'K') { /* Kermit variable */ + int k; + k = (int) strlen(p); + if (k > 0 && p[k-1] == ')') { + p = (char *)(srvcmd + 4); + *(srvcmd+4) = CMDQ; + *(srvcmd+5) = 'f'; /* Function, so make it \f...() */ + } else { + *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */ + *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */ + *(srvcmd+5) = '('; /* around variable name */ + *(srvcmd+n) = ')'; + *(srvcmd+n+1) = NUL; + } + } else { + *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */ + *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */ + *(srvcmd+5) = '('; /* around variable name */ + *(srvcmd+n) = ')'; + *(srvcmd+n+1) = NUL; + if (c == 'S') { /* System variable */ + *(srvcmd+4) = '$'; /* so it's \$(...) */ + } else if (c == 'G') { /* Non-\ Global variable */ + *(srvcmd+4) = 'm'; /* so wrap it in \m(...) */ + } + } + } /* Now evaluate it */ + n = QBUFL; /* Max length */ + q = querybuf; /* Where to put it */ + if (zzstring(p,&q,&n) < 0) { + errpkt((n > 0) ? (CHAR *)"Can't get value" + : (CHAR *)"Value too long" + ); + RESUME; + return(-1); + } else { + if (encstr((CHAR *)querybuf) > -1) { /* Encode it */ + ack1(data); /* If it fits, send it back in ACK */ + success = 1; + RESUME; + return(-1); + } else if (sndstring(querybuf)) { /* Long form response */ + BEGIN ssinit; + return(-1); + } else { /* sndhlp() fails */ + errpkt((CHAR *)"Can't send value"); + RESUME; + return(-1); + } + } + } + } else if (c == 'S') { /* Set (assign) */ + if (!ENABLED(en_asg)) { /* Security */ + errpkt((CHAR *)"REMOTE ASSIGN disabled"); + RESUME; + return(-1); + } else { /* OK */ + int n; + n = xunchar(*(srvcmd+3)); /* Length of name */ + n = 3 + n + 1; /* Position of length of value */ + *(srvcmd+n) = NUL; /* Don't need it */ + if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0) + errpkt((CHAR *)"REMOTE ASSIGN failed"); + else { + ack(); + success = 1; + } + RESUME; + return(-1); + } + } else { + errpkt((CHAR *)"Badly formed server command"); + RESUME; + return(-1); + } +#else + errpkt((CHAR *)"Variable query/set not available"); + RESUME; + return(-1); +#endif /* NOSPL */ +#endif /* NOSERVER */ +} + +static int +srv_copy() { +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE COPY", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifdef ZCOPY + if (!ENABLED(en_cpy)) { + errpkt((CHAR *)"REMOTE COPY disabled"); + RESUME; + return(-1); + } else { + char *str1, *str2, f1[256], f2[256]; + int len1, len2; + len1 = xunchar(srvcmd[1]); /* Separate the parameters */ + len2 = xunchar(srvcmd[2+len1]); + strncpy(f1,(char *)(srvcmd+2),len1); + f1[len1] = NUL; + strncpy(f2,(char *)(srvcmd+3+len1),len2); + f2[len2] = NUL; +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE COPY", f1, f2); +#endif /* IKSDB */ + if (!ENABLED(en_cwd)) { /* If CWD is disabled */ + zstrip(f1,&str1); /* and they included a pathname, */ + zstrip(f2,&str2); + if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */ + errpkt((CHAR *)"Access denied"); + RESUME; /* Remember, this is not a goto! */ + return(-1); + } + } + if (state == generic) { /* It's OK to go ahead. */ + if (zcopy(f1,f2)) { /* Try */ + errpkt((CHAR *)"Can't copy file"); /* give error message */ + } else { + success = 1; + ack(); + } + RESUME; /* wait for next server command */ + return(-1); + } + } + return(-1); +#else /* no ZCOPY */ + errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */ + RESUME; /* wait for next server command */ + return(-1); +#endif /* ZCOPY */ +#endif /* NOSERVER */ +} + +static int +srv_rename() { +#ifndef NOSERVER +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE RENAME", (char *)srvcmd); +#endif /* CKSYSLOG */ +#ifdef ZRENAME + if (!ENABLED(en_ren)) { + errpkt((CHAR *)"REMOTE RENAME disabled"); + RESUME; + return(-1); + } else { /* RENAME is enabled */ + char *str1, *str2, f1[256], f2[256]; + int len1, len2; + len1 = xunchar(srvcmd[1]); /* Separate the parameters */ + len2 = xunchar(srvcmd[2+len1]); + strncpy(f1,(char *)(srvcmd+2),len1); + f1[len1] = NUL; + strncpy(f2,(char *)(srvcmd+3+len1),len2); + f2[len2] = NUL; + len2 = xunchar(srvcmd[2+len1]); + strncpy(f1,(char *)(srvcmd+2),len1); + f1[len1] = NUL; + strncpy(f2,(char *)(srvcmd+3+len1),len2); + f2[len2] = NUL; +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE RENAME", f1, f2); +#endif /* IKSDB */ + if (!ENABLED(en_cwd)) { /* If CWD is disabled */ + zstrip(f1,&str1); /* and they included a pathname, */ + zstrip(f2,&str2); + if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */ + errpkt((CHAR *)"Access denied"); + RESUME; /* Remember, this is not a goto! */ + return(-1); + } + } + if (state == generic) { /* It's OK to go ahead. */ + if (zrename(f1,f2)) { /* Try */ + errpkt((CHAR *)"Can't rename file"); /* Give error msg */ + } else { + success = 1; + ack(); + } + RESUME; /* Wait for next server command */ + return(-1); + } + } + return(-1); +#else /* no ZRENAME */ + /* Give error message */ + errpkt((CHAR *)"REMOTE RENAME not available"); + RESUME; /* Wait for next server command */ + return(-1); +#endif /* ZRENAME */ +#endif /* NOSERVER */ +} + +static int +srv_login() { +#ifndef NOSERVER + char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1]; + CHAR *p; + int len, i; + + debug(F101,"REMOTE LOGIN x_login","",x_login); + debug(F101,"REMOTE LOGIN x_logged","",x_logged); + + f1[0] = NUL; f2[0] = NUL; f3[0] = NUL; + len = 0; + if (srvcmd[1]) /* First length field */ + len = xunchar(srvcmd[1]); /* Separate the parameters */ + + if (x_login) { /* Login required */ + if (x_logged) { /* And already logged in */ + if (len > 0) { /* Logging in again */ + errpkt((CHAR *)"Already logged in."); + } else { /* Logging out */ + debug(F101,"REMOTE LOGOUT","",x_logged); +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGOUT", NULL); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"REMOTE LOGOUT", "", ""); +#endif /* IKSDB */ + tlog(F110,"Logged out",x_user,0); + ack1((CHAR *)"Logged out"); + success = 1; + msleep(500); +#ifdef CK_LOGIN + x_logged = 0; +#ifdef IKSD + if (inserver) + ckxlogout(); +#endif /* IKSD */ +#endif /* CK_LOGIN */ + } + } else { /* Not logged in yet */ + debug(F101,"REMOTE LOGIN len","",len); + if (len > 0) { /* Have username */ +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGIN", NULL); +#endif /* CKSYSLOG */ + if (len > LOGINLEN) { + errpkt((CHAR *)"Username too long"); + } + p = srvcmd + 2; /* Point to it */ + for (i = 0; i < len; i++) /* Copy it */ + f1[i] = p[i]; + f1[len] = NUL; /* Terminate it */ + p += len; /* Point to next length field */ + if (*p) { /* If we have one */ + len = xunchar(*p++); /* decode it */ + if (len > 0 && len <= LOGINLEN) { + for (i = 0; i < len; i++) /* Same deal for password */ + f2[i] = p[i]; + f2[len] = NUL; + p += len; /* And account */ + if (*p) { + len = xunchar(*p++); + if (len > 0 && len <= LOGINLEN) { + for (i = 0; i < len; i++) + f3[i] = p[i]; /* Set but never used */ + f3[len] = NUL; /* (because account not used) */ + } + } + } + } + debug(F101,"REMOTE LOGIN 1","",x_logged); +#ifdef IKSD +#ifdef CK_LOGIN + if (inserver) { /* Log in to system for real */ + x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0); + debug(F101,"REMOTE LOGIN 2","",x_logged); + if (x_logged) { /* Count attempts */ + logtries = 0; + justone = 1; + } else { + logtries++; + sleep(logtries); + } + } else +#endif /* CK_LOGIN */ +#endif /* IKSD */ + if (x_user && x_passwd) { /* User and password must match */ + if (!strcmp(x_user,f1)) /* SET SERVER LOGIN */ + if (!strcmp(x_passwd,f2)) + x_logged = 1; + debug(F101,"REMOTE LOGIN 3","",x_logged); + } else if (x_user) { /* Only username given, no password */ + if (!strcmp(x_user,f1)) /* so only username must match */ + x_logged = 1; + debug(F101,"REMOTE LOGIN 4","",x_logged); + } +#ifdef CK_LOGIN + else { + x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0); + debug(F101,"REMOTE LOGIN 5","",x_logged); + } +#endif /* CK_LOGIN */ + if (x_logged) { /* Logged in? */ + tlog(F110,"Logged in", x_user, 0); + if (isguest) + ack1((CHAR *)"Logged in as guest - restrictions apply"); + else + ack1((CHAR *)"Logged in"); + success = 1; + } else { + tlog(F110,"Login failed", f1, 0); + errpkt((CHAR *)"Access denied."); +#ifdef IKSD +#ifdef CK_LOGIN + if (inserver && logtries > 2) + ckxlogout(); +#endif /* CK_LOGIN */ +#endif /* IKSD */ + } + } else { /* LOGOUT */ + errpkt((CHAR *)"Logout ignored"); + } + } + } else { /* Login not required */ + if (len > 0) + errpkt((CHAR *)"Login ignored."); + else + errpkt((CHAR *)"Logout ignored."); + } +#endif /* NOSERVER */ + RESUME; + return(-1); +} + +static int +srv_timeout() { + /* K95 does this its own way */ + if (idletmo) { +#ifdef IKSD + if (inserver) { + printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", srvidl); + doexit(GOOD_EXIT,xitsta); + } +#endif /* IKSD */ + idletmo = 0; + printf("\r\nSERVER IDLE TIMEOUT: %d sec\r\n", srvidl); + xitsta |= (what & W_KERMIT); + QUIT; + } +#ifndef NOSERVER + else if (fatalio) { /* Connection lost */ +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "Connection lost", NULL); +#endif /* CKSYSLOG */ +#ifdef IKSDB + if (ikdbopen) slotstate(what,"SERVER DISCONNECT",(char *)srvcmd, ""); +#endif /* IKSDB */ + xitsta |= what; + QUIT; + } else if (interrupted) { /* Interrupted by hand */ + if (!ENABLED(en_fin)) { + errpkt((CHAR *)"QUIT disabled"); + RESUME; + return(-1); + } else { + if (what == W_SEND || what == W_RECV || what == W_REMO) { + success = 0; +#ifdef CKSYSLOG + if (ckxsyslog >= SYSLG_PR && ckxlogging) + cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL); +#endif /* CKSYSLOG */ + } else if (what == W_NOTHING && filcnt == 0) { + success = 1; + } /* Otherwise leave success alone */ + xitsta |= (what & W_KERMIT); + QUIT; + } + } else { /* Shouldn't happen */ + debug(F100,"SERVER (top) GOT UNEXPECTED 'q'","",0); + QUIT; + } +#endif /* NOSERVER */ +} + +static int +rcv_s_pkt() { +#ifndef NOSERVER + if (state == rgen) + urserver = 1; + if (/* state == serve && */ x_login && !x_logged) { + errpkt((CHAR *)"Login required"); + SERVE; + } else +#endif /* NOSERVER */ + if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */ + errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */ + RESUME; + return(-1); + } else { /* OK to go ahead. */ +#ifdef CK_TMPDIR + if (dldir && !f_tmpdir) { /* If they have a download directory */ + debug(F110,"receive download dir",dldir,0); + if (s = zgtdir()) { /* Get current directory */ + debug(F110,"receive current dir",s,0); + if (zchdir(dldir)) { /* Change to download directory */ + debug(F100,"receive zchdir ok","",0); + ckstrncpy(savdir,s,TMPDIRLEN); + f_tmpdir = 1; /* Remember that we did this */ + } else + debug(F100,"receive zchdir failed","",0); + } + } +#endif /* CK_TMPDIR */ + nakstate = 1; /* Can send NAKs from here. */ + rinit(rdatap); /* Set parameters */ + bctu = bctr; /* Switch to agreed-upon block check */ + bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */ + what = W_RECV; /* Remember we're receiving */ + lastxfer = W_RECV; + resetc(); /* Reset counters */ + rtimer(); /* Reset timer */ +#ifdef GFTIMER + rftimer(); +#endif /* GFTIMER */ + streamon(); + BEGIN rfile; /* Go into receive-file state */ + } + return(-1); +} + + +/* END OF ROUTINES MOVED OUT OF STATE MACHINE */ + + +/* P R O T O -- Protocol entry function */ + +static int is_tn = 0; /* It's a Telnet connection */ + +#ifdef CK_SPEED +int f_ctlp = 0; /* Control-character prefix table */ +#ifdef COMMENT +short s_ctlp[256]; +#endif /* COMMENT */ +#endif /* CK_SPEED */ + +/* + This is simply a wrapper for the real protocol function just below, + that saves any items that might be changed automatically by protocol + negotiations and then restores them upon exit from protocol mode. +*/ +VOID +proto() { + extern int b_save, f_save, c_save, ss_save, slostart, reliable, urclear; +#ifndef NOCSETS + extern int fcharset, fcs_save, tcharset, tcs_save; +#endif /* NOCSETS */ + +#ifdef PIPESEND + extern int pipesend; +#endif /* PIPESEND */ +#ifndef NOLOCAL +#ifdef OS2 + extern int cursorena[], cursor_save, term_io; + extern BYTE vmode; + extern int display_demo; + int term_io_save; +#endif /* OS2 */ +#endif /* NOLOCAL */ +#ifdef TNCODE + int _u_bin=0, _me_bin = 0; +#ifdef IKS_OPTION + int /* _u_start=0, */ _me_start = 0; +#endif /* IKS_OPTION */ +#endif /* TNCODE */ +#ifdef PATTERNS + int pa_save; + int i; +#endif /* PATTERNS */ + int scan_save; + +#ifdef PATTERNS + pa_save = patterns; +#endif /* PATTERNS */ + scan_save = filepeek; + + myjob = sstate; + +#ifdef CK_LOGIN + if (isguest) { /* If user is anonymous */ + en_pri = 0; /* disable printing */ + en_mai = 0; /* and disable email */ + en_del = 0; /* and file deletion */ + } +#endif /* CK_LOGIN */ + +#ifndef NOLOCAL +#ifdef OS2 + cursor_save = cursorena[vmode]; + cursorena[vmode] = 0; + term_io_save = term_io; + term_io = 0; +#endif /* OS2 */ +#endif /* NOLOCAL */ + b_save = binary; /* SET FILE TYPE */ + f_save = fncnv; /* SET FILE NAMES */ + c_save = bctr; + p_save = fnspath; + r_save = recursive; + s_timint = timint; + ss_save = slostart; +#ifndef NOCSETS + fcs_save = fcharset; + tcs_save = tcharset; +#endif /* NOCSETS */ + +#ifdef COMMENT +/* Don't do this because then user can never find out what happened. */ +#ifdef CK_SPEED + for (i = 0; i < 256; i++) + s_ctlp[i] = ctlp[i]; + f_ctlp = 1; +#endif /* CK_SPEED */ +#endif /* COMMENT */ + if (reliable == SET_ON) + slostart = 0; + is_tn = (!local && sstelnet) +#ifdef TNCODE + || (local && network && ttnproto == NP_TELNET) +#endif /* TNCODE */ + ; +#ifdef TNCODE + if (is_tn) { + if (tn_b_xfer && !(sstelnet || inserver)) { + /* Save the current state of Telnet Binary */ + _u_bin = TELOPT_U(TELOPT_BINARY); + _me_bin = TELOPT_ME(TELOPT_BINARY); + + /* If either direction is not Binary attempt to negotiate it */ + if (!_u_bin && TELOPT_U_MODE(TELOPT_BINARY) != TN_NG_RF) { + tn_sopt(DO,TELOPT_BINARY); + TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1; + } + if (!_me_bin && TELOPT_ME_MODE(TELOPT_BINARY) != TN_NG_RF) { + tn_sopt(WILL,TELOPT_BINARY); + TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1; + } + if (!(_me_bin && _u_bin)) + tn_wait("proto set binary mode"); + } +#ifdef IKS_OPTION +#ifdef CK_XYZ + if (protocol != PROTO_K) { /* Non-Kermit protocol selected */ + if (TELOPT_U(TELOPT_KERMIT) && + TELOPT_SB(TELOPT_KERMIT).kermit.u_start) { + iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */ + /* _u_start = 1; */ + } + if (TELOPT_ME(TELOPT_KERMIT) && + TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { + tn_siks(KERMIT_STOP); /* I'm not servering */ + TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0; + _me_start = 1; + } + } else +#endif /* CK_XYZ */ + if (sstate == 'x' || sstate == 'v') { /* Responding to a request */ + if (!inserver && TELOPT_U(TELOPT_KERMIT) && + TELOPT_SB(TELOPT_KERMIT).kermit.u_start) { + iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */ + /* _u_start = 1; */ + } + if (TELOPT_ME(TELOPT_KERMIT) && + !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { + tn_siks(KERMIT_START); /* Send Kermit-Server Start */ + TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1; + } + } else { /* Initiating a request */ + if (TELOPT_ME(TELOPT_KERMIT) && + TELOPT_SB(TELOPT_KERMIT).kermit.me_start) { + tn_siks(KERMIT_STOP); /* I'm not servering */ + TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0; + _me_start = 1; + } + if (TELOPT_U(TELOPT_KERMIT) && + !TELOPT_SB(TELOPT_KERMIT).kermit.u_start) { + /* Send Req-Server-Start */ + if (!iks_wait(KERMIT_REQ_START,0)) { + if (sstate != 's') { + success = 0; /* Other Kermit refused to serve */ + if (local) + printf("A Kermit Server is not available\r\n"); + debug(F110,"proto()", + "A Kermit Server is not available",0); + tlog(F110,"IKS client/server failure", + "A Kermit Server is not available",0); + goto xxprotox; + } + } + } + } +#endif /* IKS_OPTION */ +#ifdef CK_ENCRYPTION + if (tn_no_encrypt_xfer && !(sstelnet || inserver)) { + ck_tn_enc_stop(); + } +#endif /* CK_ENCRYPTION */ + } +#endif /* TNCODE */ + + if (!xfrint) connoi(); + xxproto(); /* Call the real protocol function */ + +#ifdef IKS_OPTION + xxprotox: +#endif /* IKS_OPTION */ + xferstat = success; /* Remember transfer status */ + kactive = 0; + +#ifdef TNCODE +#ifdef CK_ENCRYPTION + if (tn_no_encrypt_xfer && !(sstelnet || inserver)) { + ck_tn_enc_start(); + } +#endif /* CK_ENCRYPTION */ +#ifdef IKS_OPTION + if (TELOPT_ME(TELOPT_KERMIT) && + TELOPT_SB(TELOPT_KERMIT).kermit.me_start && !_me_start) { + tn_siks(KERMIT_STOP); /* Server is stopped */ + TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0; + } +#endif /* IKS_OPTION */ + if (is_tn && tn_b_xfer && !(sstelnet || inserver)) { + /* if we negotiated Binary mode try to reset it */ + if (!_u_bin) { + /* Check to see if the state changed during the transfer */ + if (TELOPT_U(TELOPT_BINARY)) { + tn_sopt(DONT,TELOPT_BINARY); + TELOPT_UNANSWERED_DONT(TELOPT_BINARY) = 1; + } else + _u_bin = 1; /* So we don't call tn_wait() */ + } + if (!_me_bin) { + /* Check to see if the state changed during the transfer */ + if (TELOPT_ME(TELOPT_BINARY)) { + tn_sopt(WONT,TELOPT_BINARY); + TELOPT_UNANSWERED_WONT(TELOPT_BINARY) = 1; + } else + _me_bin = 1; /* So we don't call tn_wait() */ + } + if (!(_me_bin && _u_bin)) + tn_wait("proto reset binary mode"); + } +#endif /* TNCODE */ + +#ifdef PATTERNS + patterns = pa_save; +#endif /* PATTERNS */ + filepeek = scan_save; + +#ifdef STREAMING + streaming = 0; + /* streamok = 0; */ +#endif /* STREAMING */ +#ifdef COMMENT +#ifdef CK_SPEED + for (i = 0; i < 256; i++) + ctlp[i] = s_ctlp[i]; + f_ctlp = 0; +#endif /* CK_SPEED */ +#endif /* COMMENT */ + urclear = 0; + if (!success) { + xitsta |= (what & W_KERMIT); + tlog(F110," failed:",(char *)epktmsg,0); + } + debug(F111,"proto xferstat",epktmsg,xferstat); + slostart = ss_save; + if (s_timint > -1) { /* Because of REMOTE SET */ + timint = s_timint; + s_timint = -1; + } + recursive = r_save; + fnspath = p_save; + if (c_save > -1) { /* Because of REMOTE SET */ + bctr = c_save; + c_save = -1; + } + fncnv = f_save; + binary = b_save; +#ifdef PIPESEND + pipesend = 0; /* Next time might not be pipesend */ +#endif /* PIPESEND */ +#ifndef NOLOCAL +#ifdef OS2 + cursorena[vmode] = cursor_save; + term_io = term_io_save; + display_demo = 1; +#endif /* OS2 */ +#endif /* NOLOCAL */ +} + +static VOID +xxproto() { + int x; + long lx; +#ifdef CK_XYZ +#ifdef XYZ_INTERNAL +_PROTOTYP( int pxyz, (int) ); +#endif /* XYZ_INTERNAL */ +#endif /* CK_XYZ */ + + char xss[2]; /* String representation of sstate */ + xss[0] = sstate; + xss[1] = NUL; + s_timint = timint; + + debug(F101,"xxproto entry justone","",justone); + success = 0; + + retrieve = 0; /* Reset these ... */ + reget = 0; + opkt = 0; + + if (local && ttchk() < 0) { /* Giving BYE or FIN */ + if (bye_active) { /* but there is no connection */ + ttclos(0); + success = 1; + return; + } + /* Ditto for any REMOTE command */ + if (sstate == 'g' && cmarg ) { + if (*cmarg == 'L' || *cmarg == 'F' || *cmarg == 'X') + success = 1; + else + printf("?No connection\r\n"); + return; + } + } + +/* Set up the communication line for file transfer. */ +/* NOTE: All of the xxscreen() calls prior to the wart() invocation */ +/* could just as easily be printf's or, for that matter, hints. */ + + if (local && (speed < 0L) && (network == 0)) { + xxscreen(SCR_EM,0,0L,"Sorry, you must 'set speed' first"); + return; + } + x = -1; + if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) { + debug(F111,"failed: proto ttopen local",ttname,local); + xxscreen(SCR_EM,0,0L,"Can't open line"); + return; + } + if (x > -1) local = x; + debug(F111,"proto ttopen local",ttname,local); + + lx = (local && !network) ? speed : -1; +#ifdef NETCONN +#ifdef CK_SPEED + if (is_tn) { + ctlp[(unsigned)255] = ctlp[CR] = 1; + if (parity == 'e' || parity == 'm') ctlp[127] = 1; + if (flow == FLO_XONX) { /* Also watch out for Xon/Xoff */ + ctlp[17] = ctlp[19] = 1; + ctlp[17+128] = ctlp[19+128] = 1; + } + } +#endif /* CK_SPEED */ +#endif /* NETCONN */ + if (ttpkt(lx,flow,parity) < 0) { /* Put line in packet mode, */ + xxscreen(SCR_EM,0,0L,"Can't condition line"); + return; + } + if (local && !network && carrier != CAR_OFF) { + int x; /* Serial connection */ + x = ttgmdm(); /* with carrier checking */ + if (x > -1) { + if (!(x & BM_DCD)) { + debug(F101,"proto ttgmdm","",0); + xxscreen(SCR_EM,0,0L,"Carrier required but not detected"); + return; + } + } + } + /* Send remote side's "receive" or "server" startup string, if any */ + if (local && ckindex((char *)xss,"srgcjhk",0,0,1)) { + char *s = NULL; + if ( +#ifdef IKS_OPTION + /* Don't send auto-blah string if we know other side is serving */ + !TELOPT_U(TELOPT_KERMIT) || + !TELOPT_SB(TELOPT_KERMIT).kermit.u_start +#else + 1 +#endif /* IKS_OPTION */ + ) { + if (sstate == 's') { /* Sending file(s) */ + s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init; + } else if (protocol == PROTO_K) { /* Command for server */ + s = ptab[protocol].h_x_init; + } + } +#ifdef CK_SPEED +#ifndef UNPREFIXZERO + if (protocol == PROTO_K) /* Because of C-strings... */ + ctlp[0] = 1; +#endif /* UNPREFIXZERO */ +#endif /* CK_SPEED */ + if (s) if (*s) { /* If we have a command to send... */ + char tmpbuf[356]; + int tmpbufsiz = 356; + int stuff = -1, stuff2 = -1, len = 0; + extern int tnlm; + if (sstate == 's') { /* Sending file(s) */ +#ifdef CK_XYZ + if (protocol == PROTO_X) { + char * s2; + s2 = cmarg2[0] ? cmarg2 : cmarg; + if ((int)strlen(s) + (int)strlen(s2) + 4 < 356) + sprintf(tmpbuf, s, s2); + else + tmpbuf[0] = NUL; + } else { +#endif /* CK_XYZ */ + ckmakmsg(tmpbuf, 356, s, NULL, NULL, NULL); +#ifdef CK_XYZ + } +#endif /* CK_XYZ */ + } else { /* Command for server */ + ckstrncpy(tmpbuf,s,356); + } + ckstrncat(tmpbuf, "\015",sizeof(tmpbuf)); + if (tnlm) /* TERMINAL NEWLINE ON */ + stuff = LF; /* Stuff LF */ +#ifdef TNCODE + /* TELNET NEWLINE MODE */ + if (is_tn) { + switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) { + case TNL_CR: + break; + case TNL_CRNUL: + break; + case TNL_CRLF: + stuff2 = stuff; + stuff = LF; + break; + } + } +#endif /* TNCODE */ + +#ifdef NETCONN +#ifdef TCPSOCKET +#ifdef RLOGCODE + if (network && ttnproto == NP_RLOGIN) { + switch (tn_b_nlm) { /* Always BINARY */ + case TNL_CR: + break; + case TNL_CRNUL: + stuff2 = stuff; + stuff = NUL; + break; + case TNL_CRLF: + stuff2 = stuff; + stuff = LF; + break; + } + } +#endif /* RLOGCODE */ +#endif /* TCPSOCKET */ +#endif /* NETCONN */ + + len = strlen(tmpbuf); + if (stuff >= 0 && len < tmpbufsiz - 1) { + tmpbuf[len++] = stuff; + if (stuff2 >= 0 && len < tmpbufsiz - 1) + tmpbuf[len++] = stuff2; + tmpbuf[len] = NUL; + } + ttol((CHAR *)tmpbuf,len); + if (protocol == PROTO_K) /* Give remote Kermit time to start */ + msleep(400); + } + } + +#ifdef CK_XYZ + if (protocol != PROTO_K) { /* Non-Kermit protocol selected */ + char tmpbuf[356]; + int tmpbufsiz = 356; + char * s = ""; + +#ifdef CK_TMPDIR + if (sstate == 'v') { /* If receiving and... */ + if (dldir && !f_tmpdir) { /* if they have a download directory */ + if (s = zgtdir()) { /* Get current directory */ + if (zchdir(dldir)) { /* Change to download directory */ + ckstrncpy(savdir,s,TMPDIRLEN); + f_tmpdir = 1; /* Remember that we did this */ + } + } + } + } +#endif /* CK_TMPDIR */ + +#ifdef XYZ_INTERNAL /* Internal */ + success = !pxyz(sstate); +#else +#ifdef CK_REDIR /* External */ + switch (sstate) { + case 's': /* 'Tis better to SEND... */ + s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd; + break; + case 'v': /* ... than RECEIVE */ + s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd; + break; + } + if (!s) s = ""; + if (*s) { + if (sstate == 's') { + if ((int)strlen(s) + (int)strlen(fspec) < tmpbufsiz) { + sprintf(tmpbuf,s,fspec); /* safe (prechecked) */ + tlog(F110,"Sending",fspec,0L); + } + } else { + if ((int)strlen(s) + (int)strlen(cmarg2) < tmpbufsiz) { + sprintf(tmpbuf,s,cmarg2); /* safe (prechecked) */ + tlog(F110,"Receiving",cmarg2,0L); + } + } + tlog(F110," via external protocol:",tmpbuf,0); + debug(F110,"ckcpro ttruncmd",tmpbuf,0); + success = ttruncmd(tmpbuf); + tlog(F110," status:",success ? "OK" : "FAILED", 0); + } else { + printf("?Sorry, no external protocol defined for %s\r\n", + ptab[protocol].p_name + ); + } +#else + printf( +"Sorry, only Kermit protocol is supported in this version of Kermit\n" + ); +#endif /* CK_REDIR */ +#endif /* XYZ_INTERNAL */ + return; + } +#endif /* CK_XYZ */ + +#ifdef NTSIGX + conraw(); + connoi(); +#else + if (!local) + connoi(); /* No console interrupts if remote */ +#endif /* NTSIG */ + + kactive = 1; + if (sstate == 'x') { /* If entering server mode, */ + extern int howcalled; + server = 1; /* set flag, */ + debug(F101,"server backgrd","",backgrd); + debug(F101,"server quiet","",quiet); + debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0); + if (howcalled == I_AM_SSHSUB) { /* and issue appropriate message. */ + ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26); + } else if (!local) { + if (!quiet && !backgrd +#ifdef IKS_OPTION + && !TELOPT_ME(TELOPT_KERMIT) /* User was told by negotiation */ +#endif /* IKS_OPTION */ + ) { + conoll(srvtxt); + conoll("KERMIT READY TO SERVE..."); + } + } else { + conol("Entering server mode on "); + conoll(ttname); + conoll("Type Ctrl-C to quit."); + if (srvdis) intmsg(-1L); +#ifdef TCPSOCKET +#ifndef NOLISTEN + if (network && tcpsrfd > 0) + ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26); +#endif /* NOLISTEN */ +#endif /* TCPSOCKET */ + } + } else + server = 0; +#ifdef VMS + if (!quiet && !backgrd) /* So message doesn't overwrite prompt */ + conoll(""); + if (local) conres(); /* So Ctrl-C will work */ +#endif /* VMS */ +/* + If in remote mode, not shushed, not in background, and at top command level, + issue a helpful message telling what to do... +*/ + if (!local && !quiet && !backgrd) { + if (sstate == 'v') { + conoll("Return to your local Kermit and give a SEND command."); + conoll(""); + conoll("KERMIT READY TO RECEIVE..."); + } else if (sstate == 's') { + conoll("Return to your local Kermit and give a RECEIVE command."); + conoll(""); + conoll("KERMIT READY TO SEND..."); + } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' || + sstate == 'j' || sstate == 'c' ) { + conoll("Return to your local Kermit and give a SERVER command."); + conoll(""); + conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ? + "KERMIT READY TO GET..." : + "KERMIT READY TO SEND SERVER COMMAND..."); + } + } +#ifdef COMMENT + if (!local) sleep(1); +#endif /* COMMENT */ +/* + The 'wart()' function is generated by the wart program. It gets a + character from the input() routine and then based on that character and + the current state, selects the appropriate action, according to the state + table above, which is transformed by the wart program into a big case + statement. The function is active for one transaction. +*/ + rtimer(); /* Reset elapsed-time timer */ +#ifdef GFTIMER + rftimer(); +#endif /* GFTIMER */ + resetc(); /* & other per-transaction counters. */ + + debug(F101,"proto calling wart, justone","",justone); + + wart(); /* Enter the state table switcher. */ +/* + Note: the following is necessary in case we have just done a remote-mode + file transfer, in which case the controlling terminal modes have been + changed by ttpkt(). In particular, special characters like Ctrl-C and + Ctrl-\ might have been turned off (see ttpkt). So this call to ttres() is + essential. IMPORTANT: restore interrupt handlers first, otherwise any + terminal interrupts that occur before this is done in the normal place + later will cause a crash. +*/ +#ifdef OS2 + ttres(); /* Reset the communication device */ +#else + if (!local) { + setint(); /* Arm interrupt handlers FIRST */ + msleep(500); + ttres(); /* Then restore terminal. */ + } +#endif /* OS2 */ + xxscreen(SCR_TC,0,0L,""); /* Transaction complete */ + x = quiet; + quiet=1; + clsif(); /* Failsafe in case we missed */ + clsof(1); /* a case in the state machine. */ + quiet = x; + + if (server) { /* Back from packet protocol. */ + if (!quiet && !backgrd +#ifdef IKSD + && !inserver +#endif /* IKSD */ + ) { /* Give appropriate message */ + conoll(""); + conoll("C-Kermit server done"); + } + server = 0; /* Not a server any more */ + } +} + +/* S G E T I N I T -- Handle incoming GET-Class packets */ + +/* + Returns: + -1: On error + 0: GET packet processed OK - ready to Send. + 1: Extended GET processed OK - wait for another. +*/ +static int +sgetinit(reget,xget) int reget, xget; { /* Server end of GET command */ + char * fs = NULL; /* Pointer to filespec */ + int i, n, done = 0; +#ifdef PIPESEND + extern int usepipes, pipesend; +#endif /* PIPESEND */ + extern int nolinks; + + if (!ENABLED(en_get)) { /* Only if not disabled! */ + errpkt((CHAR *)"GET disabled"); + return(-1); + } + + /* OK to proceed */ + + nolinks = recursive; + filcnt = 0; + +#ifdef WHATAMI + /* If they are alike this was already done in whoarewe() */ + debug(F101,"sgetinit whatru","",whatru); + if (whatru & WMI_FLAG) { /* Did we get WHATAMI info? */ + debug(F101,"sgetinit binary (1)","",binary); +#ifdef VMS + if (binary != XYFT_I && binary != XYFT_L) +#else +#ifdef OS2 + if (binary != XYFT_L) +#endif /* OS2 */ +#endif /* VMS */ + binary = (whatru & WMI_FMODE) ? /* Yes, set file type */ + XYFT_B : XYFT_T; /* automatically */ + debug(F101,"sgetinit binary (2)","",binary); + if (!wearealike) + fncnv = (whatru & WMI_FNAME) ? 1 : 0; /* And name conversion */ + } +#endif /* WHATAMI */ + + fs = (char *)srvcmd; + srvptr = srvcmd; /* Point to server command buffer */ + decode(rdatap,putsrv,0); /* Decode the GET command into it */ + /* Accept multiple filespecs */ + cmarg2 = ""; /* Don't use cmarg2 */ + cmarg = ""; /* Don't use cmarg */ + + done = 1; /* Only 1 packet needed... */ + if (xget) { /* Special decoding for Extended GET */ + char L, next, c; /* PLV items */ + int len, val; /* More PLV items */ + char * p = (char *)srvcmd; /* String to decode */ + + done = 0; /* Maybe more packets needed */ + fs = NULL; /* We don't know the filespec yet */ + c = *p++; /* Get first parameter */ + + while (c) { /* For all parameters... */ + debug(F000,"sgetinit c","",c); + L = *p++; /* Get length */ + if (L >= SP) /* Decode length */ + len = xunchar(L); + else if (c == '@') { /* Allow missing EOP length field */ + len = 0; + } else { + len = (xunchar(*p++) * 95); + len += xunchar(*p++); + } + debug(F101,"sgetinit len","",len); + next = *(p+len); /* Get next parameter */ + *(p+len) = NUL; /* Zero it out to terminal value */ + debug(F110,"sgetinit p",p,0); + switch (c) { /* Do the parameter */ + case 'O': /* GET Options */ + val = atoi(p); /* Convert to int */ + debug(F101,"sgetinit O val","",val); + if (val & GOPT_DEL) moving = 1; + if (val & GOPT_RES) reget = 1; + if (val & GOPT_REC) { + recursive = 1; + nolinks = 2; + if (fnspath == PATH_OFF) + fnspath = PATH_REL; + } + break; + case 'M': /* Transfer Mode */ + val = atoi(p); + debug(F101,"sgetinit M val","",val); + if (val < 1) + break; + patterns = 0; /* Takes precedence over patterns */ + filepeek = 0; /* and FILE SCAN */ + if (val == GMOD_TXT) binary = XYFT_T; /* Text */ + if (val == GMOD_BIN) binary = XYFT_B; /* Binary */ + if (val == GMOD_LBL) binary = XYFT_L; /* Labeled */ + break; + case 'F': /* Filename */ + fs = p; + debug(F110,"sgetinit filename",fs,0); + break; + case '@': /* End Of Parameters */ + done = 1; + debug(F100,"sgetinit EOP","",0); + break; + default: + errpkt((CHAR *)"Unknown GET Parameter"); + debug(F100,"sgetinit unknown parameter","",0); + return(-1); + } + p += (len + 1); + c = next; + } + } + if (!fs) fs = ""; /* A filename is required */ + if (*fs) { + havefs = 1; + n = 0; /* Check for quoted name */ + if ((n = strlen(fs)) > 1) { + /* Note: this does not allow for multiple quoted names */ + if ((fs[0] == '{' && fs[n-1] == '}') || + (fs[0] == '"' && fs[n-1] == '"')) { + fs[n-1] = '\0'; + fs++; + debug(F111,"sgetinit unquoted filename",fs,n); + } else + n = 0; /* This means no quoting */ + } + +#ifdef PIPESEND + debug(F111,"sgetinit",fs,usepipes); + if (usepipes && ENABLED(en_hos) && *fs == '!') { + cmarg = fs + 1; /* Point past the bang */ + *fs = NUL; + nfils = -1; + pipesend = 1; + debug(F111,"sgetinit pipesend",cmarg,pipesend); + } + if (!pipesend) { /* If it's not a pipe */ +#endif /* PIPESEND */ + if (n == 0) { /* If the name was not quoted */ +#ifndef NOMSEND + nfils = fnparse(fs); /* Allow it to be a list of names */ + debug(F111,"sgetinit A",fs,nfils); +#ifdef COMMENT +/* This doesn't work if a GET-PATH is set. */ + if (nfils == 1 && !iswild(fs)) { /* Single file */ + char * m; + if ((x = zchki(fs)) < 0) { /* Check if it's sendable */ + switch (x) { + case -1: m = "File not found"; break; + case -2: m = "Not a regular file"; break; + case -3: m = "Read access denied"; break; + } + errpkt((CHAR *)m); + return(-1); + } + } +#endif /* COMMENT */ + } else { /* If it was quoted */ +#endif /* NOMSEND */ + nzxopts = 0; +#ifdef UNIXOROSK + if (matchdot) nzxopts |= ZX_MATCHDOT; +#endif /* UNIXOROSK */ + if (recursive) nzxopts |= ZX_RECURSE; + /* Treat as a single filespec */ + nfils = 0 - nzxpand(fs,nzxopts); + debug(F111,"sgetinit B",fs,nfils); + cmarg = fs; + } +#ifdef PIPESEND + } +#endif /* PIPESEND */ + } + if (!done) { /* Need more O packets... */ + debug(F100,"sgetinit O-Packet TBC","",0); /* To Be Continued */ + return(1); + } + debug(F100,"sgetinit O-Packet done - havefs","",havefs); + if (!havefs) { /* Done - make sure we have filename */ + errpkt((CHAR *)"GET without filename"); + return(-1); + } + freerpkt(winlo); + winlo = 0; /* Back to packet 0 again. */ + debug(F101,"sgetinit winlo","",winlo); + nakstate = 0; /* Now I'm the sender! */ + if (reget) sendmode = SM_RESEND; + if (sinit() > 0) { /* Send Send-Init */ +#ifdef STREAMING + if (!streaming) +#endif /* STREAMING */ + timint = chktimo(rtimo,timef); /* Switch to per-packet timer */ + return(0); /* If successful, switch state */ + } else return(-1); /* Else back to server command wait */ +} + +#else /* NOXFER */ + +#include "ckcdeb.h" + +VOID +proto() { + extern int success; + success = 0; +} +#endif /* NOXFER */ diff --git a/ckcpro.w b/ckcpro.w index cd9d1fa..c74a1aa 100644 --- a/ckcpro.w +++ b/ckcpro.w @@ -1069,7 +1069,7 @@ a { xxscreen(SCR_TC,0,0L,""); /* Display */ doclean(1); /* Clean up files, etc */ #ifdef DEBUG - debug(F100,"C-Kermit BYE - Loggin out...","",0); + debug(F100,"C-Kermit BYE - Logging out...","",0); zclose(ZDFILE); #endif /* DEBUG */ #ifdef IKSD diff --git a/debian/patches/060_speeling.patch b/debian/patches/060_speeling.patch index dfca4f3..25ea32d 100644 --- a/debian/patches/060_speeling.patch +++ b/debian/patches/060_speeling.patch @@ -1,8 +1,8 @@ Fix spelling errors. Index: ckermit/ckcftp.c =================================================================== ---- ckermit.orig/ckcftp.c 2010-05-12 01:22:31.000000000 +0100 -+++ ckermit/ckcftp.c 2010-05-12 01:22:31.000000000 +0100 +--- ckermit.orig/ckcftp.c 2010-05-12 01:33:56.000000000 +0100 ++++ ckermit/ckcftp.c 2010-05-12 01:33:59.000000000 +0100 @@ -8623,7 +8623,7 @@ #endif /* NOCSETS */ " /SERVER-RENAME:text", @@ -14,8 +14,8 @@ Index: ckermit/ckcftp.c " /TEXT", /* /ASCII */ Index: ckermit/ckuus2.c =================================================================== ---- ckermit.orig/ckuus2.c 2010-05-12 01:22:31.000000000 +0100 -+++ ckermit/ckuus2.c 2010-05-12 01:22:31.000000000 +0100 +--- ckermit.orig/ckuus2.c 2010-05-12 01:33:56.000000000 +0100 ++++ ckermit/ckuus2.c 2010-05-12 01:33:59.000000000 +0100 @@ -3660,7 +3660,7 @@ " ", "SET DIAL RETRIES ", @@ -27,8 +27,8 @@ Index: ckermit/ckuus2.c "SET DIAL INTERVAL ", Index: ckermit/ckuker.nr =================================================================== ---- ckermit.orig/ckuker.nr 2010-05-12 01:27:07.000000000 +0100 -+++ ckermit/ckuker.nr 2010-05-12 01:27:46.000000000 +0100 +--- ckermit.orig/ckuker.nr 2010-05-12 01:33:59.000000000 +0100 ++++ ckermit/ckuker.nr 2010-05-12 01:33:59.000000000 +0100 @@ -879,7 +879,7 @@ Sends all files that match. .TP @@ -49,8 +49,8 @@ Index: ckermit/ckuker.nr Asks the server to send the given files. Synonym: G. Index: ckermit/ckututor.txt =================================================================== ---- ckermit.orig/ckututor.txt 2010-05-12 01:27:16.000000000 +0100 -+++ ckermit/ckututor.txt 2010-05-12 01:28:05.000000000 +0100 +--- ckermit.orig/ckututor.txt 2010-05-12 01:33:56.000000000 +0100 ++++ ckermit/ckututor.txt 2010-05-12 01:33:59.000000000 +0100 @@ -682,7 +682,7 @@ SEND [ options ] filename [ as-name ] Sends the given file. Synonym: S. @@ -69,3 +69,16 @@ Index: ckermit/ckututor.txt point of failure. GET [ options ] remote-filespec Asks the server to send the given files. Synonym: G. +Index: ckermit/ckcpro.w +=================================================================== +--- ckermit.orig/ckcpro.w 2010-05-12 01:34:08.000000000 +0100 ++++ ckermit/ckcpro.w 2010-05-12 01:34:11.000000000 +0100 +@@ -1069,7 +1069,7 @@ + xxscreen(SCR_TC,0,0L,""); /* Display */ + doclean(1); /* Clean up files, etc */ + #ifdef DEBUG +- debug(F100,"C-Kermit BYE - Loggin out...","",0); ++ debug(F100,"C-Kermit BYE - Logging out...","",0); + zclose(ZDFILE); + #endif /* DEBUG */ + #ifdef IKSD -- 2.11.0