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

📄 ckcfn2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
		    "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 + -