diff options
-rw-r--r-- | innbbsd/Makefile | 6 | ||||
-rw-r--r-- | innbbsd/receive_article.c | 7 | ||||
-rw-r--r-- | innbbsd/str_decode.c | 281 |
3 files changed, 290 insertions, 4 deletions
diff --git a/innbbsd/Makefile b/innbbsd/Makefile index 8fd415ad..92214f93 100644 --- a/innbbsd/Makefile +++ b/innbbsd/Makefile @@ -31,21 +31,23 @@ BBS_REC = $(BBS_UTIL)/util_record.o $(BBS_UTIL)/util_cache.o $(BBS_UTIL)/util_pa ############### DEBUGOBJ = /usr/lib/debug/mallocmap.o CFLAGS+= -c -I. -I$(BBS_SRC)/include -I$(BBS_SRC)/mbbsd -D$(BBS_DEP) \ +-I/usr/local/include -L/usr/local/lib \ $(EXTRAFLAGS) -DDBZDEBUG -DBBSHOME='"$(BBSHOME)"' \ -D_PATH_BBSHOME=\"$(BBSHOME)\" \ -DVERSION=\"$(VERSION)\" -DADMINUSER=\"$(ADMINUSER)\" +LDFLAGS+= -liconv # #################################################### OBJS = inndchannel.o innbbsd.o connectsock.o rfc931.o \ daemon.o file.o pmain.o his.o dbz.o \ closeonexec.o dbztool.o inntobbs.o receive_article.o \ - echobbslib.o $(BBS_REC) + echobbslib.o str_decode.o $(BBS_REC) # $(BBS_REC) SRCS = inndchannel.c innbbsd.c connectsock.c rfc931.c \ daemon.c file.c pmain.c parsdate.y his.c dbz.c \ closeonexec.c dbztool.c inntobbs.c bbslib.c receive_article.c \ - port.c + port.c str_decode.c MOBJS = makedbz.o bbslib.o file.o dbz.o closeonexec.o HOBJS = mkhistory.o bbslib.o file.o his.o dbz.o port.o closeonexec.o diff --git a/innbbsd/receive_article.c b/innbbsd/receive_article.c index 0c2827da..6b1e59c7 100644 --- a/innbbsd/receive_article.c +++ b/innbbsd/receive_article.c @@ -545,6 +545,7 @@ receive_control() *firstpath = '\0'; if (isdir(boardhome)) { + strcpy(SUBJECT, str_decode_M3(SUBJECT)); fname = (char *) post_article(boardhome, FROM, "control", bbspost_write_control, NULL, firstpath); if (fname != NULL) { @@ -678,8 +679,10 @@ cancel_article_front(msgid) if (body2 != NULL) *body = '\n'; } - if (*subject) - SUBJECT = subject; + if (*subject){ + strcpy(subject, str_decode_M3(subject)); + SUBJECT = subject; + } fname = (char *) post_article(boardhome, FROM, "deleted", bbspost_write_cancel, filename, firstpath); if (fname != NULL) { diff --git a/innbbsd/str_decode.c b/innbbsd/str_decode.c new file mode 100644 index 00000000..23a10551 --- /dev/null +++ b/innbbsd/str_decode.c @@ -0,0 +1,281 @@ +/* 使用方法大致如下: innbbsd 中 + 在 SUBJECT 從 news 讀進來後, 呼叫 str_decode_M3(SUBJECT) 就行了 */ + +/* bsd 底下使用要編譯時要加 -I/usr/local/include -L/usr/local/lib -liconv + 並安裝 libiconv, + 若真的沒有iconv就把底下的 #define USE_ICONV 1 刪了 */ + +/*-------------------------------------------------------*/ +/* lib/str_decode.c ( NTHU CS MapleBBS Ver 3.00 ) */ +/*-------------------------------------------------------*/ +/* target : included C for QP/BASE64 decoding */ +/* create : 95/03/29 */ +/* update : 97/03/29 */ +/*-------------------------------------------------------*/ + + +/* ----------------------------------------------------- */ +/* QP code : "0123456789ABCDEF" */ +/* ----------------------------------------------------- */ + +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#define USE_ICONV 1 +/* bsd 底下使用要編譯時要加 -I/usr/local/include -L/usr/local/lib -liconv + 若真的沒有iconv就把上面這行 #define 刪了 */ + +#ifdef USE_ICONV +#include <iconv.h> +#endif + +static int qp_code(int x) +{ + if (x >= '0' && x <= '9') + return x - '0'; + if (x >= 'a' && x <= 'f') + return x - 'a' + 10; + if (x >= 'A' && x <= 'F') + return x - 'A' + 10; + return -1; +} + + +/* ------------------------------------------------------------------ */ +/* BASE64 : */ +/* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */ +/* ------------------------------------------------------------------ */ + + +static int base64_code(int x) +{ + if (x >= 'A' && x <= 'Z') + return x - 'A'; + if (x >= 'a' && x <= 'z') + return x - 'a' + 26; + if (x >= '0' && x <= '9') + return x - '0' + 52; + if (x == '+') + return 62; + if (x == '/') + return 63; + return -1; +} + + +/* ----------------------------------------------------- */ +/* judge & decode QP / BASE64 */ +/* ----------------------------------------------------- */ + +static inline int isreturn(unsigned char c) +{ + return c == '\r' || c == '\n'; +} + +static inline int isspace(unsigned char c) +{ + return c == ' ' || c == '\t' || isreturn(c); +} + +/* static inline */ +int mmdecode(unsigned char *src, unsigned char encode, unsigned char *dst) +{ + /* Thor.980901: src和dst可相同, 但src 一定有?或\0結束 */ + /* Thor.980901: 注意, decode出的結果不會自己加上 \0 */ + unsigned char *t = dst; + int pattern = 0, bits = 0; + encode |= 0x20; /* Thor: to lower */ + switch(encode) + { + case 'q': /* Thor: quoted-printable */ + while(*src && *src != '?') /* Thor: delimiter */ + { /* Thor.980901: 0 算是 delimiter */ + if(*src == '=') + { + int x = *++src, y = x ? *++src : 0; + if(isreturn(x)) continue; + if( (x = qp_code(x)) < 0 || ( y = qp_code(y)) < 0) return -1; + *t++ = (x << 4) + y , src++; + } + else if(*src == '_') + *t++ = ' ', src++; +#if 0 + else if(!*src) /* Thor: no delimiter is not successful */ + return -1; +#endif + else /* Thor: *src != '=' '_' */ + *t++ = *src++; + } + return t - dst; + case 'b': /* Thor: base 64 */ + while(*src && *src != '?') /* Thor: delimiter */ /* Thor.980901: 0也算 */ + { /* Thor: pattern & bits are cleared outside */ + int x; +#if 0 + if (!*src) return -1; /* Thor: no delimiter is not successful */ +#endif + x = base64_code(*src++); + if(x < 0) continue; /* Thor: ignore everything not in the base64,=,.. */ + pattern = (pattern << 6) | x; + bits += 6; /* Thor: 1 code gains 6 bits */ + if(bits >= 8) /* Thor: enough to form a byte */ + { + bits -= 8; + *t++ = (pattern >> bits) & 0xff; + } + } + return t - dst; + } + return -1; +} + +#ifdef USE_ICONV +int str_iconv( + const char *fromcode, /* charset of source string*/ + const char *tocode, /* charset of destination string */ + char *src, /* source string */ + int srclen, /* source string length */ + char *dst, /* destination string */ + int dstlen) /* destination string length */ +/* 這個函式會將一個字串 (src) 從 charset=fromcode 轉成 charset=tocode, + srclen 是 src 的長度, dst 是輸出的buffer, dstlen 則指定了 + dst 的大小, 最後會補 '\0', 所以要留一個byte給'\0'. + 如果遇到 src 中有非字集的字, 或是 src 中有未完整的 byte, + 都會砍掉. + */ +{ + iconv_t iconv_descriptor; + int iconv_ret,dstlen_old; + + dstlen--; /* keep space for '\0' */ + + dstlen_old = dstlen; + + /* Open a descriptor for iconv */ + iconv_descriptor = iconv_open(tocode, fromcode); + + if (iconv_descriptor == ((iconv_t)(-1)) ) /* if open fail */ + { + strncpy(dst,src,dstlen); + return dstlen; + } + + /* Start translation */ + while (srclen > 0 && dstlen > 0) + { + iconv_ret = iconv(iconv_descriptor, &src, &srclen, + &dst, &dstlen); + if (iconv_ret != 0) + { + switch(errno) + { + /* invalid multibyte happened */ + case EILSEQ: + /* forward that byte */ + *dst = *src; + src++; srclen--; + dst++; dstlen--; + break; + /* incomplete multibyte happened */ + case EINVAL: + /* forward that byte (maybe wrong)*/ + *dst = *src; + src++; srclen--; + dst++; dstlen--; + break; + /* dst no rooms */ + case E2BIG: + /* break out the while loop */ + srclen = 0; + break; + } + } + } + *dst = '\0'; + /* close descriptor of iconv*/ + iconv_close(iconv_descriptor); + + return (dstlen_old - dstlen); +} +#endif + + +void str_decode_M3(unsigned char *str) +{ + int adj; + int i; + unsigned char *src, *dst; + unsigned char buf[512]; + unsigned char charset[512],dst1[512]; + + + src = str; + dst = buf; + adj = 0; + + while (*src && (dst - buf) < sizeof(buf) - 1) + { + if (*src != '=') + { /* Thor: not coded */ + unsigned char *tmp = src; + while(adj && *tmp && isspace(*tmp)) tmp++; + if(adj && *tmp=='=') + { /* Thor: jump over space */ + adj = 0; + src = tmp; + } + else + *dst++ = *src++; + /* continue;*/ /* Thor: take out */ + } + else /* Thor: *src == '=' */ + { + unsigned char *tmp = src + 1; + if(*tmp == '?') /* Thor: =? coded */ + { + /* "=?%s?Q?" for QP, "=?%s?B?" for BASE64 */ + tmp ++; + i=0; + while(*tmp && *tmp != '?') + { + if (i+1<sizeof(charset)) + { + charset[i] = *tmp; + charset[i+1]='\0'; + i++; + } + tmp++; + } + if(*tmp && tmp[1] && tmp[2]=='?') /* Thor: *tmp == '?' */ + { +#ifdef USE_ICONV + int i = mmdecode(tmp + 3, tmp[1], dst1); + i = str_iconv(charset,"big5",dst1,i,dst, + sizeof(buf)-((int)(dst-buf)) ); +#else + int i = mmdecode(tmp + 3, tmp[1], dst); +#endif + if (i >= 0) + { + tmp += 3; /* Thor: decode's src */ +#if 0 + while(*tmp++ != '?'); /* Thor: no ? end, mmdecode -1 */ +#endif + while(*tmp && *tmp++ != '?'); /* Thor: no ? end, mmdecode -1 */ + /* Thor.980901: 0 也算 decode 結束 */ + if(*tmp == '=') tmp++; + src = tmp; /* Thor: decode over */ + dst += i; + adj = 1; /* Thor: adjcent */ + } + } + } + + while(src != tmp) /* Thor: not coded */ + *dst++ = *src++; + } + } + *dst = 0; + strcpy(str, buf); +} |