aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-01-18 14:59:35 -0500
committerFranklin Wei <git@fwei.tk>2016-01-18 14:59:35 -0500
commit344a56010938c28225c3d145d5191c8fb8234288 (patch)
tree49fe35f68d9f69d917dbd87aa177b5260c286699 /src
parenta8cdc61833ab16dcb0d0d8364710d55759cc0293 (diff)
downloadnetcosm-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.h4
-rw-r--r--src/client.c71
-rw-r--r--src/server_reqs.c8
-rw-r--r--src/telnet.c67
-rw-r--r--src/telnet.h8
-rw-r--r--src/userdb.c4
6 files changed, 83 insertions, 79 deletions
diff --git a/src/auth.h b/src/auth.h
index 578f6d8..b77a711 100644
--- a/src/auth.h
+++ b/src/auth.h
@@ -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;