📄 ckcpro.w
字号:
char *protv = /* -*-C-*- */"C-Kermit Protocol Module 7.0.135, 1 Jan 2000";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 <fdc@columbia.edu>, Columbia University Academic Information Systems, New York City. Copyright (C) 1985, 2000, 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 <os2.h>#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(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 *cdmsgfile[]; extern char * snd_move, * snd_rename, * srimsg; extern char filnam[], 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; 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 char * remdest;#ifdef PKTZEROHACK#define PKTZEROLEN 32static char ipktack[PKTZEROLEN];static int ipktlen = 0;#endif /* PKTZEROHACK */static int s_timint = -1; /* For saving timeout value */static int havefs = 0;#ifdef CK_LOGINstatic int logtries = 0;#endif /* CK_LOGIN */#ifdef STREAMINGextern int streaming, streamok;static int cancel = 0;int fackbug = 0;static VOIDstreamon() { if (streamok) { debug(F100,"streamon","",0); streaming = 1; timint = 0; /* No timeouts while streaming. */ }}#ifdef COMMENT /* (not used) */static VOIDstreamoff() { 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 */#ifdef CK_SPEED extern int ttnproto; /* Network protocol */ extern short ctlp[]; /* Control-character prefix table */#endif /* CK_SPEED */#include "ckcnet.h"#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_TMPDIRextern 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;static VOIDrdebug() { 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 NOSPLextern 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) { return(0); } else \if (justone) { justone=0; 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 void 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: <current-states>input-character { action } nakstate != 0 means we're in a receiving state, in which we send ACKs & NAKs.*/<rgen,get,serve,ropkt>S { /* Receive Send-Init packet. */ rc = rcv_s_pkt(); 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. */<ipkt>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 */ winlo = 0; /* Set window-low back to zero */ debug(F101,"<ipkt>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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -