summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/daemon/boardd/boardd.c145
1 files changed, 67 insertions, 78 deletions
diff --git a/pttbbs/daemon/boardd/boardd.c b/pttbbs/daemon/boardd/boardd.c
index 4edfd136..e7933d6e 100644
--- a/pttbbs/daemon/boardd/boardd.c
+++ b/pttbbs/daemon/boardd/boardd.c
@@ -167,6 +167,65 @@ answer_key(struct evbuffer *buf, const char *key)
}
}
+#ifdef CONVERT_TO_UTF8
+
+// Converts given evbuffer contents to UTF-8 and returns the new buffer.
+// The original buffer is freed. Returns NULL on error
+
+struct evbuffer *
+evbuffer_b2u(struct evbuffer *source)
+{
+ unsigned char c[2];
+ int out = 0;
+
+ if (evbuffer_get_length(source) == 0)
+ return source;
+
+ struct evbuffer *destination = evbuffer_new();
+
+ // Peek at first byte
+ while (evbuffer_copyout(source, c, 1) > 0) {
+ if (isascii(c[0])) {
+ if (evbuffer_add(destination, c, 1) < 0)
+ break;
+
+ // Remove byte from source buffer
+ evbuffer_drain(source, 1);
+ out++;
+ } else {
+ // Big5
+
+ // Copy both bytes from source buffer
+ if (evbuffer_copyout(source, c, 2) != 2)
+ break;
+
+ uint8_t utf8[4];
+ int len = ucs2utf(b2u_table[c[0] << 8 | c[1]], utf8);
+ utf8[len] = 0;
+
+ if (evbuffer_add(destination, utf8, len) < 0)
+ break;
+
+ // Remove DBCS character from source buffer
+ evbuffer_drain(source, 2);
+ out += len;
+ }
+ }
+
+ if (evbuffer_get_length(source) == 0 && out) {
+ // Success
+ evbuffer_free(source);
+ return destination;
+ }
+
+ // Fail
+ evbuffer_free(source);
+ evbuffer_free(destination);
+ return NULL;
+}
+
+#endif // CONVERT_TO_UTF8
+
// Command functions
void
@@ -184,6 +243,14 @@ cmd_get(struct bufferevent *bev, void *ctx, int argc, char **argv)
answer_key(buf, *argv);
if (evbuffer_get_length(buf) == 0)
continue;
+#ifdef CONVERT_TO_UTF8
+ buf = evbuffer_b2u(buf);
+ if (buf == NULL) {
+ // Failed to convert
+ buf = evbuffer_new();
+ continue;
+ }
+#endif
evbuffer_add_printf(output, "VALUE %s 0 %ld\r\n", *argv, evbuffer_get_length(buf));
evbuffer_add_buffer(output, buf);
evbuffer_add_printf(output, "\r\n");
@@ -258,81 +325,3 @@ setup_program()
attach_SHM();
}
-#ifdef CONVERT_TO_UTF8
-
-enum bufferevent_filter_result
-filter_pass(struct evbuffer *source, struct evbuffer *destination,
- ev_ssize_t dst_limit, enum bufferevent_flush_mode mode, void *ctx)
-{
- int len = evbuffer_get_length(source);
-
- if (len == 0)
- return BEV_NEED_MORE;
-
- len = evbuffer_remove_buffer(source, destination, dst_limit >= 0 ? dst_limit : len);
-
- return len > 0 ? BEV_OK : (len == 0 ? BEV_NEED_MORE : BEV_ERROR);
-}
-
-enum bufferevent_filter_result
-filter_b2u(struct evbuffer *source, struct evbuffer *destination,
- ev_ssize_t dst_limit, enum bufferevent_flush_mode mode, void *ctx)
-{
- unsigned char c[2];
- int out = 0;
-
- // Peek at first byte
- while (evbuffer_copyout(source, c, 1) > 0) {
- if (isascii(c[0])) {
- // Check for rate limit
- if (dst_limit > 0 && out >= dst_limit)
- break;
-
- if (evbuffer_add(destination, c, 1) < 0)
- return BEV_ERROR;
-
- // Remove byte from source buffer
- evbuffer_drain(source, 1);
- out++;
- } else {
- // Big5
-
- // Check for rate limit
- if (dst_limit > 0 && (out + 1) >= dst_limit)
- break;
-
- // Copy both bytes from source buffer
- if (evbuffer_copyout(source, c, 2) != 2)
- break;
-
- uint8_t utf8[4];
- int len = ucs2utf(b2u_table[c[0] << 8 | c[1]], utf8);
- utf8[len] = 0;
-
- if (evbuffer_add(destination, utf8, len) < 0)
- return BEV_ERROR;
-
- // Remove DBCS character from source buffer
- evbuffer_drain(source, 2);
- out += len;
- }
- }
-
- return out ? BEV_OK : BEV_NEED_MORE;
-}
-
-void
-setup_client(struct event_base *base, evutil_socket_t fd,
- struct sockaddr *address, int socklen)
-{
- struct bufferevent *bev = bufferevent_socket_new(base, fd,
- BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
- struct bufferevent *bev2 = bufferevent_filter_new(bev, filter_pass,
- filter_b2u, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS,
- NULL, NULL);
- bufferevent_setcb(bev2, client_read_cb, NULL, client_event_cb, NULL);
- bufferevent_set_timeouts(bev2, common_timeout, common_timeout);
- bufferevent_enable(bev2, EV_READ|EV_WRITE);
-}
-
-#endif // CONVERT_TO_UTF8