diff options
| author | Franklin Wei <git@fwei.tk> | 2016-01-18 14:59:35 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2016-01-18 14:59:35 -0500 |
| commit | 344a56010938c28225c3d145d5191c8fb8234288 (patch) | |
| tree | 49fe35f68d9f69d917dbd87aa177b5260c286699 /src | |
| parent | a8cdc61833ab16dcb0d0d8364710d55759cc0293 (diff) | |
| download | netcosm-344a56010938c28225c3d145d5191c8fb8234288.zip netcosm-344a56010938c28225c3d145d5191c8fb8234288.tar.gz netcosm-344a56010938c28225c3d145d5191c8fb8234288.tar.bz2 netcosm-344a56010938c28225c3d145d5191c8fb8234288.tar.xz | |
fix a synchronization bug, better word wrapping, and pretty telnet
Diffstat (limited to 'src')
| -rw-r--r-- | src/auth.h | 4 | ||||
| -rw-r--r-- | src/client.c | 71 | ||||
| -rw-r--r-- | src/server_reqs.c | 8 | ||||
| -rw-r--r-- | src/telnet.c | 67 | ||||
| -rw-r--r-- | src/telnet.h | 8 | ||||
| -rw-r--r-- | src/userdb.c | 4 |
6 files changed, 83 insertions, 79 deletions
@@ -23,8 +23,8 @@ #define SALT_LEN 12 #define ALGO GCRY_MD_SHA512 #define AUTH_HASHLEN (512/8) -//#define HASH_ITERS 500000 -#define HASH_ITERS 1 +#define HASH_ITERS 500000 +//#define HASH_ITERS 1 struct authinfo_t { bool success; diff --git a/src/client.c b/src/client.c index 0482b4b..3d77ddf 100644 --- a/src/client.c +++ b/src/client.c @@ -58,53 +58,48 @@ try_again: goto try_again; } -#define WRAP_COLS 80 - void __attribute__((format(printf,1,2))) out(const char *fmt, ...) { char buf[1024]; memset(buf, 0, sizeof(buf)); va_list ap; va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); /* do some line wrapping */ - int x = 0; - - char word_buf[sizeof(buf)], *ptr = buf; - + int pos = 0, last_space = 0; char newline = '\n'; - - int word_idx = 0; - while(1) + char *ptr = buf; + uint16_t line_width = telnet_get_width(); + while(ptr[pos]) { - char c = *ptr++; - if(!c) - break; - word_buf[word_idx++] = c; - x++; - if(c == ' ' || c == '\n') + bool is_newline = (ptr[pos] == '\n'); + if(is_newline || pos >= line_width) { - if(x >= WRAP_COLS - 1) - { - sig_debugf("Wrapping...\n"); - out_raw(&newline, 1); - x = 0; - } - out_raw(word_buf, word_idx); - word_idx = 0; + if(is_newline || !last_space) + last_space = pos; + while(*ptr && last_space-- > 0) + out_raw(ptr++, 1); + out_raw(&newline, 1); + if(is_newline) + ++ptr; /* skip newline */ + while(*ptr && *ptr == ' ') + ++ptr; + last_space = 0; + pos = 0; + } + else + { + if(ptr[pos] == ' ') + last_space = pos; + ++pos; } } - - if(x >= WRAP_COLS - 1) - { - sig_debugf("Wrapping...\n"); - out_raw(&newline, 1); - x = 0; - } - out_raw(word_buf, word_idx); + out_raw(ptr, strlen(ptr)); } static volatile sig_atomic_t request_complete; @@ -157,7 +152,7 @@ void send_master(unsigned char cmd, const void *data, size_t sz) poll(&pfd, 1, -1); - while(poll_requests()); + while(!request_complete) poll_requests(); free(req); } @@ -198,14 +193,16 @@ tryagain: } else if(fds[i].fd == client_fd) { - if(read(client_fd, buf, BUFSZ - 1) < 0) + ssize_t len = read(client_fd, buf, BUFSZ - 1); + if(len < 0) error("lost connection"); buf[BUFSZ - 1] = '\0'; - if(buf[0] & 0x80) - { - int ret = telnet_handle_command((unsigned char*)buf); + enum telnet_status ret = telnet_parse_data((unsigned char*)buf, len); + + if(ret != TELNET_DATA) + { free(buf); if(ret == TELNET_EXIT) exit(0); @@ -485,7 +482,7 @@ auth: client_change_state(STATE_LOGGEDIN); /* authenticated */ - debugf("Authenticated as %s\n", current_user); + debugf("client: Authenticated as %s\n", current_user); client_change_user(current_user); current_room = 0; client_change_room(current_room); diff --git a/src/server_reqs.c b/src/server_reqs.c index d461147..6a63d1e 100644 --- a/src/server_reqs.c +++ b/src/server_reqs.c @@ -294,7 +294,7 @@ bool handle_child_req(int in_fd) pid_t sender_pid; memcpy(&sender_pid, packet, sizeof(pid_t)); - sig_debugf("Got request from PID %d\n", sender_pid); + debugf("servreq: Got request from PID %d\n", sender_pid); struct child_data *sender = hash_lookup(child_map, &sender_pid); @@ -356,12 +356,12 @@ bool handle_child_req(int in_fd) finish: - if(req) - send_packet(sender, REQ_ALLDONE, NULL, 0); - if(req && req->finalize) req->finalize(data, datalen, sender); + if(req) + send_packet(sender, REQ_ALLDONE, NULL, 0); + fail: return true; } diff --git a/src/telnet.c b/src/telnet.c index 0558dfd..c605c2e 100644 --- a/src/telnet.c +++ b/src/telnet.c @@ -33,11 +33,14 @@ uint16_t telnet_get_height(void) return term_height; } -int telnet_handle_command(const unsigned char *buf, size_t buflen) +enum telnet_status telnet_parse_data(const unsigned char *buf, size_t buflen) { + bool iac = false; bool found_cmd = false; bool in_sb = false; + debugf("telnet: "); + for(unsigned i = 0; i < buflen; ++i) { unsigned char c = buf[i]; @@ -63,52 +66,56 @@ int telnet_handle_command(const unsigned char *buf, size_t buflen) { IP, "IP" }, }; - for(unsigned int cmd_idx = 0; cmd_idx < ARRAYLEN(commands); ++cmd_idx) + if(c == IAC) + iac = true; + + if(iac) { - if(c == commands[cmd_idx].val) + for(unsigned int cmd_idx = 0; cmd_idx < ARRAYLEN(commands); ++cmd_idx) { - debugf("%s ", commands[cmd_idx].name); - found_cmd = true; - switch(c) + if(c == commands[cmd_idx].val) { - case IP: - return TELNET_EXIT; - case SB: - in_sb = true; - break; - case NAWS: - if(in_sb) + debugf("%s ", commands[cmd_idx].name); + found_cmd = true; + switch(c) { - /* read height/width */ - uint8_t bytes[4]; - int j = 0; - while(j < 4 && i < buflen) + case IP: + return TELNET_EXIT; + case SB: + in_sb = true; + break; + case NAWS: + if(in_sb) { - bytes[j++] = buf[++i]; - sig_debugf("read byte %d %d\n", buf[i], j); - if(bytes[j - 1] == 255) /* 255 is doubled */ + /* read height/width */ + uint8_t bytes[4]; + int j = 0; + while(j < 4 && i < buflen) { - ++i; + bytes[j++] = buf[++i]; + debugf("%d ", buf[j - 1]); + if(bytes[j - 1] == 255) /* 255 is doubled to distinguish from IAC */ + { + ++i; + } } + term_width = ntohs(*((uint16_t*)bytes)); + term_height = ntohs(*((uint16_t*)(bytes+2))); } - term_width = ntohs(*((uint16_t*)bytes)); - term_height = ntohs(*((uint16_t*)(bytes+2))); - sig_debugf("term size: %dx%d\n", term_width, term_height); + break; } - break; + goto got_cmd; } - goto got_cmd; } } - debugf("???: %d ", c); + debugf("%d ", c); got_cmd: ; } - if(found_cmd) - debugf("\n"); + debugf("\n"); - return TELNET_OK; + return found_cmd ? TELNET_FOUNDCMD : TELNET_DATA; } void telnet_echo_off(void) diff --git a/src/telnet.h b/src/telnet.h index 854828e..2289e84 100644 --- a/src/telnet.h +++ b/src/telnet.h @@ -42,11 +42,11 @@ void telnet_init(void); -#define TELNET_OK 0 -#define TELNET_EXIT 1 +enum telnet_status { TELNET_DATA = 0, + TELNET_FOUNDCMD, + TELNET_EXIT }; -/* returns either TELNET_OK or TELNET_EXIT */ -int telnet_handle_command(const unsigned char*, size_t); +enum telnet_status telnet_parse_data(const unsigned char*, size_t); uint16_t telnet_get_width(void); uint16_t telnet_get_height(void); diff --git a/src/userdb.c b/src/userdb.c index 79ba1f2..32e43b8 100644 --- a/src/userdb.c +++ b/src/userdb.c @@ -108,12 +108,12 @@ bool userdb_remove(const char *key) return false; } -/* should never fail, but returns NULL if something weird happens */ +/* should never fail, but could return NULL if something really weird + * happens */ struct userdata_t *userdb_add(struct userdata_t *data) { struct userdata_t *new = calloc(1, sizeof(*new)); /* only in C! */ memcpy(new, data, sizeof(*new)); - strncpy(new->username, data->username, sizeof(new->username)); struct userdata_t *ret; |