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

📄 ckcfn2.c

📁 KERMIT工具 这在办公室下载不了,很多人都没有载不到.
💻 C
📖 第 1 页 / 共 5 页
字号:
		    dumprbuf();		    type = 'E';		    break;		}		dumprbuf();		/* Debugging */#ifdef OLDCHKINT		if (chkint() < 0) {	/* Check for console interrupts. */		    errpkt((CHAR *)"User cancelled.");		    return(type = 'E');		}#endif /* OLDCHKINT */		/* Got a packet */#ifdef STREAMING		if (streaming) {		/* Streaming */		    if (type == 'Q' || type == 'T') { /* Errors are fatal. */			crunched++;	/* For statistics */			errpkt((CHAR *)"Transmission error on reliable link.");			type = 'E';		    }		}#endif /* STREAMING */		if (type == 'E') {		    debug(F101,"input send got E, nakstate","",nakstate);		    break;		/* Error packet */		}		if (type == 'Q') {	/* Crunched packet */		    crunched++;		/* For statistics */		    numerrs++;		/* For packet resizing */		    x = resend(winlo);	/* Resend window-low */		    if (x < 0) {			type = 'E';			errpkt((CHAR *)"Too many retries");			break;		    }		    continue;		}		if (type == 'T') {	/* Timeout waiting for ACKs. */		    timeouts++;		/* Count it */		    numerrs++;		/* Count an error too */		    debug(F101,"input send state timeout, winlo","",winlo);		    /* Retransmit the oldest un-ACK'd packet. */		    debug(F101,"input send resending winlo","",winlo);		    if (resend(winlo) < 0) { /* Check retries */			debug(F101,"input send too many resends","",maxtry);			errpkt((CHAR *)"Too many retries");			return(type = 'E');		    }#ifdef NEWDPL		    /* Reduce prevailing packet length */		    x = sseqtbl[winlo];	/* Get length of packet we want ACKd */		    if (x > -1) {	/* Only if we have a valid index */			if (s_pkt[x].pk_typ == 'D') { /* only for D packets */			    spsiz = (s_pkt[x].pk_len + 8) >> 1; /* halve it */			    if (spsiz < 20) spsiz = 20; /* within reason */			    debug(F101,"input T cut packet length","",spsiz);			}		    }#endif /* NEWDPL */		    continue;		}	    }	    /* Got an actual normal packet */	    nak2ack = 0;		/* Unset this flag. */	    y = chkwin(rsn,winlo,wslots); /* Is it in the window? */	    debug(F101,"input send rsn","",rsn);	    debug(F101,"input send winlo","",winlo);	    debug(F101,"input send chkwin","",y);	    if (type == 'Y') {		/* Got an ACK */		if (y == 0) {		/* In current window */		    if (spackets < 4)	/* Error counter doesn't count */		      numerrs = 0;	/* until data phase. */		    sacktbl[rsn]++;	/* Mark the packet as ACK'd */		    x = sseqtbl[rsn];	/* Get ACK'd packet's buffer index */		    debug(F101,"bestlen ack x","",x);#ifdef NEWDPL		    if (x > -1) {			acktype = s_pkt[x].pk_typ; /* Get type */			debug(F000,"bestlen ack type","",acktype);			if (acktype == 'D') { /* Adjust data packet length */			    if (spsiz > bestlen) {				bestlen = spsiz;				debug(F101,"bestlen B","",bestlen);			    }#ifdef DEBUG			    if (deblog) {				debug(F101,"bestlen retry","",s_pkt[x].pk_rtr);				debug(F101,"bestlen len","",s_pkt[x].pk_len);				debug(F101,"bestlen spackets","",spackets);			    }#endif /* DEBUG */			    /* Set new best length */			    if (s_pkt[x].pk_rtr == 0 &&				s_pkt[x].pk_len + 8 > bestlen) {				bestlen = s_pkt[x].pk_len + 8;				if (bestlen > spmax)				  bestlen = spmax;				debug(F101,"bestlen A","",bestlen);			    }#ifdef DEBUG			    if (deblog) {				debug(F101,"bestlen wslots","",wslots);				debug(F101,"bestlen maxsend","",maxsend);			    }#endif /* DEBUG */			    /* Slow start */			    if (slostart &&				(maxsend <= spmax) &&				(rpackets < 11) &&				(numerrs == 0)) {				spsiz = spsiz << 1;				debug(F101,"bestlen spsiz A","",spsiz);			    /* Creep up to best length */			    } else if ((spackets > 5) &&				       (spsiz < bestlen - 8)) {				spsiz += (bestlen - spsiz) / 3;				debug(F101,"bestlen spsiz B","",spsiz);			    /* Push the envelope */			    } else if ((spackets % (wslots + 1) == 0) &&				       (spackets > 6) &&				       (bestlen < spmax - 8) &&				       (spsiz < spmax)) {				spsiz += (spmax - bestlen) / 3;				debug(F101,"bestlen spsiz C","",spsiz);			    }			    /* But not too far */			    if (spsiz > spmax) {				spsiz = spmax;				debug(F101,"bestlen spsiz D","",spsiz);			    }			}		    }#endif /* NEWDPL */#ifdef CK_TIMERS		    if (rttflg && timint) /* If doing dynamic timers */		      getrtt(nakstate, rsn); /* call routine to set it. */#endif /* CK_TIMERS *//*  NOTE: The following statement frees the buffer of the ACK we just got.  But the upper layers still need the data, like if it's the ACK to an I,  S, F, D, Z, or just about any kind of packet.  So for now, freerbuf()  deallocates the buffer, but does not erase the data or destroy the pointer  to it.  There's no other single place where these receive buffers can be  correctly freed (?) ...*/		    freerpkt(rsn);	/* Free the ACK's buffer */		    freesbuf(rsn);	/* *** Free the sent packet's buffer */		    if (rsn == winlo) {	/* Got the one we want */			sacktbl[winlo] = 0;			winlo = (winlo + 1) % 64;			debug(F101,"input send rotated send window","",winlo);			break;		/* Return the ACK */		    } else {			debug(F101,"input send mark pkt","",rsn);			continue;	/* Otherwise go read another packet */		    }		} else if (y == 1 && wslots < 2) { /* (190) ACK for previous */		    numerrs++;		/* == NAK for current, count error */		    debug(F101,"input send ACK for previous","",rsn);		    freerpkt(rsn);	/* Free NAK's buffer */		    x = resend(winlo);	/* Resend current packet */		    if (x < 0) {			type = 'E';			errpkt((CHAR *)"Too many retries");			break;		    } else continue;	/* Resend ok, go read another packet */		} else {		/* Other cases, just ignore */		    debug(F101,"input send ACK out of window","",rsn);		    freerpkt(rsn);		    continue;		}	    }	    if (type == 'N') {		/* NAK */		numerrs++;		/* Count an error */#ifdef STREAMING		if (streaming) {		/* Streaming */		    errpkt((CHAR *)"NAK received on reliable link.");		    type = 'E';		    break;		}#endif /* STREAMING */		debug(F101,"input send NAK","",rsn);#ifdef NEWDPL		/* Reduce prevailing packet length */		x = sseqtbl[rsn];	/* Length of packet that was NAK'd */		if (x > -1) {		/* If it's a Data packet we've sent */		    if (s_pkt[x].pk_typ == 'D') {			spsiz = (s_pkt[x].pk_len + 8) >> 1; /* Halve length */#ifdef COMMENT			/* This might be a good idea -- haven't tried it ... */			if (bestlen > 0 && spsiz > bestlen)			  spsiz = bestlen;#endif /* COMMENT */			if (spsiz < 20) spsiz = 20;			debug(F101,"input N cut packet length","",spsiz);		    }		}#endif /* NEWDPL */		freerpkt(rsn);		/* Free buffer where NAK lies. */		if (y == 0) {		/* In current window */		    debug(F100," in window","",0);		    k = sseqtbl[rsn];	/* Get pointer to NAK'd packet. */		    if (k < 0 || (k > -1 && s_pkt[k].pk_typ == ' ')) {			x = resend(winlo); /* Packet we haven't sent yet. */		    } else {			x = resend(rsn); /* Resend requested packet. */		    }		    if (x < 0) {	/* Resend error is fatal.  */			type = 'E';			errpkt((CHAR *)"Too many retries");			break;		    } else continue;	/* Resend ok, go read another packet */		} else if ((rsn == (pktnum + 1) % 64)) { /* NAK for next pkt */		    if (wslots > 1) {			debug( F101,"NAK for next packet, windowing","",rsn);			x = resend(winlo); /* Resend window-low */			if (x < 0) {			    type = 'E';			    errpkt((CHAR *)"Too many retries");			    break;			}			continue;	/* Go back and read another pkt */		    }		    debug(F101,"NAK for next packet, no windowing","",rsn);		    x = (rsn == 0) ? 63 : rsn - 1;		    if (x == 0 && (sndtyp == 'S' || sndtyp == 'I')) {			resend(0);	/* ACK for S or I packet missing */			continue;	/* so resend the S or I */		    }		    rsn = x;		/* Else, treat NAK(n+1) as ACK(n) */		    nak2ack = 1;	/* Go back and process the ACK */		    continue;		} else if (y > 0) {	/* NAK for pkt we can't resend */		    debug(F101," NAK out of window","",rsn); /* bad... */		    type = 'E';		    errpkt((CHAR *)"NAK out of window");		    break;		} else continue;	/* Ignore other NAKs */	    }				/* End of file-sender NAK handler */            if (rsn == winlo) {		/* Not ACK, NAK, timeout, etc. */		debug(F000,"input send unexpected type","",type);		break;	    }	}				/* End of file-sender section */    }					/* End of input() while() loop *//*  When the window size is 1 and we have the packet we want, there can not  possibly be anything waiting for us on the connection that is useful to us.  However, there might be redundant copies of a packet we already got, which  would cause needless cycles of repeated packets.  Therefore we flush the  communications input buffer now to try to get rid of undesired and unneeded  packets that we have not read yet.*/    if (wslotn == 1			/* (not wslots!) */#ifdef STREAMING	&& !streaming			/* But not when streaming */#endif /* STREAMING */	) {	debug(F100,"input about to flush","",0);	ttflui();		/* Got what we want, clear input buffer. */    }#ifndef NEWDPL    if (!nakstate)			/* When sending */      rcalcpsz();			/* recalculate size every packet */#endif /* NEWDPL */    if (type == 'E')      xitsta |= (what ? what : 1);	/* Remember what failed. */    debug(F101,"input winlo","",winlo);    debug(F101,"input rsn","",rsn);    debug(F000,"input returning type","",type);    return(rcvtyp = type);		/* Success, return packet type. */}#ifdef PARSENSE/*  P A R C H K  --  Check if Kermit packet has parity  *//*  Call with s = pointer to packet, start = packet start character, n = length.  Returns 0 if packet has no parity, -1 on error, or, if packet has parity:    'e' for even, 'o' for odd, 'm' for mark.  Space parity cannot be sensed.  So a return value of 0 really means either space or none.  Returns -2 if parity has already been checked during this protocol operation.*/int#ifdef CK_ANSICparchk(CHAR *s, CHAR start, int n)#elseparchk(s,start,n) CHAR *s, start; int n;#endif /* CK_ANSIC *//* parchk */ {    CHAR s0, s1, s2, s3;    debug(F101,"parchk n","",n);    debug(F101,"parchk start","",start);    s0 = s[0] & 0x7f;			/* Mark field (usually Ctrl-A) */    if (s0 != start || n < 5) return(-1); /* Not a valid packet *//* Look at packet control fields, which never have 8th bit set *//* First check for no parity, most common case. */    if (((s[0] | s[1] | s[2] | s[3]) & 0x80) == 0)      return(0);			/* No parity or space parity *//* Check for mark parity */    if (((s[0] & s[1] & s[2] & s[3]) & 0x80) == 0x80)      return('m');			/* Mark parity *//* Packet has some kind of parity *//* Make 7-bit copies of control fields */    s1 = s[1] & 0x7f;			/* LEN */    s2 = s[2] & 0x7f;			/* SEQ */    s3 = s[3] & 0x7f;			/* TYPE *//* Check for even parity */    if ((s[0] == p_tbl[s0]) &&        (s[1] == p_tbl[s1]) &&        (s[2] == p_tbl[s2]) &&	(s[3] == p_tbl[s3]))      return('e');/* Check for odd parity */    if ((s[0] != p_tbl[s0]) &&        (s[1] != p_tbl[s1]) &&        (s[2] != p_tbl[s2]) &&	(s[3] != p_tbl[s3]))      return('o');/* Otherwise it's probably line noise.  Let checksum calculation catch it. */    return(-1);}#endif /* PARSENSE *//*  Check to make sure timeout intervals are long enough to allow maximum  length packets to get through before the timer goes off.  If not, the  timeout interval is adjusted upwards.  This routine is called at the beginning of a transaction, before we  know anything about the delay characteristics of the line.  It works  only for serial communication devices; it trusts the speed reported by  the operating system.  Call with a timout interval.  Returns it, adjusted if necessary.*/intchktimo(timo,flag) int timo, flag; {    long cps, z; int x, y;#ifdef STREAMING    debug(F101,"chktimo streaming","",streaming);    if (streaming)      return(0);#endif /* STREAMING */    debug(F101,"chktimo timo","",timo); /* Timeout before adjustment */    debug(F101,"chktimo flag","",flag);    if (flag)				/* Don't change timeout if user */      return(timo);			/* gave SET SEND TIMEOUT command. */    debug(F101,"chktimo spmax","",spmax);    debug(F101,"chktimo urpsiz","",urpsiz);    if (!network) {			/* On serial connections... */	speed = ttgspd();		/* Get current speed. */	if (speed > 0L) {	    cps = speed / 10L;		/* Convert to chars per second */	    if (cps > 0L) {		long plen;		/* Maximum of send and rcv pkt size */		z = cps * (long) timo;	/* Chars per timeout interval */		z -= z / 10L;		/* Less 10 percent */		plen = spmax;		if (urpsiz > spmax) plen = urpsiz;		debug(F101,"chktimo plen","",plen);		if (z < plen) {		/* Compare with packet size */		    x = (int) ((long) plen / cps); /* Adjust if necessary */		    y = x / 10;		/* Add 10 percent for safety */		    if (y < 2) y = 2;	/* Or 2 seconds, whichever is more */		    x += y;		    if (x > timo)	/* If this is greater than current */		      timo = x;		/* timeout, change the timeout */		    debug(F101,"chktimo new timo","",timo);		}	    }	}    }    return(timo);}/*  S P A C K  --  Construct and send a packet  *//*  spack() sends a packet of the given type, sequence number n, with len data  characters pointed to by d, in either a regular or extended- length packet,  depending on len.  Returns the number of bytes actually sent, or else -1  upon failure.  Uses global npad, padch, mystch, bctu, data.  Leaves packet  fully built and null-terminated for later retransmission by resend().  Updates global sndpktl (send-packet length).  NOTE: The global pointer "data" is assumed to point into the 7th position  of a character array (presumably in packet buffer for the current packet).  It was used by getpkt() to build the packet data field.  spack() fills in  the header to the left of the data pointer (the data pointer is defined

⌨️ 快捷键说明

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