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

📄 ckcfn2.c

📁 linux终端仿真程序
💻 C
📖 第 1 页 / 共 5 页
字号:
      spack((char)'H',pktnum,size,data); /* Send the packet. */    else      spack((char)(reget ? 'J' : 'R'),pktnum,size,data); /* Send the packet. */    return(0);}/*  K S T A R T  --  Checks for a Kermit packet while in terminal mode.  */#ifdef CK_APCint #ifdef CK_ANSICkstart(CHAR ch)#elsekstart(ch) CHAR ch;#endif /* CK_ANSIC *//* kstart */ {    static int buflen = 94;    static CHAR buf[95];    static CHAR * p = NULL;    extern CHAR stchr, eol;    if (ch == stchr) {			/* Start of packet */	p = buf;	*p = ch;	debug(F101,"kstart SOP","",ch);    } else if (ch == eol) {		/* End of packet */	if (p) {	    p++;	    if (p - buf < 94 ) { 		int rc = 0;		*p = ch;		p++;		*p = NUL;		if (rc = chkspkt((char *)buf))		  debug(F111,"kstart EOP", buf, ch);		p = NULL;		if (!rc) return(0);		return(rc == 1 ? PROTO_K + 1 : 0 - (PROTO_K + 1));	    } else {		p = NULL;	    }	}     } else if (p) {	p++;	if (p - buf < 94)	  *p = ch;	else 	  p = NULL;    }    return(0);}#ifdef CK_XYZ/*  Z S T A R T  --  Checks for a ZMODEM packet while in terminal mode.  */int #ifdef CK_ANSICzstart(CHAR ch)#elsezstart(ch) CHAR ch;#endif /* CK_ANSIC *//* zstart */ {    static CHAR * matchstr = (CHAR *) "\030B00";    /* "rz\r**\030B00000000000000\r\033J\021"; */    static CHAR * p = NULL;    if (!ch)      return(0);    if (!p)      p = matchstr;    if (ch == *p) {	p++;	if (*p == '\0') {	    p = matchstr;	    debug(F100, "zstart Zmodem SOP","",0);	    return(PROTO_Z + 1);	}    } else       p = matchstr;    return(0);}#endif /* CK_XYZ *//*  C H K S P K T  --  Check if buf contains a valid S or I packet  */intchkspkt(buf) char *buf; {    int buflen;    int len = -1;    CHAR chk;    char type = 0;    char *s = buf;    if (!buf) return(0);    buflen = strlen(buf);    if (buflen < 5) return(0);		/* Too short */    if (*s++ != stchr) return(0);	/* SOH */    len = xunchar(*s++);		/* Length */    if (len < 0) return(0);    if (*s++ != SP) return(0);		/* Sequence number */    type = *s++;			/* Type */    if (type != 'S' && type != 'I')      return(0);    if (buflen < len + 2) return(0);    s += (len - 3);			/* Position of checksum */    chk = (CHAR) (*s);			/* Checksum */    *s = NUL;    if (xunchar(chk) != chk1((CHAR *) (buf+1))) return(0); /* Check it */    *s = chk;    return(type == 'S' ? 1 : 2);}#endif /* CK_APC *//* 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), and returns the packet type.*/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 */#ifdef GETMSEC    long t1, t2;#endif /* GETMSEC */    debug(F101,"entering rpack, pktnum","",pktnum);#ifndef OLDCHKINT    if (chkint() < 0)			/* Check for console interrupts. */      return('z');#endif /* OLDCHKINT */    k = getrbuf();			/* Get a new packet input buffer. */    debug(F101,"rpack getrbuf","",k);    if (k < 0) return(-1);		/* Return like this if none free. */    if (pktmsg) *pktmsg = NUL;    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 GETMSEC    if (deblog) t1 = getmsec();#endif /* GETMSEC */#ifdef PARSENSE#ifdef UNIX/*  So far the final turn argument is only for ck[uvdl]tio.c.  Should be added  to the others too.  (turn == handshake character.)*/    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);#else#ifdef VMS    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);#else#ifdef datageneral    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);#else#ifdef STRATUS    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);#else#ifdef OS2    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);#else#ifdef OSK    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr,turn);#else    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e,stchr);#endif /* OSK */#endif /* OS2 */#endif /* STRATUS */#endif /* datageneral */#endif /* VMS */#endif /* UNIX */    if (parity != ttprty) autopar = 1;    parity = ttprty; #else /* !PARSENSE */    j = ttinl(recpkt,r_pkt[k].bf_len - 1,rcvtimo,e);#endif /* PARSENSE */#ifdef GETMSEC    if (deblog)  {	t2 = getmsec();	if (t2 > -1L && t1 > -1L)	  debug(F101,"rpack ttinl time","",t2-t1);	else	  debug(F100,"rpack ttinl time error","",0);    }#endif /* GETMSEC */    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 */	    else return(-2);	}	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>");	    screen(SCR_PT,'%',(long)pktnum,"Bad packet header");	    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>");	screen(SCR_PT,'%',(long)pktnum,"Bad packet length");	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>");	screen(SCR_PT,'%',(long)pktnum,"Bad sequence number");	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>");		screen(SCR_PT,'%',(long)pktnum,"Checksum error");		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>");		screen(SCR_PT,'%',(long)pktnum,"Checksum error");		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,parity)) {		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,parity));		freerbuf(k);		logpkt('r',-1,(CHAR *)"<crunched:chk3>");		screen(SCR_PT,'%',(long)pktnum,"CRC error");		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>");		screen(SCR_PT,'%',(long)pktnum,"Checksum error");		return('Q');	    }	    break;	default:			/* Shouldn't happen... */	    freerbuf(k);	    logpkt('r',-1,(CHAR *)"<crunched:chkx>");	    screen(SCR_PT,'%',(long)pktnum,"(crunched)");	    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

⌨️ 快捷键说明

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