diff --git a/Makefile.freebsd b/Makefile.freebsd index 8379b14..6c2d050 100644 --- a/Makefile.freebsd +++ b/Makefile.freebsd @@ -34,7 +34,7 @@ OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list. $(CC) -c -o $@ $< $(CFLAGS) magicka: $(OBJ) ${LUA} ${JAMLIB} ${ZMODEM} ${JSMN} - $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh + $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh -liconv magimail: $(JAMLIB) cd utils/magimail && $(MAKE) freebsd diff --git a/Makefile.freebsd.WWW b/Makefile.freebsd.WWW index 3b76f56..b600e2d 100644 --- a/Makefile.freebsd.WWW +++ b/Makefile.freebsd.WWW @@ -39,7 +39,7 @@ OBJ = deps/aha/aha.o inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o do $(CC) -c -o $@ $< $(CFLAGS) magicka: $(OBJ) ${LUA} ${ZMODEM} ${JAMLIB} ${B64} ${JSMN} - $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh $(MICROHTTPD) + $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh -liconv $(MICROHTTPD) magimail: $(JAMLIB) cd utils/magimail && $(MAKE) freebsd diff --git a/Makefile.linux b/Makefile.linux index 8c4b2ad..71ff5c1 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -35,7 +35,7 @@ OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o $(CC) -c -o $@ $< $(CFLAGS) magicka: $(OBJ) ${LUA} ${ZMODEM} ${JAMLIB} ${JSMN} - $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -ldl -lssl -lcrypto -lssh + $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -ldl -lssl -lcrypto -lssh -liconv magimail: $(JAMLIB) cd utils/magimail && $(MAKE) linux diff --git a/Makefile.linux.WWW b/Makefile.linux.WWW index 8e53977..d868726 100644 --- a/Makefile.linux.WWW +++ b/Makefile.linux.WWW @@ -39,7 +39,7 @@ OBJ = deps/aha/aha.o inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o do $(CC) -c -o $@ $< $(CFLAGS) magicka: $(OBJ) ${LUA} ${JAMLIB} ${ZMODEM} ${B64} ${JSMN} - $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -ldl -lssl -lcrypto -lssh $(MICROHTTPD) + $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/local/lib -lsqlite3 -lutil -lm -ldl -lssl -lcrypto -lssh -liconv $(MICROHTTPD) magimail: $(JAMLIB) cd utils/magimail && $(MAKE) linux diff --git a/Makefile.netbsd b/Makefile.netbsd index 8ebda68..2e56955 100644 --- a/Makefile.netbsd +++ b/Makefile.netbsd @@ -34,7 +34,7 @@ OBJ = inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o doors.o bbs_list.o $(CC) -c -o $@ $< $(CFLAGS) magicka: $(OBJ) ${LUA} ${ZMODEM} ${JAMLIB} ${JSMN} - $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/pkg/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh + $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/pkg/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh -liconv magiedit: $(ODOORS) cd utils/magiedit && $(MAKE) diff --git a/Makefile.netbsd.WWW b/Makefile.netbsd.WWW index abf326e..50ddd12 100644 --- a/Makefile.netbsd.WWW +++ b/Makefile.netbsd.WWW @@ -39,7 +39,7 @@ OBJ = deps/aha/aha.o inih/ini.o bbs.o main.o users.o main_menu.o mail_menu.o do $(CC) -c -o $@ $< $(CFLAGS) magicka: $(OBJ) ${LUA} ${ZMODEM} ${JAMLIB} ${B64} ${JSMN} - $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/pkg/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh $(MICROHTTPD) + $(CC) -o magicka -o $@ $^ $(CFLAGS) -L/usr/pkg/lib -lsqlite3 -lutil -lm -lssl -lcrypto -lssh -liconv $(MICROHTTPD) magiedit: $(ODOORS) cd utils/magiedit && $(MAKE) diff --git a/bbs.h b/bbs.h index 01b699e..58ab727 100644 --- a/bbs.h +++ b/bbs.h @@ -45,6 +45,7 @@ struct door_config { char *name; char *command; int stdio; + char *codepage; }; struct mail_area { @@ -144,6 +145,7 @@ struct bbs_config { char *menu_path; char *external_editor_cmd; int external_editor_stdio; + char *external_editor_codepage; int fork; int nodes; @@ -273,8 +275,8 @@ extern void next_mail_area(struct user_record *user); extern void prev_mail_area(struct user_record *user); extern void post_message(struct user_record *user); -extern void rundoor(struct user_record *user, char *cmd, int stdio); -extern void runexternal(struct user_record *user, char *cmd, int stdio, char **argv, char *cwd, int raw); +extern void rundoor(struct user_record *user, char *cmd, int stdio, char *codepage); +extern void runexternal(struct user_record *user, char *cmd, int stdio, char **argv, char *cwd, int raw, char *codepage); extern void bbs_list(struct user_record *user); diff --git a/config_default/bbs.ini b/config_default/bbs.ini index 0117907..e404c48 100644 --- a/config_default/bbs.ini +++ b/config_default/bbs.ini @@ -1,5 +1,5 @@ [main] -Codepage = cp437 +Codepage = CP437 Telnet Port = 2023 BBS Name = Magicka BBS Sysop Name = sysop @@ -11,6 +11,7 @@ MagiChat BBSTag = Magicka Default Tagline = Brought to you by Another Magicka BBS! External Editor cmd = /home/andrew/MagickaBBS/utils/magiedit/magiedit.sh External Editor stdio = true +External Editor Codepage = CP437 Automessage Write Level = 10 Fork = false Enable WWW = false diff --git a/doors.c b/doors.c index 1505d1b..5dba537 100644 --- a/doors.c +++ b/doors.c @@ -9,6 +9,7 @@ #include #include #include +#include #if defined(linux) # include #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) @@ -130,7 +131,7 @@ int write_door32sys(struct user_record *user) { -void rundoor(struct user_record *user, char *cmd, int stdio) { +void rundoor(struct user_record *user, char *cmd, int stdio, char *codepage) { char *arguments[4]; int door_out; char buffer[10]; @@ -147,14 +148,14 @@ void rundoor(struct user_record *user, char *cmd, int stdio) { arguments[2] = strdup(buffer); arguments[3] = NULL; - runexternal(user, cmd, stdio, arguments, NULL, 0); + runexternal(user, cmd, stdio, arguments, NULL, 0, codepage); free(arguments[0]); free(arguments[1]); free(arguments[2]); } -void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], char *cwd, int raw) { +void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], char *cwd, int raw, char *codepage) { char buffer[1024]; int pid; @@ -172,7 +173,8 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c int i; int gotiac; int flush; - + iconv_t ic; + struct timeval thetimeout; struct termios oldit; struct termios oldot; @@ -182,6 +184,11 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c char outbuf[512]; int h; int g; + char *ptr1; + char *ptr2; + size_t ouc; + size_t inc; + timeoutpaused = 1; if (write_door32sys(user) != 0) { @@ -302,7 +309,27 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c } } } - write(master, outbuf, g); + if (codepage == NULL || (strcmp(codepage, "CP437") == 0 && conf.codepage == 0) || (strcmp(codepage, "UTF-8") == 0 && conf.codepage == 1)) { + write(master, outbuf, g); + } else { + if (conf.codepage == 0) { + ic = iconv_open("CP437", codepage); + } else { + ic = iconv_open("UTF-8", codepage); + } + ptr1 = outbuf; + ptr2 = (char *)malloc((g + 1) * 2); + memset(ptr2, 0, (g + 1) * 2); + inc = g; + ouc = g * 2; + + iconv(ic, &ptr1, &inc, &ptr2, &ouc); + ptr2 = ptr2 - (g * 2 - ouc); + write(master, ptr2, strlen(ptr2)); + + free(ptr2); + iconv_close(ic); + } } else if (FD_ISSET(master, &fdset)) { len = read(master, inbuf, 256); if (len == 0) { @@ -317,7 +344,27 @@ void runexternal(struct user_record *user, char *cmd, int stdio, char *argv[], c } outbuf[g++] = c; } - write(door_out, outbuf, g); + if (codepage == NULL || (strcmp(codepage, "CP437") == 0 && conf.codepage == 0) || (strcmp(codepage, "UTF-8") == 0 && conf.codepage == 1)) { + write(door_out, outbuf, g); + } else { + if (conf.codepage == 0) { + ic = iconv_open(codepage, "CP437"); + } else { + ic = iconv_open(codepage, "UTF-8"); + } + ptr1 = outbuf; + ptr2 = (char *)malloc((g + 1) * 2); + memset(ptr2, 0, (g + 1) * 2); + inc = g; + ouc = g * 2; + + iconv(ic, &ptr1, &inc, &ptr2, &ouc); + ptr2 = ptr2 - (g * 2 - ouc); + write(door_out, ptr2, strlen(ptr2)); + + free(ptr2); + iconv_close(ic); + } } } else { if (!running_door) { diff --git a/files.c b/files.c index f65aca0..d10fe62 100644 --- a/files.c +++ b/files.c @@ -439,7 +439,7 @@ int do_download(struct user_record *user, char *file) { arguments[0] = download_command; - runexternal(user, download_command, conf.protocols[user->defprotocol - 1]->stdio, arguments, conf.bbs_path, 1); + runexternal(user, download_command, conf.protocols[user->defprotocol - 1]->stdio, arguments, conf.bbs_path, 1, NULL); free(arguments); } @@ -540,7 +540,7 @@ int do_upload(struct user_record *user, char *final_path) { mkdir(upload_path, 0755); - runexternal(user, upload_command, conf.protocols[user->defprotocol - 1]->stdio, arguments, upload_path, 1); + runexternal(user, upload_command, conf.protocols[user->defprotocol - 1]->stdio, arguments, upload_path, 1, NULL); free(arguments); diff --git a/lua_glue.c b/lua_glue.c index 9b468c9..51f9f3a 100644 --- a/lua_glue.c +++ b/lua_glue.c @@ -100,8 +100,8 @@ int l_bbsMailScan(lua_State *L) { int l_bbsRunDoor(lua_State *L) { char *cmd = (char *)lua_tostring(L, 1); int stdio = lua_toboolean(L, 2); - - rundoor(gUser, cmd, stdio); + char *codepage = (char *)lua_tostring(L, 3); + rundoor(gUser, cmd, stdio, codepage); return 0; } diff --git a/mail_menu.c b/mail_menu.c index d872ee4..ff5f9ec 100644 --- a/mail_menu.c +++ b/mail_menu.c @@ -423,7 +423,7 @@ char *external_editor(struct user_record *user, char *to, char *from, char *quot } fclose(fptr); - rundoor(user, conf.external_editor_cmd, conf.external_editor_stdio); + rundoor(user, conf.external_editor_cmd, conf.external_editor_stdio, conf.external_editor_codepage); // readin msgtmp sprintf(buffer, "%s/node%d/MSGTMP", conf.bbs_path, mynode); diff --git a/main.c b/main.c index 0fd7434..dc14ac7 100644 --- a/main.c +++ b/main.c @@ -210,6 +210,8 @@ static int door_config_handler(void* user, const char* section, const char* name } else { conf->doors[i]->stdio = 0; } + } else if (strcasecmp(name, "codepage") == 0) { + conf->doors[i]->codepage = strdup(value); } return 1; } @@ -224,6 +226,7 @@ static int door_config_handler(void* user, const char* section, const char* name conf->doors[conf->door_count] = (struct door_config *)malloc(sizeof(struct door_config)); conf->doors[conf->door_count]->name = strdup(section); + conf->doors[conf->door_count]->codepage = NULL; if (strcasecmp(name, "command") == 0) { conf->doors[conf->door_count]->command = strdup(value); @@ -233,6 +236,8 @@ static int door_config_handler(void* user, const char* section, const char* name } else { conf->doors[conf->door_count]->stdio = 0; } + } else if (strcasecmp(name, "codepage") == 0) { + conf->doors[conf->door_count]->codepage = strdup(value); } conf->door_count++; @@ -434,6 +439,8 @@ static int handler(void* user, const char* section, const char* name, conf->default_tagline = strdup(value); } else if (strcasecmp(name, "external editor cmd") == 0) { conf->external_editor_cmd = strdup(value); + } else if (strcasecmp(name, "external editor codepage") == 0) { + conf->external_editor_codepage = strdup(value); } else if (strcasecmp(name, "external editor stdio") == 0) { if (strcasecmp(value, "true") == 0) { conf->external_editor_stdio = 1; @@ -482,7 +489,7 @@ static int handler(void* user, const char* section, const char* name, } else if (strcasecmp(name, "codepage") == 0) { if (strcasecmp(value, "cp437") == 0) { conf->codepage = 0; - } else if (strcasecmp(value, "utf8") == 0) { + } else if (strcasecmp(value, "utf-8") == 0) { conf->codepage = 1; } } @@ -1143,6 +1150,7 @@ int main(int argc, char **argv) { conf.mgchat_bbstag = NULL; conf.text_file_count = 0; conf.external_editor_cmd = NULL; + conf.external_editor_codepage = NULL; conf.log_path = NULL; conf.script_path = NULL; conf.automsgwritelvl = 10; diff --git a/menus.c b/menus.c index 2cd1930..e2f1d4e 100644 --- a/menus.c +++ b/menus.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "bbs.h" #include "lua/lua.h" #include "lua/lualib.h" @@ -370,7 +371,7 @@ int menu_system(char *menufile) { for (j=0;jdata, conf.doors[j]->name) == 0) { dolog("%s launched door %s, on node %d", gUser->loginname, conf.doors[j]->name, mynode); - rundoor(gUser, conf.doors[j]->command, conf.doors[j]->stdio); + rundoor(gUser, conf.doors[j]->command, conf.doors[j]->stdio, conf.doors[j]->codepage); dolog("%s returned from door %s, on node %d", gUser->loginname, conf.doors[j]->name, mynode); break; }