📄 gkermit.c
字号:
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 + -