📄 ckcfns.c
字号:
int /* Output character to console. */#ifdef CK_ANSICputtrm(char c)#elseputtrm(c) register char c;#endif /* CK_ANSIC *//* puttrm */ {#ifndef NOSPL extern int cmdsrc(); extern char * qbufp; /* If REMOTE QUERY active, */ extern int query, qbufn; /* also store response in */ if (query && qbufn++ < 1024) { /* query buffer. */ *qbufp++ = c; *qbufp = NUL; } if (!query || !cmdsrc())#endif /* NOSPL */ conoc(c); return(0);}#endif /* NOXFER */int /* Output char to file. */#ifdef CK_ANSICputmfil(char c) /* Just like putfil but to ZMFILE */#else /* rather than ZOFILE... */putmfil(c) register char c;#endif /* CK_ANSIC *//* putmfil */ { debug(F000,"putfil","",c); if (zchout(ZMFILE, (char) (c & fmask)) < 0) { czseen = 1; debug(F101,"putfil zchout write error, setting czseen","",1); return(-1); } return(0);}int /* Output char to file. */#ifdef CK_ANSICputfil(char c)#elseputfil(c) register char c;#endif /* CK_ANSIC *//* putfil */ { debug(F000,"putfil","",c); if (zchout(ZOFILE, (char) (c & fmask)) < 0) { czseen = 1; /* If write error... */ debug(F101,"putfil zchout write error, setting czseen","",1); return(-1); } return(0);}/* The following function is a wrapper for putfil(). The only reason for its existence is to be passed as a function pointer to decode(), which treats putfil() itself specially -- bypassing it and using an internal macro instead to speed things up. Use zputfil() instead of putfil() in cases where we do not want this to happen, e.g. when we need to send output to the file with a mixture of zchout() and zsout()/zsoutl() calls (as is the case with incoming short-form REMOTE command replies redirected to a file), which would otherwise result in data written to the file out of order.*/int#ifdef CK_ANSICzputfil(char c)#elsezputfil(c) register char c;#endif /* CK_ANSIC *//* zputfil */ { return(putfil(c));}#ifndef NOXFER/* D E C O D E -- Kermit packet decoding procedure *//* Call with string to be decoded and an output function. Returns 0 on success, -1 on failure (e.g. disk full). This is the "inner loop" when receiving files, and must be coded as efficiently as possible. Note some potential problems: if a packet is badly formed, having a prefixed sequence ending prematurely, this function, as coded, could read past the end of the packet. This has never happened, thus the additional (time-consuming) tests have not been added.*/static CHAR *xdbuf; /* Global version of decode()'s buffer pointer */ /* for use by translation functions. *//* Function for pushing a character onto decode()'s input stream. */VOID#ifdef CK_ANSICzdstuff(CHAR c)#elsezdstuff(c) CHAR c;#endif /* CK_ANSIC *//* zdstuff */ { xdbuf--; /* Back up the pointer. */ *xdbuf = c; /* Stuff the character. */}#ifdef CKTUNING/* Trimmed-down packet decoder for binary-mode no-parity transfers. decode() is the full version.*/int#ifdef CK_ANSICbdecode(CHAR *buf, int (*fn)(char))#elsebdecode(buf,fn) register CHAR *buf; register int (*fn)();#endif /* CK_ANSIC *//* bdecode */ { register unsigned int a, a7; /* Various copies of current char */ int ccpflg; /* For Ctrl-unprefixing stats */ int t; /* Int version of character */ int len; long z; /* For CRC calculation */ CHAR c; /* Current character */ if (!binary || parity || fn != putfil) /* JUST IN CASE */ return(decode(buf,fn,1)); debug(F100,"BDECODE","",0); xdbuf = buf; /* Global copy of source pointer. */ len = rln; /* Number of bytes in data field */ while (len > 0) { a = *xdbuf++ & 0xff; /* Get next character */ len--; rpt = 0; /* Initialize repeat count. */ if (a == rptq && rptflg) { /* Got a repeat prefix? */ rpt = xunchar(*xdbuf++ & 0xFF); /* Yes, get the repeat count, */ rptn += rpt; a = *xdbuf++ & 0xFF; /* and get the prefixed character. */ len -= 2; } ccpflg = 0; /* Control prefix flag. */ if (a == ctlq) { /* If control prefix, */ a = *xdbuf++ & 0xFF; /* get its operand */ len--; a7 = a & 0x7F; /* and its low 7 bits. */ if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') { /* Controllify */ a = ctl(a); /* if in control range. */ a7 = a & 0x7F; ccpflg = 1; /* Note that we did this */ ccp++; /* Count for stats */ } } else a7 = a & 0x7f; /* Not control quote */ if (a7 < 32 || a7 == 127) /* A bare control character? */ if (!ccpflg) ccu++; /* Count it */ if (!rpt) rpt = 1; for (; rpt > 0; rpt--) { /* Output the char RPT times */#ifdef CALIBRATE if (calibrate) { ffc++; continue; }#endif /* CALIBRATE */#ifdef OS2 if (xflg && !remfile) { /* Write to virtual screen */ char _a; _a = a & fmask; t = conoc(_a); if (t < 1) t = -1; } else#endif /* OS2 */ t = zmchout(a & fmask); /* zmchout is a macro */ if (t < 0) { debug(F101,"bdecode write error - errno","",errno); return(-1); } ffc++; /* Count the character */ if (docrc && !remfile) { /* Update file CRC */ c = a; /* Force conversion to unsigned char */ z = crc16 ^ (long)c; crc16 = (crc16 >> 8) ^ (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]); } }#ifdef CK_CTRLZ lastchar = a;#endif /* CK_CTRLZ */ } return(0);}#endif /* CKTUNING */#endif /* NOXFER *//* P N B Y T E -- Output next byte to file or other destination */static long offc = 0L;static int#ifdef CK_ANSICpnbyte(CHAR c, int (*fn)(char))#elsepnbyte(c,fn) CHAR c; int (*fn)();#endif /* CK_ANSIC *//* pnbyte */ { int rc; long z;#ifdef OS2 if (xflg && !remfile) { /* Write to virtual screen */ char _a; _a = c & fmask; rc = conoc(_a); if (rc < 1) return(-1); } else {#endif /* OS2 */ if (fn == putfil) /* Execute output function */ rc = zmchout(c); /* to-file macro (fast) */ else if (!fn) rc = putchar(c); /* to-screen macro (fast) */ else rc = (*fn)(c); /* function call (not as fast) */ if (rc < 0) return(rc);#ifdef OS2 }#endif /* OS2 *//* Both xgnbyte() and xpnbyte() increment ffc (the file byte counter). During file transfer, only one of these functions is called. However, the TRANSLATE command is likely to call them both. offc, therefore, contains the output byte count, necessary for handling the UCS-2 BOM.*/ offc++; /* Count the byte */ ffc++; /* Count the byte */#ifndef NOXFER if (docrc && !xflg && !remfile) { /* Update file CRC */ z = crc16 ^ (long)c; crc16 = (crc16 >> 8) ^ (crcta[(z & 0xF0) >> 4] ^ crctb[z & 0x0F]); }#endif /* NOXFER */ return(1);}/* X P N B Y T E -- Translate and put next byte to file. Only for Unicode. Call with next untranslated byte from incoming byte stream, which can be in any Transfer Character Set: UCS-2, UTF-8, Latin-1, Latin-Hebrew, etc. Translates to the file character set and writes bytes to the output file. Call with character as int to translate as an int, plus the transfer character set (to translate from) and the file character set (to translate to), or -1,0,0 to reset the UCS-2 byte number (which should be done at the beginning of a file). Returns: -1: On error 0: Nothing to write (mid-sequence) >0: Number of bytes written.*/#ifdef KANJIstatic int jstate = 0, jx = 0; /* For outputting JIS-7 */static char jbuf[16] = { NUL, NUL };#endif /* KANJI */int#ifdef CK_ANSICxpnbyte(int a, int tcs, int fcs, int (*fn)(char))#elsexpnbyte(a,tcs,fcs,fn) int a, tcs, fcs; int (*fn)();#endif /* CK_ANSIC *//* xpnbyte */ {#ifdef UNICODE extern int ucsorder, ucsbom; /* Byte order */#endif /* UNICODE */ CHAR c; /* Unsigned char worker */ static union ck_short uc, eu, sj; /* UCS-2, EUC, and Shift-JIS workers */ USHORT ch; /* ditto... */ USHORT * us = NULL; /* ditto... */ int c7, rc, haveuc = 0; /* Return code and UCS-2 flag */ int utferror = 0; /* UTF-8 error */ static int bn = 0; /* UCS-2 byte number */ int swapping = 0; /* Swapping UCS bytes to output? */ /* swapping must be 0 or 1 */ if (a == -1 && (tcs | fcs) == 0) { /* Reset in case previous run */ bn = 0; /* left bn at 1... */ offc = 0L; debug(F101,"xpnbyte RESET","",bn); return(0); } debug(F001,"xpnbyte a","",a);#ifdef UNICODE if (ucsorder != 1 && ucsorder != 0) /* Also just in case... */ ucsorder = 0; if ((byteorder && !ucsorder) || (!byteorder && ucsorder)) swapping = 1; /* Swapping bytes to output */ if (tcs == TC_UTF8) { /* 'a' is from a UTF-8 stream */ ch = a; if (fcs == TC_UTF8) /* Output is UTF-8 too */ return(pnbyte(ch,fn)); /* so just copy. */ rc = utf8_to_ucs2(ch,&us); /* Otherwise convert to UCS-2 */ if (rc == 0) { /* Done with this sequence */ uc.x_short = *us; /* We have a Unicode */ haveuc = 1; } else if (rc < 0) { /* Error */ debug(F101,"xpnbyte UTF-8 conversion error","",rc); haveuc = 1; /* Replace by U+FFFD */ uc.x_short = *us; utferror = 1; } else /* Sequence incomplete */ return(0); } else if (tcs == TC_UCS2) { /* 'a' is UCS-2 */ /* Here we have incoming UCS-2 in guaranteed Big Endian order */ /* so we must exchange bytes if local machine is Little Endian. */ switch (bn) { /* Which byte? */ case 0: /* High... */ uc.x_char[byteorder] = (unsigned)a & 0xff; bn++; return(0); /* Wait for next */ case 1: /* Low... */ uc.x_char[1-byteorder] = (unsigned)a & 0xff; bn = 0; /* Done with sequence */ haveuc = 1; /* Have a Unicode */ } } else#endif /* UNICODE */#ifdef KANJI /* Whether UNICODE is defined or not */ if (tcs == TC_JEUC) { /* Incoming Japanese EUC */ int bad = 0; static int kanji = 0; /* Flags set in case 0 for case 1 */ static int kana = 0; switch (bn) { /* Byte number */ case 0: /* Byte 0 */ eu.x_short = 0; if ((a & 0x80) == 0) { sj.x_short = (unsigned)a & 0xff; /* Single byte */ kanji = kana = 0; } else { /* Double byte */ c7 = a & 0x7f; if (c7 > 0x20 && c7 < 0x7f) { /* Kanji */ eu.x_char[byteorder] = (CHAR) a; /* Store first byte */ bn++; /* Set up for second byte */ kanji = 1; kana = 0; return(0); } else if (a == 0x8e) { /* SS2 -- Katakana prefix */ eu.x_char[byteorder] = (CHAR) a; /* Save it */ bn++; kana = 1; kanji = 0; return(0); } else { bad++; } } break; case 1: /* Byte 1 */ bn = 0; if (kanji) { eu.x_char[1-byteorder] = (CHAR) a; sj.x_short = eu_to_sj(eu.x_short); break; } else if (kana) { sj.x_short = (CHAR) (a | 0x80); break; } else { /* (shouldn't happen) */ bad++; } } /* Come here with one Shift-JIS character */#ifdef UNICODE if (bad) { uc.x_short = 0xfffd; } else { uc.x_short = sj_to_un(sj.x_short); /* Convert to Unicode */ } haveuc = 1;#endif /* UNICODE */ } else#endif /* KANJI */#ifdef UNICODE uc.x_short = (unsigned)a & 0xff; /* Latin-1 or whatever... */ /* Come here with uc = the character to be translated. */ /* If (haveuc) it's UCS-2 in native order, otherwise it's a byte. */ debug(F101,"xpnbyte haveuc","",haveuc); if (haveuc) { /* If we have a Unicode... */ debug(F101,"xpnbyte uc.x_short A","",uc.x_short); debug(F101,"xpnbyte feol","",feol); if (feol && uc.x_short == CR) { return(0); } else if (feol && uc.x_short == LF) { uc.x_short = feol; } debug(F101,"xpnbyte uc.x_short B","",uc.x_short); if (fcs == FC_UCS2) { /* And FCS is UCS-2 */ /* Write out the bytes in the appropriate byte order */ int count = 0; if (offc == 0L && ucsbom) { /* Beginning of file? */ if ((rc = pnbyte((ucsorder ? 0xff : 0xfe),fn)) < 0) /* BOM */ return(rc); if ((rc = pnbyte((ucsorder ? 0xfe : 0xff),fn)) < 0) return(rc); count += 2; } if (utferror) { if ((rc = pnbyte((ucsorder ? 0xfd : 0xff),fn)) < 0) return(rc); if ((rc = pnbyte((ucsorder ? 0xff : 0xfd),fn)) < 0) return(rc); count += 2; } if ((rc = pnbyte(uc.x_char[swapping],fn)) < 0) return(rc); if ((rc = pnbyte(uc.x_char[1-swapping],fn)) < 0) return(rc); count += 2; return(count); } else if (fcs == FC_UTF8) { /* Convert to UTF-8 */ CHAR * buf = NULL; int i, count; if (utferror) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -