diff options
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/convert.c | 119 | ||||
-rw-r--r-- | mbbsd/io.c | 34 | ||||
-rw-r--r-- | mbbsd/kaede.c | 2 | ||||
-rw-r--r-- | mbbsd/mbbsd.c | 18 |
4 files changed, 144 insertions, 29 deletions
diff --git a/mbbsd/convert.c b/mbbsd/convert.c index 141548d1..6ced7d2a 100644 --- a/mbbsd/convert.c +++ b/mbbsd/convert.c @@ -4,9 +4,11 @@ * The following code is copied and modified from "autoconvert" with GPL. */ -#ifdef GB_CONVERT +#ifdef CONVERT #include "convert.h" +#include "iconv.h" + char *hzconvert(char *, int *, char *, void (*dbcvrt)()); @@ -15,6 +17,8 @@ extern const unsigned char GtoB[], BtoG[]; #define c1 (unsigned char)(s[0]) #define c2 (unsigned char)(s[1]) +/* Convert: Big5 <-> GB */ + static void g2b(char *s) { unsigned int i; @@ -74,4 +78,117 @@ unsigned char *big2gb(unsigned char *s, int plen) unsigned char c = 0; return hzconvert(s, &plen, &c, b2g); } + +int gb_converting_read(int fd, void *buf, size_t count) +{ + int len = read(fd, buf, count); + if (len >= 0) + gb2big(buf, len); + return len; +} + +int gb_converting_write(int fd, void *buf, size_t count) +{ + big2gb(buf, count); + return write(fd, buf, count); +} + +/* Convert: Big5 <-> Unicode */ + +/**************************/ +static iconv_t big2ucs, ucs2big; + +int ucs_converting_init(void) +{ + big2ucs = iconv_open("utf8", "big5"); + ucs2big = iconv_open("big5", "utf8"); + return (big2ucs < 0 || ucs2big < 0); +} + +int str_iconv(iconv_t desc, char *src, int srclen) +{ + int iconv_ret; + /* Start translation */ + while (srclen > 0) { + iconv_ret = iconv(desc, (const char* *)&src, &srclen, &src, &srclen); + // deslen - 1 ?? iconv_ret = iconv(desc, (const char* *)&src, &srclen, &src, &srclen); + if (iconv_ret != 0) { + switch(errno) { + case EILSEQ: + /* forward that byte */ + src++; srclen--; + break; + /* incomplete multibyte happened */ + case EINVAL: + /* forward that byte (maybe wrong)*/ + src++; srclen--; + break; + /* des no rooms */ + case E2BIG: + /* break out the while loop */ + srclen = 0; + break; + } + } + } + *src= '\0'; + return srclen; +} + +//int str_iconv(iconv_t desc, char *src, int srclen) +//{ +// deslen--; /* keep space for '\0' */ +// deslen_old = deslen; +// +// /* Start translation */ +// while (srclen > 0 && deslen > 0) { +// iconv_ret = iconv(desc, (const char* *)&src, &srclen, &des, &deslen); +// if (iconv_ret != 0) { +// switch(errno) { +// case EILSEQ: +// /* forward that byte */ +// *des = *src; +// src++; srclen--; +// des++; deslen--; +// break; +// /* incomplete multibyte happened */ +// case EINVAL: +// /* forward that byte (maybe wrong)*/ +// *des = *src; +// src++; srclen--; +// des++; deslen--; +// break; +// /* des no rooms */ +// case E2BIG: +// /* break out the while loop */ +// srclen = 0; +// break; +// } +// } +// } +// *des = '\0'; +// return deslen_old - deslen; +//} + +int ucs_converting_read(int fd, void *buf, size_t count) +{ + int len; + if ((len = read(fd, buf, count)) < 0) + str_iconv(ucs2big, buf, count); + return len; +} + +int ucs_converting_write(int fd, void *buf, size_t count) +{ + str_iconv(big2ucs, buf, count); + return write(fd, buf, count); +} + +/* we don't need it since one cannot use it after stop mbbsd +void ucs_finish_converting(void) +{ + iconv_close(big2ucs); + iconv_close(ucs2big); +} +*/ #endif @@ -17,35 +17,25 @@ static int icurrchar = 0; /* ----------------------------------------------------- */ /* convert routines */ /* ----------------------------------------------------- */ -#ifdef GB_CONVERT +#ifdef CONVERT typedef int (* read_write_type)(int, void *, size_t); static read_write_type write_type = (read_write_type)write; static read_write_type read_type = read; -int converting_read(int fd, void *buf, size_t count) -{ - int len = read(fd, buf, count); - if (len >= 0) - gb2big(buf, len); - return len; -} - -int converting_write(int fd, void *buf, size_t count) -{ - big2gb(buf, count); - return write(fd, buf, count); -} - void set_converting_type(int which) { - if (which == 0) { + if (which == NOCONVERT) { read_type = read; write_type = (read_write_type)write; } - else if (which == 1) { - read_type = converting_read; - write_type = converting_write; + else if (which == GBCONVERT) { + read_type = gb_converting_read; + write_type = gb_converting_write; + } + else if (which == UCSCONVERT) { + read_type = ucs_converting_read; + write_type = ucs_converting_write; } } @@ -65,7 +55,7 @@ void oflush() { if (obufsize) { -#ifdef GB_CONVERT +#ifdef CONVERT write_wrapper(1, outbuf, obufsize); #else write(1, outbuf, obufsize); @@ -87,7 +77,7 @@ output(char *s, int len) assert(len<OBUFSIZE); if (obufsize + len > OBUFSIZE) { -#ifdef GB_CONVERT +#ifdef CONVERT write_wrapper(1, outbuf, obufsize); #else write(1, outbuf, obufsize); @@ -187,7 +177,7 @@ dogetch() do{ #endif -#ifdef GB_CONVERT +#ifdef CONVERT while ((len = read_wrapper(0, inbuf, IBUFSIZE)) <= 0) { #else while ((len = read(0, inbuf, IBUFSIZE)) <= 0) { diff --git a/mbbsd/kaede.c b/mbbsd/kaede.c index fd3de9ac..f166eb73 100644 --- a/mbbsd/kaede.c +++ b/mbbsd/kaede.c @@ -52,9 +52,7 @@ Ptt_prints(char *str, int mode) strbuf[w++] = '\033'; strbuf[w++] = '*'; strbuf[w++] = str[r]; - ++w; /* 後面有 --w */ } - --w; } } strbuf[w] = 0; diff --git a/mbbsd/mbbsd.c b/mbbsd/mbbsd.c index 1b932dad..c0455df1 100644 --- a/mbbsd/mbbsd.c +++ b/mbbsd/mbbsd.c @@ -510,8 +510,8 @@ inline static void mkuserdir(char *userid) static void login_query() { -#ifdef GB_CONVERT - /* uid 加一位, for gb login */ +#ifdef CONVERT + /* uid 加一位, for converting login */ char uid[IDLEN + 2], passbuf[PASSLEN]; int attempts, len; #else @@ -545,11 +545,15 @@ login_query() getdata(20, 0, "請輸入代號,或以[guest]參觀,以[new]註冊:", uid, sizeof(uid), DOECHO); -#ifdef GB_CONVERT +#ifdef CONVERT /* switch to gb mode if uid end with '.' */ len = strlen(uid); if (uid[0] && uid[len - 1] == '.') { - set_converting_type(1); + set_converting_type(GBCONVERT); + uid[len - 1] = 0; + } + else if (uid[0] && uid[len - 1] == ',') { + set_converting_type(UCSCONVERT); uid[len - 1] = 0; } else if (len >= IDLEN + 1) @@ -1258,6 +1262,12 @@ main(int argc, char *argv[], char *envp[]) signal(SIGUSR2, SIG_IGN); attach_SHM(); +#ifdef CONVERT +/* initiate the converting object before fork() + * to avoid copy on write each time */ + ucs_converting_init(); +#endif + if( (argc == 3 && shell_login(argc, argv, envp)) || (argc != 3 && daemon_login(argc, argv, envp)) ) start_client(); |