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

📄 gkermit.c

📁 使用Kermit协议传输文件的程序
💻 C
📖 第 1 页 / 共 3 页
字号:
intsattr() {				/* Build and send A packet */    int i, aln;    int binary;    extern long filelength;    nxtpkt();				/* Get next packet sequence number */    if (debug) fprintf(db,"sattr seq %d\n",seq);    i = 0;				/* i = Data field character number */    binary = !text;			/* (for notational convenience) */    xdata[i++] = '"';    if (binary) {			/* Binary */	xdata[i++] = tochar(2);		/*  Two characters */	xdata[i++] = 'B';		/*  B for Binary */	xdata[i++] = '8';		/*  8-bit bytes (note assumption...) */    } else {				/* Text */	xdata[i++] = tochar(3);		/*  Three characters */	xdata[i++] = 'A';		/*  A = (extended) ASCII with CRLFs */	xdata[i++] = 'M';		/*  M for carriage return */	xdata[i++] = 'J';		/*  J for linefeed */	xdata[i++] = '*';		/* Encoding */	xdata[i++] = tochar(1);		/* Length of value is 1 */	xdata[i++] = 'A';		/* A for ASCII */    }    if (filelength > -1L) {	xdata[i] = '1';			/* File length in bytes */	sprintf((char *) &xdata[i+2],"%ld",filelength);	aln = (int)strlen((char *)(xdata+i+2));	xdata[i+1] = tochar(aln);	i += aln + 2;    }    xdata[i] = NUL;			/* Terminate last good field */    aln = (int)strlen((char *)xdata);	/* Get overall length of attributes */    if (debug) fprintf(db,"sattr data %s\n",xdata);    return(spacket('A',seq,aln,xdata)); /* Send it */}#define FTBUFL 10			/* File type buffer */intgattr(s) char *s; {			/* Get attributes from other Kermit */    char c;    int aln, i;    static char ftbuf[FTBUFL+1];    int retcode;			/* Return code */    retcode = 0;			/* Initialize return code. */    while ((c = *s++)) {		/* Get attribute tag */	aln = xunchar(*s++);		/* Length of attribute string */	switch (c) {	  case '"':			/* File type (text, binary, ...) */	    for (i = 0; (i < aln) && (i < FTBUFL); i++)	      ftbuf[i] = *s++;		/* Copy it into a static string */	    ftbuf[i] = '\0';	    if (i < aln) s += (aln - i);	    if ((*ftbuf != 'A' && *ftbuf != 'B' && *ftbuf != 'I')) {		retcode = -1;	/* Reject the file */		break;	    }	    if (*ftbuf == 'A') {	/* Check received attributes. */		text = 1;		/* Set current type to Text. */	    } else if (*ftbuf == 'B') {		text = 0;	    }	    break;	  default:			/* Unknown attribute */	    s += aln;			/* Just skip past it */	    break;	}    }    return(retcode);}intsdata() {				/* Send a data packet */    int x;    if (cx || cz) {			/* Interrupted... */	if (debug)	  fprintf(db,"sdata interrupted cx = %d cz = %d\n",cx,cz);	failure = 1;	return(0);    }    x = getpkt(maxsiz);			/* Fill data field from input file */    if (x < 1) {	if (debug)	  fprintf(db,"sdata getpkt = %d\n",x);	return(0);    }    nxtpkt();				/* Get next packet number */    return(spacket('D',seq,x,xdata));	/* Send the packet */}intseof(s) char *s; {			/* Send end-of-file packet */    if (debug) fprintf(db,"seof [%s]\n",s);    if (zclosi() < 0) {			/* Close the file */	if (debug)	  fprintf(db,"seof zclosi failure %d\n",errno);	errpkt("Failure to close input file");    } else {	int x;        nxtpkt();			/* Get next packet number */	x = spacket('Z',seq,strlen(s),s); /* Send EOF packet */	if (debug)	  fprintf(db,"seof spacket %d\n",x);        return(x);    }    return(0);				/* To shut up picky compilers */}intseot() {				/* Send end-of-transmission packet */    nxtpkt();    return(spacket('B',seq,0,""));}intclosof() {				/* Close output file */    if (zcloso(cx|cz) < 0)      errpkt("Failure to close output file");    return(0);}int					/* Frame and send a packet */#ifdef __STDC__spacket(char type,int n,int len,char *d)#elsespacket(type,n,len,d) char type, *d; int n, len;#endif /* __STDC__ */{    register int i = 0;    int j, k, m, x;    char * p = sndpkt;    for (i = 0; i < spadn; i++)		/* Do requested padding */      p[i] = spadc;    p[i++] = smark;			/* Send-packet mark */    k = i++;				/* Remember this place */    p[i++] = tochar(n);			/* Sequence number */    p[i++] = type;			/* Packet type */    j = len + bctu;    if ((len + bctu + 2) > 94) {	/* If long packet */	x = j / 95;			/* Use long-packet format */	p[k] = tochar(0);	p[i++] = tochar(x);	x = j % 95;	p[i++] = tochar(x);        p[i] = NUL;			/* Terminate for header checksum */        p[i++] = tochar(chk1(&p[k],5));	/* Insert header checksum */    } else				/* Short packet */      p[k] = tochar(j+2);    for (j = len; j > 0; j--) {		/* Data */        p[i++] = *d++;    }    p[i] = NUL;				/* Null-terminate */    m = i - k;    switch (bctu) {			/* Block Check Type Used? */      case 1:				/* Type 1 - 6 bit checksum */	p[i++] = tochar(chk1(p+k,m));	break;      case 2:				/* Type 2 - 12 bit checksum */	j = chksum(p+1,m);	p[i++] = tochar((j >> 6) & 077);	p[i++] = tochar(j & 077);	break;      case 3:				/* Type 3 - 16 bit CRC-CCITT */	j = chk3(p+1,m);	p[i++] = tochar((j >> 12) & 017);	p[i++] = tochar((j >> 6) & 077);	p[i++] = tochar(j & 077);	break;    }    p[i++] = seol;			/* End of line */    p[i] = NUL;				/* Null string-terminator */    sndpkl = i;				/* Remember length. */    x = ttol(p,sndpkl);			/* Send the packet. */    if (x > -1)      sendtype = type;			/* Remember its type */    return(x);}intresend() {				/* Resend a packet */    int x;    if (*sndpkt) {	retries++;	if (debug) fprintf(db,"resend #%d (%d/%d)\n",seq,retries,MAXTRY);	if (retries > MAXTRY) {		/* Check retry limit */	    errpkt("Too many retries");	    doexit(1);	}	x = ttol(sndpkt,sndpkl);   	/* Send previous packet */    } else {	x = nak();			/* or NAK if nothing sent yet. */    }    return(x);}intrpacket() {				/* Read a packet */    register int i = 0;    int j, x, type, rlnpos, rpktl;	/* Local variables */    unsigned int c1, c2;    char * p = rcvpkt;    char pbc[5];			/* Packet block check */    rsn = rln = -1;			/* In case of failure. */    *p = NUL;				/* Initialize the receive buffer. */    j = ttinl(p,maxrp,timint,reol,rmark,0); /* Read a raw packet */    if (j < 5) {			/* Error */	if (j == -1) return('T');	/* Timed out. */	if (j < -1) doexit(1);		/* I/O error, hangup, etc. */	if (debug) fprintf(db,"rpacket runt");	return('Q');			/* Runt */    }    rpktl = j;				/* Remember length. */    rlnpos = ++i;			/* Length position. */    if ((j = xunchar(p[i++])) == 0) {	/* Get packet length.  */        if ((j = rlnpos+5) > rpktl) {	/* Long packet */	    if (debug) fprintf(db,"rpacket bad length");	    return('Q');		/* Too long */	}	x = p[j];			/* Header checksum. */	p[j] = NUL;			/* Calculate & compare. */	if (xunchar(x) != chk1(p+rlnpos,5)) {	    if (debug)	      fprintf(db,"rpacket header checksum: %u\n",x);	    return('Q');	}	p[j] = x;			/* Checksum ok, put it back. */	rln = xunchar(p[j-2]) * 95 + xunchar(p[j-1]) - bctu;	j = 3;				/* Data offset. */    } else if (j < 3) {			/* Bad length */	if (debug) fprintf(db,"rpacket bad xlength");	return('Q');    } else {				/* Regular packet */	rln = j - bctu - 2;		/* No extended header */	j = 0;    }    rsn = xunchar(p[i++]);		/* Sequence number */    type = p[i++];			/* Packet type */    if (debug)      fprintf(db,"rpacket type=%c, seq=%02d, len=%d\n",type,rsn,rln);    i += j;    rdatap = p+i;			/* The data itself */    j = rln + i;			/* Position of block check */    for (x = 0; x < bctu; x++)		/* Copy the block check. */      pbc[x] = p[j+x];    pbc[x] = NUL;    p[j] = NUL;				/* Null-terminate the data */    datalen = j - i;			/* Remember data length */    switch (bctu) {			/* Check the block check */      case 1:	c1 = (unsigned)xunchar((unsigned)((unsigned)(*pbc) & 0xff));	c2 = chk1(p+rlnpos,j-rlnpos);	if (c1 != c2) {	    if (debug) fprintf(db,"rpacket chk1 (0x%x:0x%x)\n",c1,c2);	    return('Q');	}	break;      case 2:	c1 = (unsigned)xunchar(*pbc) << 6 | (unsigned)xunchar(pbc[1]);	c2 = chksum(p+rlnpos,j-rlnpos);	if (c1 != c2) {	    if (debug) fprintf(db,"rpacket chk2 (0x%x:0x%x)\n",c1,c2);	    return('Q');	}	break;      case 3:	c1 = ((unsigned)(xunchar((unsigned)((unsigned)*pbc & 0xff)) << 12) |	      (unsigned)(xunchar((unsigned)((unsigned)pbc[1] & 0xff)) << 6) |	      (unsigned)(xunchar((unsigned)((unsigned)pbc[2] & 0xff)))) &		0xffff;	c2 = chk3(p+rlnpos,j-rlnpos);	if (c1 != c2) {	    if (debug) fprintf(db,"rpacket crc (0x%x:0x%x)\n",c1,c2);	    return('Q');	}	break;      default:	errpkt("BLOCKCHECK");    }    recvtype = type;			/* Remember type. */    return(type);			/* Good packet, return type. */}unsigned intchksum(p,len) char *p; int len; {	/* Generate arithmetic checksum */    register unsigned int k, m;    m = (parity) ? 0177 : 0377;    for (k = 0; len-- > 0; *p++)      k += (unsigned)*p & m;    return(k);}unsigned intchk1(packet,len) char *packet; int len; { /* Generate Type 1 block check */    unsigned int x;    x = chksum(packet,len);    if (debug) fprintf(db,"chksum=%u\n",x);    return((((x & 192) >> 6) + x) & 63);}unsigned intchk3(s,len) char *s; int len; {		/* Tableless 16-bit CRC generator */    register unsigned int c;    register ULONG q, crc = 0L;    while (len-- > 0) {	c = (unsigned)(*s++);	if (parity) c &= 0177;	q = (crc ^ c) & 017;	crc = (crc >> 4) ^ (q * 010201);	q = (crc ^ (c >> 4)) & 017;	crc = (crc >> 4) ^ (q * 010201);    }    if (debug) fprintf(db,"crc=%u\n",(unsigned int)(crc & 0xffff));    return((unsigned int)(crc & 0xffff));}intgetpkt(maxlen) int maxlen; {		/* Fill a packet from file */    int i, next;    static int c;    static char remain[6] = { NUL, NUL, NUL, NUL, NUL, NUL };    if (first == 1) {			/* If first time thru...  */	first = 0;			/* don't do this next time, */	*remain = NUL;			/* discard any old leftovers. */	if (isp) {			/* Get first byte. */	    c = *isp++;			/* Of memory string... */	    if (!c) c = -1;	} else {			/* or file... */	    c = zgetc(text);	}	if (c < 0) {			/* Watch out for empty file. */	    first = -1;	    return(size = 0);	}    } else if (first == -1 && !*remain) { /* EOF from last time? */        return(size = 0);    }    for (size = 0; (xdata[size] = remain[size]) != NUL; size++) ;    *remain = NUL;    if (first == -1)      return(size);    rpt = 0;				/* Initialize repeat counter. */    while (first > -1) {		/* Until end of file or string... */	if (isp) {	    next = *isp++;	    if (!next) next = -1;	} else {	    next = zgetc(text);	}	if (next < 0) first = -1;	/* If none, we're at EOF. */        osize = size;			/* Remember current size. */        encode(c,next);			/* Encode the character. */	c = next;			/* Old next char is now current. */

⌨️ 快捷键说明

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