summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
Diffstat (limited to 'mbbsd')
-rw-r--r--mbbsd/convert.c119
-rw-r--r--mbbsd/io.c34
-rw-r--r--mbbsd/kaede.c2
-rw-r--r--mbbsd/mbbsd.c18
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
diff --git a/mbbsd/io.c b/mbbsd/io.c
index f31d5f30..13e313f4 100644
--- a/mbbsd/io.c
+++ b/mbbsd/io.c
@@ -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();