summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/sys/string.c260
-rw-r--r--include/cmsys.h37
-rw-r--r--innbbsd/Makefile4
-rw-r--r--innbbsd/str_decode.c291
-rw-r--r--util/Makefile5
5 files changed, 301 insertions, 296 deletions
diff --git a/common/sys/string.c b/common/sys/string.c
index 72c80cef..e529425c 100644
--- a/common/sys/string.c
+++ b/common/sys/string.c
@@ -471,3 +471,263 @@ char * qp_encode (char *s, size_t slen, const char *d, const char *tocode)
return s0;
}
+// following code is moved from innbbsd/str_decode.c
+/*-------------------------------------------------------*/
+/* 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 */
+/*-------------------------------------------------------*/
+#include <iconv.h>
+
+
+/* ----------------------------------------------------- */
+/* QP code : "0123456789ABCDEF" */
+/* ----------------------------------------------------- */
+
+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
+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;
+}
+
+size_t
+str_iconv(
+ const char *fromcode, /* charset of source string */
+ const char *tocode, /* charset of destination string */
+ const char *src, /* source string */
+ size_t srclen, /* source string length */
+ char *dst, /* destination string */
+ size_t 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;
+ size_t 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);
+}
+
+
+/**
+ * inplace decode mime header string (rfc2047) to big5 encoding
+ *
+ * @param str [in,out] string, assume buffer size 512
+ *
+ * TODO rewrite, don't hardcode 512
+ */
+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 == '?' */
+ int i = mmdecode(tmp + 3, tmp[1], dst1);
+ i = str_iconv((char*)charset, "big5", (char*)dst1, i, (char*)dst,
+ sizeof(buf) - ((int)(dst - buf)));
+ 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((char*)str, (char*)buf);
+}
diff --git a/include/cmsys.h b/include/cmsys.h
index 2b90042c..1b2b4f4e 100644
--- a/include/cmsys.h
+++ b/include/cmsys.h
@@ -104,6 +104,14 @@ extern unsigned StringHash(const char *s);
extern int DBCS_RemoveIntrEscape(unsigned char *buf, int *len);
extern int DBCS_Status(const char *dbcstr, int pos);
extern char * DBCS_strcasestr(const char* pool, const char *ptr);
+extern size_t str_iconv(
+ const char *fromcode, /* charset of source string */
+ const char *tocode, /* charset of destination string */
+ const char *src, /* source string */
+ size_t srclen, /* source string length */
+ char *dst, /* destination string */
+ size_t dstlen);
+extern void str_decode_M3(unsigned char *str);
/* time.c */
extern int is_leap_year(int year);
@@ -166,4 +174,33 @@ extern void Vector_sublist(const struct Vector *src, struct Vector *dst, const c
extern int Vector_remove(struct Vector *self, const char *name);
extern int Vector_search(const struct Vector *self, const char *name);
+/* telnet.c */
+struct TelnetCallback {
+ void (*term_resize)(int w, int h);
+ void (*update_client_code)(void *ccctx, unsigned char seq);
+};
+#define TELNET_IAC_MAXLEN (16)
+
+struct TelnetCtx {
+ int fd; // should be blocking fd
+ unsigned char iac_state;
+
+ unsigned char iac_quote;
+ unsigned char iac_opt_req;
+
+ unsigned char iac_buf[TELNET_IAC_MAXLEN];
+ unsigned int iac_buflen;
+
+ const struct TelnetCallback *callback;
+ void *ccctx; // client code detection contex
+};
+typedef struct TelnetCtx TelnetCtx;
+
+extern TelnetCtx *telnet_create_contex(void);
+extern void telnet_ctx_init(TelnetCtx *ctx, const struct TelnetCallback *callback, int fd);
+extern void telnet_ctx_set_ccctx(TelnetCtx *ctx, void *ccctx);
+
+extern void telnet_send_init_cmds(int fd);
+extern ssize_t telnet_process(TelnetCtx *ctx, unsigned char *buf, size_t size);
+
#endif
diff --git a/innbbsd/Makefile b/innbbsd/Makefile
index 676aee46..e698e6f0 100644
--- a/innbbsd/Makefile
+++ b/innbbsd/Makefile
@@ -48,11 +48,11 @@ echobbslib.o: echobbslib.c
innbbsd: 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 str_decode.o nocem.o
+ inntobbs.o receive_article.o echobbslib.o nocem.o
${CC} -o $@ ${LDFLAGS} $> ${LINK_UTIL_OBJS} $(LDLIBS)
bbslink: bbslink.o pmain.o inntobbs.o echobbslib.o connectsock.o \
- file.o port.o str_decode.o
+ file.o port.o
${CC} -o $@ ${LDFLAGS} $> ${LINK_UTIL_OBJS} $(LDLIBS)
bbsnnrp: bbsnnrp.o pmain.o bbslib.o connectsock.o file.o
diff --git a/innbbsd/str_decode.c b/innbbsd/str_decode.c
deleted file mode 100644
index 7a58439d..00000000
--- a/innbbsd/str_decode.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * 使用方法大致如下: 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>
-#include <ctype.h> /* isspace() */
-
-#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 */
-/* ----------------------------------------------------- */
-
-inline int
-isreturn(unsigned char c)
-{
- return c == '\r' || c == '\n';
-}
-
-#if 0 /* in glibc */
-inline int
-isspace(unsigned char c)
-{
- return c == ' ' || c == '\t' || isreturn(c);
-}
-#endif
-
-/* 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
-size_t
-str_iconv(
- const char *fromcode, /* charset of source string */
- const char *tocode, /* charset of destination string */
- char *src, /* source string */
- size_t srclen, /* source string length */
- char *dst, /* destination string */
- size_t 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;
- size_t 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((char*)charset, "big5", (char*)dst1, i, (char*)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((char*)str, (char*)buf);
-}
diff --git a/util/Makefile b/util/Makefile
index b9bb8eb3..2570bc0b 100644
--- a/util/Makefile
+++ b/util/Makefile
@@ -69,9 +69,8 @@ util_${fn}.o: ${BBSBASE} $(SRCROOT)/mbbsd/${fn}.c
shmctl: ${BBSBASE} shmctl.c ${UTIL_OBJS}
${CC} ${CFLAGS} ${LDFLAGS} -o shmctl ${UTIL_OBJS} shmctl.c $(LDLIBS)
-bbsmail: ${BBSBASE} bbsmail.c $(SRCROOT)/innbbsd/str_decode.c $(UTIL_OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) -o bbsmail -DUSE_ICONV \
- bbsmail.c $(SRCROOT)/innbbsd/str_decode.c $(UTIL_OBJS) $(LDLIBS)
+bbsmail: ${BBSBASE} bbsmail.c $(UTIL_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o bbsmail bbsmail.c $(UTIL_OBJS) $(LDLIBS)
install: $(PROGS)
install -d $(BBSHOME)/bin/