📄 ckcfns.c
字号:
#ifdef KANJI if (!binary && tcharset == TC_JEUC && fcharset != FC_JEUC) { /* Translating from J-EUC */ if (ffc == 0L) xkanjf(); if (xkanji(a,fn) < 0) /* to something else? */ return(-1); } else#endif /* KANJI */#endif /* NOCSETS */ if ((t = zmchout(a & fmask)) < 0) { /* zmchout is a macro */#ifdef COMMENT/* Too costly, uncomment these if you really need them. */ debug(F101,"decode zmchout","",t); debug(F101,"decode zoutcnt","",zoutcnt); debug(F101,"decode a","",a);#endif /* COMMENT */ return(-1); } ffc++; /* Count the character */ } } else { /* Output to something else. */ a &= fmask; /* Apply file mask */ for (; rpt > 0; rpt--) { /* Output the char RPT times */ if ((*fn)((char) a) < 0) return(-1); /* Send to output func. */ ffc++; } } } return(0);}/* G E T P K T -- Fill a packet data field *//* Gets characters from the current source -- file or memory string. Encodes the data into the packet, filling the packet optimally. Set first = 1 when calling for the first time on a given input stream (string or file). Call with: bufmax -- current send-packet size xlate -- flag: 0 to skip character-set translation, 1 to translate Uses global variables: t -- current character. first -- flag: 1 to start up, 0 for input in progress, -1 for EOF. next -- next character. data -- pointer to the packet data buffer. size -- number of characters in the data buffer. memstr - flag that input is coming from a memory string instead of a file. memptr - pointer to string in memory. (*sx)() character set translation functionReturns the size as value of the function, and also sets global "size",and fills (and null-terminates) the global data array. Returns 0 upon eof.Rewritten by Paul W. Placeway (PWP) of Ohio State University, March 1989.Incorporates old getchx() and encode() inline to reduce function calls,uses buffered input for much-improved efficiency, and clears up someconfusion with line termination (CRLF vs LF vs CR).Rewritten again by Frank da Cruz to incorporate locking shift mechanism,May 1991.*//* Lookahead function to decide whether locking shift is worth it. Looks at the next four input characters to see if all of their 8th bits match the argument. Call with 0 or 0200. Returns 1 if so, 0 if not. If we don't happen to have at least 4 more characters waiting in the input buffer, returns 1. Note that zinptr points two characters ahead of the current character because of repeat-count lookahead.*/#ifdef KANJIintkgetf() { return(zminchar());}intkgetm() { int x; if (x = *memptr++) return(x); else return(-1);}#endif /* KANJI */intlslook(b) unsigned int b; { /* Locking Shift Lookahead */ int i; if (zincnt < 3) /* If not enough chars in buffer, */ return(1); /* force shift-state switch. */ b &= 0200; /* Force argument to proper form. */ for (i = -1; i < 3; i++) /* Look at next 5 characters to */ if (((*(zinptr+i)) & 0200) != b) /* see if all their 8th bits match. */ return(0); /* They don't. */ return(1); /* They do. */}intgetpkt(bufmax,xlate) int bufmax, xlate; { /* Fill one packet buffer */ register CHAR rt = t, rnext = next; /* register shadows of the globals */ register CHAR *dp, *odp, *odp2, *p1, *p2; /* pointers... */ register int x; /* Loop index. */ register int a7; /* Low 7 bits of character */ static CHAR leftover[9] = { '\0','\0','\0','\0','\0','\0','\0','\0','\0' }; CHAR xxls, xxdl, xxrc, xxss, xxcq; /* Pieces of prefixed sequence */ int n; /* worker *//* Assume bufmax is the receiver's total receive-packet buffer length. Our whole packet has to fit into it, so we adjust the data field length. We also decide optimally whether it is better to use a short-format or long-format packet when we're near the borderline.*/ n = bufmax - 5; /* Space for Data and Checksum */ if (n > 92 && n < 96) n = 92; /* "Short" Long packets don't pay */ if (n > 92 && lpcapu == 0) /* If long packets needed, */ n = 92; /* make sure they've been negotiated */ bufmax = n - bctl; /* Space for data */ if (n > 92) bufmax -= 3; /* Long packet needs header chksum */ if (first == 1) { /* If first character of this file... */ ffc = 0L; /* Reset file character counter */ first = 0; /* Next character won't be first */ *leftover = '\0'; /* Discard any interrupted leftovers, */ /* get first character of file into rt, watching out for null file */#ifndef NOCSETS#ifdef KANJI if (!binary && tcharset == TC_JEUC && xlate) { x = zkanjf(); if ((x = zkanji( memstr ? kgetm : kgetf )) < 0) { first = -1; size = 0; if (x == -2) { debug(F100,"getpkt(zkanji): input error","",0); cxseen = 1; } else debug(F100,"getpkt(zkanji): empty string/file","",0); return (0); } ffc++; rt = x; } else {#endif /* KANJI */#endif /* not NOCSETS */ if (memstr) { /* Reading data from memory string */ if ((rt = *memptr++) == '\0') { /* end of string ==> EOF */ first = -1; size = 0; debug(F100,"getpkt: empty string","",0); return (0); } } else { /* Reading data from a file */ if ((x = zminchar()) < 0) { /* End of file or input error */ first = -1; size = 0; if (x == -2) { /* Error */ debug(F100,"getpkt: input error","",0); cxseen = 1; /* Interrupt the file transfer */ } else debug(F100,"getpkt: empty file","",0); /* Empty file */ return(0); } ffc++; /* Count a file character */ rt = x; /* Convert int to char */ debug(F101,"getpkt zminchar","",rt); }#ifndef NOCSETS#ifdef KANJI }#endif /* KANJI */#endif /* not NOCSETS */ rt &= fmask; /* Apply SET FILE BYTESIZE mask */ debug(F101,"getpkt fmask","",fmask); debug(F101,"getpkt new rt","",rt);#ifndef NOCSETS if (xlate) { debug(F101,"getpkt about to call translate function","",rt); debug(F101,"tcharset","",tcharset); debug(F101,"fcharset","",fcharset); }#ifdef KANJI if (tcharset != TC_JEUC)#endif /* KANJI */ if (!binary && sx && xlate) { rt = (*sx)(rt); /* Translate */ debug(F101," translate function returns","",rt); }#endif /* not NOCSETS */ /* PWP: handling of NLCHAR is done later (in the while loop)... */ } else if ((first == -1) && (*leftover == '\0')) /* EOF from last time? */ return(size = 0);/* Here we handle characters that were encoded for the last packet but did not fit, and so were saved in the "leftover" array.*/ dp = data; /* Point to packet data buffer */ for (p1 = leftover; (*dp = *p1) != '\0'; p1++, dp++) /* Copy leftovers */ ; *leftover = '\0'; /* Delete leftovers */ if (first == -1) /* Handle EOF */ return(size = (dp - data)); /* Now fill up the rest of the packet. */ rpt = 0; /* Initialize character repeat count */ while (first > -1) { /* Until EOF... */#ifndef NOCSETS#ifdef KANJI if (!binary && xlate && tcharset == TC_JEUC) { if ((x = zkanji( memstr ? kgetm : kgetf )) < 0) { first = -1; if (x == -2) cxseen = 1; } ffc++; rnext = x & fmask; } else {#endif /* KANJI */#endif /* not NOCSETS */ if (memstr) { /* Get next char from memory string */ if ((x = *memptr++) == '\0') /* End of string means EOF */ first = -1; /* Flag EOF for next time. */ rnext = x & fmask; /* Apply file mask */ } else { if ((x = zminchar()) < 0) { /* Real file, check for EOF */ first = -1; /* Flag eof for next time. */ if (x == -2) cxseen = 1; /* If error, cancel this file. */ } rnext = x & fmask; /* Apply file mask */ } ffc++; /* Count the character */#ifndef NOCSETS#ifdef KANJI }#endif /* KANJI */#endif /* not NOCSETS */ /*** debug(F101,"getpkt rnext","",rnext); ***/#ifndef NOCSETS#ifdef KANJI if (tcharset != TC_JEUC)#endif /* KANJI */ if (!binary && sx && xlate) { rnext = (*sx)(rnext); /* Translate */ debug(F101,"getpkt xlated rnext to","",rnext); }#endif /* not NOCSETS */ odp = dp; /* Remember where we started. */ xxls = xxdl = xxrc = xxss = xxcq = NUL; /* Clear these. *//* Now encode the character according to the options that are in effect: binary: text or binary mode. rptflg: repeat counts enabled. ebqflg: 8th-bit prefixing enabled. lscapu: locking shifts enabled.*/ if (rptflg) { /* Repeat processing is on? */ if (#ifdef NLCHAR /* * If the next char is really CRLF, then we cannot * be doing a repeat (unless CR,CR,LF which becomes * "~ <n-1> CR CR LF", which is OK but not most efficient). * I just plain don't worry about this case. The actual * conversion from NL to CRLF is done after the rptflg if... */ (binary || (rnext != NLCHAR)) &&#endif /* NLCHAR */ (rt == rnext) && (first == 0)) { /* Got a run... */ if (++rpt < 94) { /* Below max, just count */ continue; /* go back and get another */ } else if (rpt == 94) { /* Reached max, must dump */ xxrc = tochar(rpt); /* Put the repeat count here */ rptn += rpt; /* Accumulate it for statistics */ rpt = 0; /* And reset it */ } } else if (rpt > 1) { /* More than two */ xxrc = tochar(++rpt); /* and count. */ rptn += rpt; rpt = 0; /* Reset repeat counter. */ } /* If (rpt == 1) we must encode exactly two characters. This is done later, after the first character is encoded. */ }#ifdef NLCHAR if (!binary && (rt == NLCHAR)) { /* It's the newline character */ if (lscapu && lsstate) { /* If SHIFT-STATE is SHIFTED */ if (ebqflg) { /* If single shifts enabled, */ *dp++ = ebq; /* insert a single shift. */ } else { /* Otherwise must shift in. */ *dp++ = myctlq; /* Insert shift-out code */ *dp++ = 'O'; lsstate = 0; /* Change shift state */ } } *dp++ = myctlq; /* Insert carriage return directly */ *dp++ = 'M'; rt = LF; /* Now make next char be linefeed. */ }#endif /* NLCHAR *//* Now handle the 8th bit of the file character. If we have an 8-bit connection, we preserve the 8th bit. If we have a 7-bit connection, we employ either single or locking shifts (if they are enabled).*/ a7 = rt & 0177; /* Get low 7 bits of character */ if (rt & 0200) { /* 8-bit character? */ if (lscapu) { /* Locking shifts enabled? */ if (!lsstate) { /* Not currently shifted? */ x = lslook(0200); /* Look ahead */ if (x != 0 || ebqflg == 0) { /* Locking shift decision */ xxls = 'N'; /* Need locking shift-out */ lsstate = 1; /* and change to shifted state */ } else if (ebqflg) { /* Not worth it */ xxss = ebq; /* Use single shift */ } } rt = a7; /* Replace character by 7-bit value */ } else if (ebqflg) { /* 8th bit prefixing is on? */ xxss = ebq; /* Insert single shift */ rt = a7; /* Replace character by 7-bit value */ } } else if (lscapu) { /* 7-bit character */ if (lsstate) { /* Comes while shifted out? */ x = lslook(0); /* Yes, look ahead */ if (x || ebqflg == 0) { /* Time to shift in. */ xxls = 'O'; /* Set shift-in code */ lsstate = 0; /* Exit shifted state */ } else if (ebqflg) { /* Not worth it, stay shifted out */ xxss = ebq; /* Insert single shift */ } } } /* If data character is significant to locking shift protocol... */ if (lscapu && (a7 == SO || a7 == SI || a7 == DLE)) xxdl = 'P'; /* Insert datalink escape */ if ((a7 < SP) || (a7 == DEL)) { /* Do control prefixing if necessary */ xxcq = myctlq; /* The prefix */ rt = ctl(rt); /* Uncontrollify the character */ } if (a7 == myctlq) /* Always prefix the control prefix */ xxcq = myctlq; if ((rptflg) && (a7 == rptq)) /* If it's the repeat prefix, */ xxcq = myctlq; /* prefix it if doing repeat counts */ if ((ebqflg) && (a7 == ebq)) /* Prefix the 8th-bit prefix */ xxcq = myctlq; /* if doing 8th-bit prefixes *//* Now construct the entire sequence */ if (xxls) { *dp++ = myctlq; *dp++ = xxls; } /* Locking shift */ odp2 = dp; /* (Save this place) */ if (xxdl) { *dp++ = myctlq; *dp++ = xxdl; } /* Datalink escape */ if (xxrc) { *dp++ = rptq; *dp++ = xxrc; } /* Repeat count */ if (xxss) { *dp++ = ebq; } /* Single shift */ if (xxcq) { *dp++ = myctlq; } /* Control prefix */ *dp++ = rt; /* Finally, the character itself */ if (rpt == 1) { /* Exactly two copies? */ rpt = 0; p2 = dp; /* Save place temporarily */ for (p1 = odp2; p1 < p2; p1++) /* Copy the old chars over again */ *dp++ = *p1; if ((p2-data) <= bufmax) odp = p2; /* Check packet bounds */ } rt = rnext; /* Next character is now current. *//* Done encoding the character. Now take care of packet buffer overflow. */ if ((dp-data) >= bufmax) { /* If too big, save some for next. */ size = (dp-data); /* Calculate the size. */ *dp = '\0'; /* Mark the end. */ if ((dp-data) > bufmax) { /* if packet is overfull */ /* copy the part that doesn't fit into the leftover buffer, */ /* taking care not to split a prefixed sequence. */ for (p1 = leftover, p2=odp; (*p1 = *p2) != '\0'; p1++,p2++) ; debug(F111,"getpkt leftover",leftover,size); debug(F101," osize","",(odp-data)); size = (odp-data); /* Return truncated packet. */ *odp = '\0'; /* Mark the new end */ } t = rt; next = rnext; /* save for next time */ return(size); } } /* Otherwise, keep filling. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -