⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gkermit.c

📁 使用Kermit协议传输文件的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* G K E R M I T  --  GNU Kermit  *//*  A free implementation of the Kermit file transfer protocol for UNIX.  If you change this software, please either (a) send changes back to the  Kermit Project to be considered for the base version; or (b) change the  strings below to show a new version number and date and to reflect the  person or organization responsible for the new version.  Sat Dec 25 19:22:54 1999*/char *versio = "G-Kermit CU-1.00, Columbia University, 1999-12-25";char *url =    "http://www.columbia.edu/kermit/";char *email =  "kermit@columbia.edu";/*  Author:    Frank da Cruz    The Kermit Project    Columbia University    612 West 115th Street    New York NY 10025-7799  USA    http://www.columbia.edu/kermit/    kermit@columbia.edu  Copyright (C) 1999,  The Trustees of Columbia University in the City of New York.  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef POSIXchar *build =  "POSIX";			/* Identify which build */#else#ifdef SYSVchar *build =  "SYSV";#else#ifdef BSDchar *build =  "BSD";#elsechar *build =  "stty";#endif /* BSD */#endif /* SYSV */#endif /* POSIX */#define _GKERMIT_C#include <stdio.h>#include "gkermit.h"/* Forward declarations of functions used within this module... */_MYPROTOTYPE( int cmdlin, (void) );	/* Command-line parser */_MYPROTOTYPE( int spacket, (char,int,int,char *) ); /* Make & send a packet */_MYPROTOTYPE( int rpacket, (void) );	/* Read a packet */_MYPROTOTYPE( unsigned int chk1, (char *,int) ); /* 1-byte block check */_MYPROTOTYPE( unsigned int chk3, (char *,int) ); /* 3-byte CRC */_MYPROTOTYPE( unsigned int chksum, (char *,int) ); /* Checksum */_MYPROTOTYPE( int getpkt, (int) );	/* Fill packet data field */_MYPROTOTYPE( VOID encode, (int,int) ); /* Encode a character */_MYPROTOTYPE( VOID decstr, (char *) );	/* Decode a memory string *//* Externs */extern int zincnt;			/* For buffered file i/o */extern char * zinptr;extern FILE * ofp;			/* Output file pointer *//* Global variables declared here */char *cmarg, *cmarg2 = NULL;		/* Send filename pointers */char **cmlist = NULL;			/* Pointer to file list in argv */FILE * db = NULL;			/* Debug log file pointer */int debug = 0;				/* Debugging on */int failure = 0;			/* Return status */int retries = 0;			/* Packet retry counter */int sendtype = 0;			/* Type of last packet sent */int recvtype = 0;			/* Type of last packet received */int datalen = 0;			/* Length of received data field *//* Protocol parameters */int spsiz = 90,				/* Default send-packet size */    rpsiz = 94,				/* Default short receive-packet size */    urpsiz = DEFRP,			/* Default long receive-packet size */    maxrp = MAXRP,			/* Maximum  long receive-packet size */    timint = 9,				/* Timeout interval I use */    rtimo = 7,				/* Timeout I want you to use */    rpadn = 0,				/* How much padding to send */    spadn = 0,				/* How much padding to ask for */    bctr = 3,				/* Block check type requested */    bctu = 1,				/* Block check type used */    ebq =  '&',				/* 8th bit prefix */    ebqflg = 0,				/* 8th-bit quoting flag */    rqf = -1,				/* Flag used in 8bq negotiation */    rq = 0,				/* Received 8bq bid */    sq = 'Y',				/* Sent 8bq bid */    rpt = 0,				/* Repeat count */    rptq = '~',				/* Repeat prefix */    rptflg = 0,				/* Repeat processing flag */    backup = 1,				/* Back up existing files */    seq = 0,				/* Current packet number */    size,				/* Current size of output pkt data */    osize,				/* Previous output packet data size */    maxsiz,				/* Max size for building data field */    rln,				/* Received packet length */    rsn,				/* Received packet sequence number */    sndpkl;				/* Length of packet being sent */char spadc = 0,				/* Padding character to send */    rpadc = 0,				/* Padding character to ask for */    seol = CR,				/* End-Of-Line character to send */    reol = CR,				/* End-Of-Line character to look for */    rctlq = '#',			/* Control prefix in incoming data */    sctlq = '#',			/* Outbound control character prefix */    sndpkt[MAXSP+16],			/* Entire packet being sent */    rcvpkt[MAXRP+16], 			/* Packet most recently received */    *rdatap,				/* Pointer to data field of rcvpkt */    xxdata[MAXRP+16],			/* Packet data buffer */    *isp = NUL,				/* Input string pointer */    *osp = NUL,				/* Output string pointer */    smark = '\1',			/* Outbound packet-start character */    rmark = '\1';			/* Incoming packet-start character */char * xdata = xxdata;			/* Packet data field pointer *//* File-related variables */char filnam[MAXPATHLEN+1];		/* Name of current file. */char ttname[DEVNAMLEN+1];		/* Name of communication device. */int nfils;				/* Number of files to send */int cx = 0, cz = 0;			/* File and batch interruption flags */int quiet = 0;				/* Suppress messages */int keep = 0;				/* Keep incompletely received files */int streamok = 0;			/* Streaming protocol negotiated */int streaming = 0;			/* Streaming active now */int nomodes = 0;			/* Don't mess with tty modes */int xonxoff = 0;			/* Force Xon/Xoff */int noxonxoff = 0;			/* Don't force Xon/Xoff */int manual = 0;				/* Transfer mode manual, not auto */int parity = 0;				/* Parity specified, 0,'e','o',etc */int delay = 1;				/* Initial delay before sending */int text = 0;				/* Flag for text/binary mode */int first = 0;				/* Flag for first input from file */int longpackets = 0;			/* Long packets negotiated */int attributes = 0;			/* Attribute packets negotiated */int literal = 0;			/* Literal filenames */char start  = 0;			/* Starting state for automaton */char **xargv;				/* Global copies of argv */int  xargc;				/* and argc */char *dftty = CTTNAM;			/* Default controlling terminal name */char *#ifdef __STDC__mystrchr(char * s, char c)#elsemystrchr(s,c) char *s, c;#endif /* __STDC__ */{    if (!s)				/* strchr() replacement */      return(NULL);			/* because strchr not portable */    while (*s && *s != c)      s++;    return((*s == c) ? s : NULL);}int					/* Main Program */main(argc,argv) int argc; char **argv; {    xargc = argc;			/* Make global copies of argc */    xargv = argv;			/* ...and argv. */    start = 0;				/* No default start state. */    seq = 0;				/* Packet sequence number. */    parity = 0;				/* Initial parity. */    strncpy(ttname,dftty,DEVNAMLEN);	/* Default device name. */    if (argc < 2) {			/* If no args */	usage();			/* give usage message */	doexit(1);			/* and quit. */    }    sysinit();				/* Set up interrupt handlers, etc */    if (urpsiz > MAXRP)			/* In case MAXRP < DEFRP... */      urpsiz = MAXRP;    if (maxrp > 9020)      maxrp = 9020;    start = cmdlin();			/* Parse args */    if (start == 0 && !debug) {		/* Nothing to do? */	fprintf(stderr,"No start state\n");	doexit(1);    }    if (ttopen(ttname) < 0) {		/* "Open" the communication device */	fprintf(stderr,"Can't open terminal\n");	doexit(1);    }    if (ttpkt(parity) < 0) {		/* Open OK, put it in packet mode */	printf("Can't set packet mode\n");	doexit(1);    }					/* OK, do requested actions. */    if (start) {			/* Start state */	if (start == 's' || start == 'r') /* If sending or getting*/	  ttflui();			/* flush comm line input buffer */	gwart();			/* Do the protocol */    }    doexit(failure);			/* Done, exit. */    return(failure);			/* To shut up picky compilers. */}/* Functions */int					/* Called implicitly by protocol */input() {				/* to get the next packet. */    int x, type;    if (start != 0) {			/* Start state in effect? */	type = start;			/* Yes, call it a packet type, */	start = 0;			/* nullify the start state, */	if (debug) fprintf(db,"input[%c]\n",(char)type);	return(type);			/* and return the type. */    }    if (streaming && (sendtype == 'D')) { /* If streaming and sending data */	x = ttchk();			/* Look for return traffic */	if (debug)	  fprintf(db,"input streaming ttchk %d\n",x);	if (x < 0)	  errpkt("Fatal i/o error");	else if (x < 5)	  return('Y');			/* If none, pretend we got an ACK */	timint = 4;	type = rpacket();		/* Something came in, read it */	timint = 0;	if (mystrchr("TQN",type))	  errpkt("Transmission error while streaming");    } else {	type = rpacket();		/* No start state, read a packet. */	while (rsn != seq ||		/* Sequence number doesn't match, or */	       mystrchr("TQN",type)	/* Timeout, Checksum error, or NAK */	       ) {	    if (streaming)	      errpkt("Transmission error while streaming");	    resend();			/* Resend previous packet. */	    type = rpacket();		/* Try to read response. */	}    }    if (!streaming)			/* Got a good packet */      ttflui();				/* Flush buffer if not streaming */    if (debug)      fprintf(db,"input[%c]\n",(char)type);    return(type);			/* Return its type */}VOIDnxtpkt() {				/* Next packet */    retries = 0;			/* Reset per-packet retry count */    seq = (seq + 1) & 63;		/* Next packet number, mod 64 */}intack() {					/* Acknowledge */    int x = 0;				/* Empty acknowledgement */    if (!streaming || recvtype != 'D')      x = spacket('Y',seq,0,"");	/* Send the packet */    nxtpkt();				/* Increment packet number */    return(x);}intack1(s) char *s; {			/* Acknowledgement with data */    int x;    x = spacket('Y',seq,strlen(s),s);	/* Send the packet */    nxtpkt();				/* Increment packet number */    return(x);}intnak() {					/* Negative acknowledgement */    int x;    retries++;    if (debug)      fprintf(db,"nak #%d (%d/%d)\n",seq,retries,MAXTRY);    if (retries > MAXTRY) {		/* Check retry limit */	errpkt("Too many retries");	doexit(1);    }    x = spacket('N',seq,0,"");		/* A NAK never has data */    return(x);}VOIDtinit() {				/* Transaction Initialization */    osp = NULL;				/* Reset output string pointer */    cx = cz = 0;			/* File interruption flags off */    bctu = 1;				/* Block check back to 1 */    ebqflg = rptflg = 0;		/* 8th bit & repeat quoting off */    sq = 'Y';				/* Normal 8th bit quote bid */    rqf = -1;				/* Flag that no 8-b-q bid seen yet */    seq = 0;				/* Start off with packet zero */    *filnam = *sndpkt = *rcvpkt = NUL;	/* Clear out string buffers */}VOIDerrpkt(s) char *s; {			/* Fatal error */    if (start == 'v' || start == 'r')	/* Receiving a file? */      sleep(1);				/* Time to soak up incoming junk. */    spacket('E',seq,(int)strlen(s),s); 	/* Send Error packet. */    doexit(1);				/* Exit with failure status. */}int#ifdef __STDC__sinit(char c)#elsesinit(c) char c;#endif /* __STDC__ */{					/* Begin send */    char *s;    s = rpar();				/* Get our protocol parameters */    if (c == 'S') {			/* Sending a file... */	tmsgl(versio);	tmsgl("Escape back to your local Kermit and give a RECEIVE command.");	tmsgl("");	tmsgl("KERMIT READY TO SEND...");	sleep(delay);    }    return(spacket(c,seq,strlen(s),s));	/* Send S or I packet */}intsfile() {				/* Send file header packet */    int x;    char pktnam[MAXPATHLEN];    if (debug)      fprintf(db,"sfile filnam [%s] max = %d\n",filnam,MAXPATHLEN);    if (zopeni(filnam) < 0) {		/* Open the input file */	if (debug)	  fprintf(db,"sfile error %d",errno);	errpkt("Failure to open file");    }    if (cmarg2)				/* User-supplied name - use as-is */      strncpy(pktnam,cmarg2,MAXPATHLEN);    else				/* Actual filename - convert */      zltor(filnam,pktnam,MAXPATHLEN);    cmarg2 = NULL;			/* Only works for one file */    if (debug)      fprintf(db,"sfile pktnam %s\n",pktnam);    x = encstr(pktnam);			/* Encode name */    if (debug)      fprintf(db,"sfile encstr[%s] x=%d\n",xdata,x);    first = 1;				/* Starting condition for file */    maxsiz = spsiz - (bctr + 3);	/* Maximum packet data field length */    if (spsiz > 94) maxsiz -= 4;	/* Long packet has more fields */    nxtpkt();				/* Get next packet number */    return(spacket('F',seq,x,xdata));	/* Send filename */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -