📄 ckcfn2.c
字号:
"resend logic error: NPS, n=%d, j=%d.",n,j); return(-2);#else/* Just ignore it. */ return(0);#endif /* COMMENT */ } } ttol(s_pkt[j].pk_adr,s_pkt[j].pk_len); /* Everything ok, send the packet */ retrans++; /* Count a retransmission */ screen(SCR_PT,'%',(long)pktnum,"(resend)"); /* Tell user about resend */ logpkt('S',n,s_pkt[j].pk_adr); /* Log the resent packet */ return(s_pkt[j].pk_rtr); /* Return the number of retries. */}interrpkt(reason) CHAR *reason; { /* Send an error packet. */ int x, y; encstr(reason); y = spack('E',pktnum,size,encbuf+7); x = quiet; quiet = 1; /* Close files silently. */ clsif(); clsof(1); quiet = x;#ifdef COMMENT screen(SCR_TC,0,0l,"");#endif /* COMMENT */ if (what < W_CONNECT) xitsta |= what; /* Remember what failed. */ success = 0; return(y);}/* scmd() -- Send a packet of the given type */int#ifdef CK_ANSICscmd(char t, CHAR *dat)#elsescmd(t,dat) char t; CHAR *dat;#endif /* CK_ANSIC *//* scmd */ { encstr(dat); /* Encode the command string */ spack(t,pktnum,size,(CHAR *)(encbuf+7)); return(0);}VOIDsrinit() { /* Send R (GET) packet */ encstr((CHAR *)cmarg); /* Encode the filename. */ spack('R',pktnum,size,encbuf+7); /* Send the packet. */}/* R P A C K -- Read a Packet *//* rpack reads a packet and returns the packet type, or else Q if the packet was invalid, or T if a timeout occurred. Upon successful return, sets the values of global rsn (received sequence number), rln (received data length), and rdatap (pointer to null-terminated data field).*/intrpack() { register int i, j, x, lp; /* Local variables */ int k, type, chklen; unsigned crc; CHAR pbc[4]; /* Packet block check */ CHAR *sohp; /* Pointer to SOH */ CHAR e; /* Packet end character */ debug(F101,"entering rpack, pktnum","",pktnum); k = getrbuf(); /* Get a new packet input buffer. */ debug(F101,"rpack getrbuf","",k); if (k < 0) return(-1); /* Return like this if none free. */ recpkt = r_pkt[k].bf_adr; *recpkt = '\0'; /* Clear receive buffer. */ sohp = recpkt; /* Initialize pointers to it. */ rdatap = recpkt; rsn = rln = -1; /* In case of failure. */ e = (turn) ? turnch : eol; /* Use any handshake char for eol *//* Try to get a "line". */#ifdef PARSENSE#ifdef UNIX/* So far the final turn argument is only for ck[uvd]tio.c. Should be added to the others too. (turn == handshake character.)*/ j = ttinl(recpkt,r_pkt[k].bf_len - 1,timint,e,stchr,turn);#else#ifdef VMS j = ttinl(recpkt,r_pkt[k].bf_len - 1,timint,e,stchr,turn);#else#ifdef datageneral j = ttinl(recpkt,r_pkt[k].bf_len - 1,timint,e,stchr,turn);#else j = ttinl(recpkt,r_pkt[k].bf_len - 1,timint,e,stchr);#endif /* datageneral */#endif /* VMS */#endif /* UNIX */ if (parity != ttprty) autopar = 1; parity = ttprty; #else j = ttinl(recpkt,r_pkt[k].bf_len - 1,timint,e);#endif /* PARSENSE */ if (j < 0) { debug(F101,"rpack: ttinl fails","",j); /* Otherwise, */ freerbuf(k); /* Free this buffer */ if (j < -1) { /* Bail out if ^C^C typed. */ debug(F101,"rpack ^C server","",server); debug(F101,"rpack ^C en_fin","",en_fin); if (server == 0) return(j); /* But not if in server mode */ else if (en_fin) return(j); /* with DISABLE FINISH */ } if (nakstate) /* call it a timeout. */ screen(SCR_PT,'T',(long)winlo,""); else screen(SCR_PT,'T',(long)pktnum,""); logpkt('r',-1,(CHAR *)"<timeout>"); if (flow == 1) ttoc(XON); /* In case of Xoff blockage. */ return('T'); } rpktl = j; tlci += j; /* All OK, Count the characters. */ flci += j;#ifndef PARSENSE/* THEN eliminate this loop... */ for (i = 0; (recpkt[i] != stchr) && (i < j); i++) sohp++; /* Find mark */ if (i++ >= j) { /* Didn't find it. */ logpkt('r',-1,"<timeout>"); freerbuf(k); return('T'); } #else i = 1;#endif /* PARSENSE */ rpackets++; lp = i; /* Remember LEN position. */ if ((j = xunchar(recpkt[i++])) == 0) { if ((j = lp+5) > MAXRP) return('Q'); /* Long packet */ x = recpkt[j]; /* Header checksum. */ recpkt[j] = '\0'; /* Calculate & compare. */ if (xunchar(x) != chk1(recpkt+lp)) { freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:hdr>"); return('Q'); } recpkt[j] = x; /* Checksum ok, put it back. */ rln = xunchar(recpkt[j-2]) * 95 + xunchar(recpkt[j-1]) - bctl; j = 3; /* Data offset. */ } else if (j < 3) { debug(F101,"rpack packet length less than 3","",j); freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:len>"); return('Q'); } else { rln = j - bctl - 2; /* Regular packet */ j = 0; /* No extended header */ } rsn = xunchar(recpkt[i++]); /* Sequence number */ logpkt('r',rsn,sohp); if (rsn < 0 || rsn > 63) { debug(F101,"rpack bad sequence number","",rsn); freerbuf(k); logpkt('r',rsn,(CHAR *)"<crunched:seq>"); return('Q'); }/* If this packet has the same type as the packet just sent, assume it is an echo and ignore it. Don't even bother with the block check calculation: even if the packet is corrupted, we don't want to NAK an echoed packet. (And we certainly don't want to NAK an ACK or NAK!)*/ type = recpkt[i++]; /* Get packet's TYPE field */ if (type == sndtyp || (nakstate && (type == 'N' /* || type == 'Y' */ ))) { debug(F000,"rpack echo","",type); /* If it's an echo */ freerbuf(k); /* Free this buffer */ logpkt('#',rsn,(CHAR *)"<echo:ignored>"); return('e'); /* return special (lowercase) code */ }/* Separate the data from the block check, accounting for the case where a packet was retransmitted after the block check switched.*/ if (type == 'I' || type == 'S') { /* I & S packets always have type 1 */ chklen = 1; rln = rln + bctl - 1; } else if (type == 'N') { /* A NAK packet never has data */ chklen = xunchar(recpkt[lp]) - 2; rln = rln + bctl - chklen; } else chklen = bctl; debug(F101,"rpack bctl","",bctl); debug(F101,"rpack chklen","",chklen); i += j; /* Buffer index of DATA field */ rdatap = recpkt+i; /* Pointer to DATA field */ if ((j = rln + i) > r_pkt[k].bf_len ) { /* Make sure it fits */ debug(F101,"packet sticks out too far","",j); freerbuf(k); logpkt('r',rsn,(CHAR *)"<overflow>"); return('Q'); } for (x = 0; x < chklen; x++) /* Copy the block check */ pbc[x] = recpkt[j+x]; pbc[x] = '\0'; /* Null-terminate block check string */ recpkt[j] = '\0'; /* and the packet DATA field. */ if (chklen == 2 && bctu == 4) { /* Adjust for Blank-Free-2 */ chklen = 4; /* (chklen is now a misnomer...) */ debug(F100,"rpack block check B","",0); } switch (chklen) { /* Check the block check */ case 1: /* Type 1, 6-bit checksum */ if (xunchar(*pbc) != chk1(recpkt+lp)) { debug(F110,"checked chars",recpkt+lp,0); debug(F101,"block check","",(int) xunchar(*pbc)); debug(F101,"should be","",chk1(recpkt+lp)); freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:chk1>"); return('Q'); } break; case 2: /* Type 2, 12-bit checksum */ x = xunchar(*pbc) << 6 | xunchar(pbc[1]); if (x != chk2(recpkt+lp)) { /* No match */ if (type == 'E') { /* Allow E packets to have type 1 */ recpkt[j++] = pbc[0]; recpkt[j] = '\0'; if (xunchar(pbc[1]) == chk1(recpkt+lp)) break; else recpkt[--j] = '\0'; } debug(F110,"checked chars",recpkt+lp,0); debug(F101,"block check","", x); debug(F101,"should be","", (int) chk2(recpkt+lp)); freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:chk2>"); return('Q'); } break; case 3: /* Type 3, 16-bit CRC */ crc = (xunchar(pbc[0]) << 12) | (xunchar(pbc[1]) << 6) | (xunchar(pbc[2])); if (crc != chk3(recpkt+lp)) { if (type == 'E') { /* Allow E packets to have type 1 */ recpkt[j++] = pbc[0]; recpkt[j++] = pbc[1]; recpkt[j] = '\0'; if (xunchar(pbc[2]) == chk1(recpkt+lp)) break; else { j -=2; recpkt[j] = '\0'; } } debug(F110,"checked chars",recpkt+lp,0); debug(F101,"block check","",xunchar(*pbc)); debug(F101,"should be","",(int) chk3(recpkt+lp)); freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:chk3>"); return('Q'); } break; case 4: /* Type 4 = Type 2, no blanks. */ x = (unsigned)((xunchar(*pbc) - 1) << 6) | (unsigned)(xunchar(pbc[1]) - 1); if (x != chk2(recpkt+lp)) { if (type == 'E') { /* Allow E packets to have type 1 */ recpkt[j++] = pbc[0]; recpkt[j] = '\0'; if (xunchar(pbc[1]) == chk1(recpkt+lp)) break; else recpkt[--j] = '\0'; } debug(F101,"bad type B block check","",x); freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:chkb>"); return('Q'); } break; default: /* Shouldn't happen... */ freerbuf(k); logpkt('r',-1,(CHAR *)"<crunched:chkx>"); return('Q'); } debug(F101,"rpack block check OK","",rsn);/* Now we can believe the sequence number, and other fields. *//* Here we violate strict principles of layering, etc, and look at the *//* packet sequence number. If there's already a packet with the same *//* number in the window, we remove this one so that the window will not *//* fill up. */ if ((x = rseqtbl[rsn]) != -1) { /* Already a packet with this number */ retrans++; /* Count it for statistics */ debug(F101,"rpack got dup","",rsn); logpkt('r',rsn,(CHAR *)"<duplicate>"); freerbuf(x); /* Free old buffer, keep new packet. */ r_pkt[k].pk_rtr++; /* Count this as a retransmission. */ }/* New packet, not seen before, enter it into the receive window. */ rseqtbl[rsn] = k; /* Make back pointer */ r_pkt[k].pk_seq = rsn; /* Record in packet info structure */ r_pkt[k].pk_typ = type; /* Sequence, type,... */ r_pkt[k].pk_adr = rdatap; /* pointer to data buffer */ screen(SCR_PT,(char)type,(long)rsn,(char *)sohp); /* Update screen */ return(type); /* Return packet type */}/* L O G P K T -- Log packet number n, pointed to by s. *//* c = 's' (send) or 'r' (receive) */VOID#ifdef CK_ANSIClogpkt(char c,int n, CHAR *s)#elselogpkt(c,n,s) char c; int n; CHAR *s;#endif /* CK_ANSIC *//* logpkt */ { char plog[20]; if (pktlog && *s) { if (n < 0) sprintf(plog,"%c-xx-%02d-",c,(gtimer()%60)); else sprintf(plog,"%c-%02d-%02d-",c,n,(gtimer()%60)); if (zsout(ZPFILE,plog) < 0) pktlog = 0; else if (zsoutl(ZPFILE,(char *)s) < 0) pktlog = 0; }}#ifdef TLOG/* T S T A T S -- Record statistics in transaction log */VOIDtstats() { char *tp; ztime(&tp); /* Get time stamp */ tlog(F110,"End of transaction",tp,0L); /* Record it */ if (filcnt < 1) return; /* If no files, done. *//* If multiple files, record character totals for all files */ if (filcnt > 1) { tlog(F101," files","",filcnt); tlog(F101," total file characters ","",tfc); tlog(F101," communication line in ","",tlci); tlog(F101," communication line out ","",tlco); }/* Record timing info for one or more files */ tlog(F101," elapsed time (seconds) ","",(long) tsecs); if (tsecs > 0) { long lx; lx = (tfc * 10L) / (long) tsecs; tlog(F101," effective data rate ","",lx/10L); if (speed <= 0L) speed = ttgspd(); if (speed > 0L && speed != 8880L && network == 0) { lx = (lx * 100L) / speed; tlog(F101," efficiency (percent) ","",lx); } } tlog(F100,"","",0L); /* Leave a blank line */}/* F S T A T S -- Record file statistics in transaction log */VOIDfstats() { tfc += ffc; tlog(F100," end of file","",0L); tlog(F101," file characters ","",ffc); tlog(F101," communication line in ","",flci); tlog(F101," communication line out ","",flco);}#else /* NOTLOG */VOIDtstats() {}VOIDfstats() { tfc += ffc;}#endif /* TLOG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -