diff --git a/src/bbs.c b/src/bbs.c index 317ca0b..54dbc6d 100644 --- a/src/bbs.c +++ b/src/bbs.c @@ -256,12 +256,18 @@ void s_putchar(char c) { size_t inc; size_t ouc; size_t sz; + int ret; if (!should_convert_utf8()) { if (sshBBS) { putchar(c); } else { - write(gSocket, &c, 1); + ret = send(gSocket, &c, 1, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } } else { ic = iconv_open("UTF-8", "CP437"); @@ -277,7 +283,12 @@ void s_putchar(char c) { if (sshBBS) { fprintf(stdout, "%s", ptr1); } else { - write(gSocket, ptr1, outbuf - ptr1); + ret = send(gSocket, ptr1, outbuf - ptr1, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } iconv_close(ic); free(ptr1); @@ -294,11 +305,17 @@ void s_putstring(char *c) { size_t sz; char *ptr1; char *ptr2; + int ret; if (!should_convert_utf8()) { if (sshBBS) { fprintf(stdout, "%s", c); } else { - write(gSocket, c, strlen(c)); + ret = send(gSocket, c, strlen(c), MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } } else { ic = iconv_open("UTF-8", "CP437"); @@ -313,7 +330,12 @@ void s_putstring(char *c) { if (sshBBS) { fprintf(stdout, "%s", ptr1); } else { - write(gSocket, ptr1, outbuf - ptr1); + ret = send(gSocket, ptr1, outbuf - ptr1, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } iconv_close(ic); free(ptr1); @@ -395,22 +417,25 @@ char s_getchar() { char iac_binary_do[] = {IAC, IAC_DO, IAC_TRANSMIT_BINARY, '\0'}; char iac_binary_wont[] = {IAC, IAC_WONT, IAC_TRANSMIT_BINARY, '\0'}; char iac_binary_dont[] = {IAC, IAC_DONT, IAC_TRANSMIT_BINARY, '\0'}; - + int ret; do { if (sshBBS) { c = getchar(); } else { - len = read(gSocket, &c, 1); - - if (len == 0) { + do { + len = read(gSocket, &c, 1); + } while (len == -1 && errno == EINTR); + if (len <= 0) { disconnect("Socket Closed"); } } if (!sshBBS) { while (c == IAC) { - len = read(gSocket, &c, 1); + do { + len = read(gSocket, &c, 1); + } while (len == -1 && errno == EINTR); if (len == 0) { disconnect("Socket Closed"); } else if (c == IAC) { @@ -418,8 +443,10 @@ char s_getchar() { return c; } if (c == IAC_WILL || c == IAC_WONT || c == IAC_DO || c == IAC_DONT) { - len = read(gSocket, &d, 1); - if (len == 0) { + do { + len = read(gSocket, &c, 1); + } while (len == -1 && errno == EINTR); + if (len <= 0) { disconnect("Socket Closed"); } @@ -428,7 +455,12 @@ char s_getchar() { if (d == 0) { if (telnet_bin_mode != 1) { telnet_bin_mode = 1; - write(gSocket, iac_binary_do, 3); + ret = send(gSocket, iac_binary_do, 3, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } } break; @@ -436,7 +468,12 @@ char s_getchar() { if (d == 0) { if (telnet_bin_mode != 0) { telnet_bin_mode = 0; - write(gSocket, iac_binary_dont, 3); + ret = send(gSocket, iac_binary_dont, 3, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } } break; @@ -444,7 +481,13 @@ char s_getchar() { if (d == 0) { if (telnet_bin_mode != 1) { telnet_bin_mode = 1; - write(gSocket, iac_binary_will, 3); + ret = send(gSocket, iac_binary_will, 3, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } + } } break; @@ -452,22 +495,31 @@ char s_getchar() { if (d == 0) { if (telnet_bin_mode != 0) { telnet_bin_mode = 0; - write(gSocket, iac_binary_wont, 3); + ret = send(gSocket, iac_binary_wont, 3, MSG_DONTWAIT); + if (ret == -1) { + if (errno == ECONNRESET) { + disconnect("Disconnected"); + } + } } } break; } } else if (c == 250) { do { - len = read(gSocket, &c, 1); - if (len == 0) { + do { + len = read(gSocket, &c, 1); + } while (len == -1 && errno == EINTR); + if (len <= 0) { disconnect("Socket Closed"); } } while(c != 240); } - len = read(gSocket, &c, 1); - if (len == 0) { + do { + len = read(gSocket, &c, 1); + } while (len == -1 && errno == EINTR); + if (len <= 0) { disconnect("Socket Closed"); } } @@ -772,25 +824,27 @@ void runbbs_real(int socket, char *ip, int ssh) { int do_internal_login = 0; int usernotfound; int tries; - + int fno; + atexit(exit_bbs); - ipaddress = ip; + usertimeout = 10; + timeoutpaused = 0; - if (!ssh) { - gUser = NULL; - sshBBS = 0; - if (write(socket, iac_echo, 3) != 3) { - dolog("Failed to send iac_echo"); - exit(0); - } - if (write(socket, iac_sga, 3) != 3) { - dolog("Failed to send iac_sga"); - exit(0); - } - } else { - sshBBS = 1; - } + + memset (&sa, 0, sizeof (sa)); + sa.sa_handler = &timer_handler; + sa.sa_flags = SA_RESTART; + sigaction (SIGALRM, &sa, 0); + + itime.it_interval.tv_sec = 60; + itime.it_interval.tv_usec = 0; + itime.it_value.tv_sec = 60; + itime.it_value.tv_usec = 0; + + setitimer (ITIMER_REAL, &itime, 0); + + ipaddress = ip; st.sa_handler = sigterm_handler2; sigemptyset(&st.sa_mask); @@ -799,26 +853,45 @@ void runbbs_real(int socket, char *ip, int ssh) { dolog("Failed to setup sigterm handler."); exit(1); } - + if (sigaction(SIGPIPE, &st, NULL) == -1) { + dolog("Failed to setup sigpipe handler."); + exit(1); + } gSocket = socket; + + if (!ssh) { + gUser = NULL; + sshBBS = 0; + if (send(socket, iac_echo, 3, MSG_DONTWAIT) != 3) { + dolog("Failed to send iac_echo"); + exit(0); + } + if (send(socket, iac_sga, 3, MSG_DONTWAIT) != 3) { + dolog("Failed to send iac_sga"); + exit(0); + } + } else { + sshBBS = 1; + } + s_printf("Magicka BBS v%d.%d (%s), Loading...\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_STR); // find out which node we are for (i=1;i<=conf.nodes;i++) { sprintf(buffer, "%s/nodeinuse.%d", conf.bbs_path, i); + if (stat(buffer, &s) != 0) { mynode = i; - nodefile = fopen(buffer, "w"); - if (!nodefile) { + fno = open(buffer, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); + if (fno == -1) { dolog("Error opening nodefile!"); - close(socket); - exit(1); + continue; } - fputs("UNKNOWN", nodefile); - fclose(nodefile); - + write(fno, "UNKNOWN", 7); + + close(fno); break; } } @@ -833,23 +906,9 @@ void runbbs_real(int socket, char *ip, int ssh) { dolog("Incoming %s connection on node %d", (ssh ? "SSH" : "Telnet"), mynode); - usertimeout = 10; - timeoutpaused = 0; - tries = 0; - - memset (&sa, 0, sizeof (sa)); - sa.sa_handler = &timer_handler; - sa.sa_flags = SA_RESTART; - sigaction (SIGALRM, &sa, 0); - - itime.it_interval.tv_sec = 60; - itime.it_interval.tv_usec = 0; - itime.it_value.tv_sec = 60; - itime.it_value.tv_usec = 0; - - setitimer (ITIMER_REAL, &itime, 0); - s_displayansi("issue"); + + tries = 0; if (!ssh) { tryagain: @@ -863,8 +922,8 @@ tryagain: if (strcasecmp(buffer, "new") == 0) { usernotfound = 1; } else if (check_user(buffer)) { - usernotfound = 1; s_printf(get_string(203)); + goto tryagain; } if (usernotfound) { diff --git a/src/users.c b/src/users.c index 583b74d..a1e0d7a 100644 --- a/src/users.c +++ b/src/users.c @@ -583,7 +583,7 @@ int check_user(char *loginname) { } struct user_record *new_user() { - char buffer[256]; + char buffer[PATH_MAX]; struct user_record *user; int done = 0; char c; @@ -753,7 +753,7 @@ struct user_record *new_user() { user->sec_level = conf.newuserlvl; user->bwavepktno = 0; user->sec_info = (struct sec_level_t *)malloc(sizeof(struct sec_level_t)); - sprintf(buffer, "%s/config/s%d.ini", conf.bbs_path, user->sec_level); + snprintf(buffer, PATH_MAX, "%s/config/s%d.ini", conf.bbs_path, user->sec_level); if (ini_parse(buffer, secLevel, user->sec_info) <0) { dolog("Unable to load sec Level ini (%s)!", buffer);