summaryrefslogtreecommitdiffstats
path: root/mbbsd/convert.c
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-04-08 21:43:47 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-04-08 21:43:47 +0800
commite5371ff83e8481cb29f3b9dc1afcfbfa9178c06a (patch)
tree9d9aee81cb42ce7aab590706dc05f640f9ce6bca /mbbsd/convert.c
parent0666dd02983c5a7ad580a29d7d6deec1cbcd80b5 (diff)
downloadpttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.tar
pttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.tar.gz
pttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.tar.bz2
pttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.tar.lz
pttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.tar.xz
pttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.tar.zst
pttbbs-e5371ff83e8481cb29f3b9dc1afcfbfa9178c06a.zip
"Bye-Bye Flying Horse" patch
- a robust and clean TELNET protocol implementation - fixed hz lib (autoconvert) utf8 buffer overflow exploit - enabled term resizing in runtime, and even AYT! - eliminated the flying-horse delay in connecting stage git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@2691 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/convert.c')
-rw-r--r--mbbsd/convert.c97
1 files changed, 71 insertions, 26 deletions
diff --git a/mbbsd/convert.c b/mbbsd/convert.c
index ff9fef5c..a7e1ff31 100644
--- a/mbbsd/convert.c
+++ b/mbbsd/convert.c
@@ -1,11 +1,8 @@
-/* $Id: convert.c 1374 2003-11-27 14:11:40Z victor $ */
+/* $Id$ */
#include "bbs.h"
#ifdef CONVERT
-extern read_write_type write_type;
-extern read_write_type read_type;
-
unsigned char *gb2big(unsigned char *, int *, int);
unsigned char *big2gb(unsigned char *, int *, int);
unsigned char *utf8_uni(unsigned char *, int *, int);
@@ -13,56 +10,104 @@ unsigned char *uni_utf8(unsigned char *, int *, int);
unsigned char *uni2big(unsigned char *, int *, int);
unsigned char *big2uni(unsigned char *, int *, int);
-static ssize_t gb_read(int fd, void *buf, size_t count)
+static ssize_t
+gb_input(void *buf, ssize_t icount)
+{
+ gb2big((char *)buf, &icount, 0);
+ return icount;
+}
+
+static ssize_t
+gb_read(int fd, void *buf, size_t count)
{
- int icount = (int)read(fd, buf, count);
- if (count > 0)
- gb2big((char *)buf, &icount, 0);
- return (size_t)icount;
+ ssize_t icount = read(fd, buf, count);
+ if (icount > 0)
+ icount = gb_input(buf, icount);
+ return icount;
}
-static ssize_t gb_write(int fd, void *buf, size_t count)
+static ssize_t
+gb_write(int fd, void *buf, size_t count)
{
int icount = (int)count;
big2gb((char *)buf, &icount, 0);
- return write(fd, buf, (size_t)icount);
+ if(icount > 0)
+ return write(fd, buf, (size_t)icount);
+ else
+ return count; /* fake */
}
-static ssize_t utf8_read(int fd, void *buf, size_t count)
+static ssize_t
+utf8_input (void *buf, ssize_t icount)
{
- count = read(fd, buf, count);
- if (count > 0) {
- int icount = (int)count;
- utf8_uni(buf, &icount, 0);
- uni2big(buf, &icount, 0);
- ((char *)buf)[icount] = 0;
- return (size_t)icount;
- }
- return count;
+ utf8_uni(buf, &icount, 0);
+ uni2big(buf, &icount, 0);
+ return icount;
+}
+
+static ssize_t
+utf8_read(int fd, void *buf, size_t count)
+{
+ ssize_t icount = read(fd, buf, count);
+ if (icount > 0)
+ icount = utf8_input(buf, icount);
+ return icount;
}
-static ssize_t utf8_write(int fd, void *buf, size_t count)
+static ssize_t
+utf8_write(int fd, void *buf, size_t count)
{
int icount = (int)count;
- big2uni(buf, &icount, 0);
- uni_utf8(buf, &icount, 0);
- ((char *)buf)[icount] = 0;
- return write(fd, buf, (size_t)icount);
+ static char *mybuf = NULL;
+ int cmybuf = 0;
+
+ /* utf8 output is a special case because
+ * we need larger buffer which can be
+ * tripple or more in size.
+ * Current implementation uses 128 for each block.
+ */
+
+ if(cmybuf < count * 4) {
+ cmybuf = (count*4+0x80) & (~0x7f) ;
+ mybuf = (char*) realloc (mybuf, cmybuf);
+ }
+ memcpy(mybuf, buf, count);
+ big2uni(mybuf, &icount, 0);
+ uni_utf8(mybuf, &icount, 0);
+ if(icount > 0)
+ return write(fd, mybuf, (size_t)icount);
+ else
+ return count; /* fake */
}
+static ssize_t
+norm_input(void *buf, ssize_t icount)
+{
+ return icount;
+}
+
+/* global function pointers */
+read_write_type write_type = (read_write_type)write;
+read_write_type read_type = read;
+convert_type input_type = norm_input;
+
void set_converting_type(int which)
{
if (which == CONV_NORMAL) {
read_type = read;
write_type = (read_write_type)write;
+ /* for speed up, NULL is better.. */
+ input_type = NULL; /* norm_input; */
}
else if (which == CONV_GB) {
read_type = gb_read;
write_type = gb_write;
+ input_type = gb_input;
}
else if (which == CONV_UTF8) {
read_type = utf8_read;
write_type = utf8_write;
+ input_type = utf8_input;
}
}