aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-01-22 17:03:05 -0500
committerFranklin Wei <git@fwei.tk>2016-01-22 17:03:05 -0500
commitb33d9c81c116d43b38ceb8b247bd77f9736574b9 (patch)
treeb92a923ffc29ee438c646f4b2b08f5bd588dee2d /src
parenta486d4b5e1679e0ddf5a4afa661501afefe4a854 (diff)
downloadnetcosm-b33d9c81c116d43b38ceb8b247bd77f9736574b9.zip
netcosm-b33d9c81c116d43b38ceb8b247bd77f9736574b9.tar.gz
netcosm-b33d9c81c116d43b38ceb8b247bd77f9736574b9.tar.bz2
netcosm-b33d9c81c116d43b38ceb8b247bd77f9736574b9.tar.xz
PuTTY compatibility, lots of other stuff
Diffstat (limited to 'src')
-rw-r--r--src/client.c64
-rw-r--r--src/hash.h4
-rw-r--r--src/room.c59
-rw-r--r--src/room.h49
-rw-r--r--src/server.c58
-rw-r--r--src/server_reqs.c33
-rw-r--r--src/server_reqs.h1
-rw-r--r--src/telnet.c106
-rw-r--r--src/telnet.h23
9 files changed, 185 insertions, 212 deletions
diff --git a/src/client.c b/src/client.c
index 2ad7256..0cfb0f9 100644
--- a/src/client.c
+++ b/src/client.c
@@ -72,9 +72,10 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
/* do some line wrapping */
int pos = 0, last_space = 0;
- char newline = '\n';
char *ptr = buf;
- uint16_t line_width = telnet_get_width();
+ uint16_t line_width = telnet_get_width() + 1;
+ char *line_buf = malloc(line_width + 2);
+ size_t line_idx = 0;
while(ptr[pos])
{
bool is_newline = (ptr[pos] == '\n');
@@ -82,12 +83,21 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
{
if(is_newline || !last_space)
last_space = pos;
+
while(*ptr && last_space-- > 0)
- out_raw(ptr++, 1);
- out_raw(&newline, 1);
+ {
+ line_buf[line_idx++] = *ptr++;
+ }
+
+ line_buf[line_idx++] = '\r';
+ line_buf[line_idx++] = '\n';
+
+ out_raw(line_buf, line_idx);
+ line_idx = 0;
+
if(is_newline)
- ++ptr; /* skip newline */
- while(*ptr && *ptr == ' ')
+ ++ptr; /* skip the newline */
+ while(*ptr == ' ')
++ptr;
last_space = 0;
pos = 0;
@@ -100,6 +110,7 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
}
}
out_raw(ptr, strlen(ptr));
+ free(line_buf);
}
static volatile sig_atomic_t request_complete;
@@ -155,6 +166,8 @@ void send_master(unsigned char cmd, const void *data, size_t sz)
while(!request_complete) poll_requests();
free(req);
+
+ debugf("done with request\n");
}
#define BUFSZ 128
@@ -162,10 +175,12 @@ void send_master(unsigned char cmd, const void *data, size_t sz)
char *client_read(void)
{
char *buf;
-
+ size_t bufidx;
tryagain:
buf = malloc(BUFSZ);
+ bufidx = 0;
+
memset(buf, 0, BUFSZ);
/* set of the client fd and the pipe from our parent */
@@ -193,20 +208,27 @@ tryagain:
}
else if(fds[i].fd == client_fd)
{
- ssize_t len = read(client_fd, buf, BUFSZ - 1);
+ ssize_t len = read(client_fd, buf + bufidx, BUFSZ - bufidx - 1);
if(len < 0)
error("lost connection");
buf[BUFSZ - 1] = '\0';
- enum telnet_status ret = telnet_parse_data((unsigned char*)buf, len);
+ enum telnet_status ret = telnet_parse_data((unsigned char*)buf + bufidx, len);
- if(ret != TELNET_DATA)
+ switch(ret)
{
+ case TELNET_EXIT:
+ case TELNET_FOUNDCMD:
free(buf);
if(ret == TELNET_EXIT)
exit(0);
goto tryagain;
+ case TELNET_DATA:
+ bufidx += len;
+ continue;
+ case TELNET_LINEOVER:
+ break;
}
remove_cruft(buf);
@@ -268,6 +290,8 @@ bool poll_requests(void)
unsigned char cmd = packet[0];
+ debugf("Child gets code %d\n", cmd);
+
switch(cmd)
{
case REQ_BCASTMSG:
@@ -348,6 +372,8 @@ void client_change_room(room_id id)
send_master(REQ_SETROOM, &id, sizeof(id));
}
+void *dir_map = NULL;
+
void client_move(const char *dir)
{
const struct dir_pair {
@@ -377,14 +403,13 @@ void client_move(const char *dir)
{ "IN", DIR_IN },
{ "OUT", DIR_OT },
};
- static void *map = NULL;
- if(!map)
+ if(!dir_map)
{
- map = hash_init(ARRAYLEN(dirs), hash_djb, compare_strings);
- hash_insert_pairs(map, (struct hash_pair*)dirs, sizeof(struct dir_pair), ARRAYLEN(dirs));
+ dir_map = hash_init(ARRAYLEN(dirs), hash_djb, compare_strings);
+ hash_insert_pairs(dir_map, (struct hash_pair*)dirs, sizeof(struct dir_pair), ARRAYLEN(dirs));
}
- struct dir_pair *pair = hash_lookup(map, dir);
+ struct dir_pair *pair = hash_lookup(dir_map, dir);
if(pair)
{
send_master(REQ_MOVE, &pair->val, sizeof(pair->val));
@@ -416,6 +441,8 @@ void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from)
debugf("New client %s\n", ip);
debugf("Total clients: %d\n", total);
+ debugf("client is running with uid %d\n", getuid());
+
auth:
out("NetCosm " NETCOSM_VERSION "\n");
@@ -601,8 +628,15 @@ auth:
else if(!strcmp(what, "KICK"))
{
char *pid_s = strtok_r(NULL, WSPACE, &save);
+ all_upper(pid_s);
if(pid_s)
{
+ if(!strcmp(pid_s, "ALL"))
+ {
+ const char *msg = "Kicking everyone...\n";
+ send_master(REQ_KICKALL, msg, strlen(msg));
+ goto next_cmd;
+ }
/* weird pointer voodoo */
/* TODO: simplify */
char pidbuf[MAX(sizeof(pid_t), MSG_MAX)];
diff --git a/src/hash.h b/src/hash.h
index e7fbe00..21da10a 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -41,8 +41,8 @@ void hash_setfreekey_cb(void*, void (*cb)(void *key));
void hash_free(void*);
/*
- * insert a pair, returns NULL if not already found, otherwise returns
- * the existing data pointer
+ * insert a pair, returns NULL if NOT already found, otherwise returns
+ * the existing data pointer without inserting the new pair
*/
void *hash_insert(void*, const void *key, const void *data);
diff --git a/src/room.c b/src/room.c
index e0be4fd..7596dc4 100644
--- a/src/room.c
+++ b/src/room.c
@@ -21,8 +21,10 @@
#include "hash.h"
#include "server.h"
#include "room.h"
+#include "userdb.h"
/* processed world data */
+
static struct room_t *world;
static size_t world_sz;
static char *world_name;
@@ -40,51 +42,17 @@ bool room_user_add(room_id id, struct child_data *child)
if(!room)
error("unknown room %d", id);
- struct user_t *iter = room->users, *last = NULL;
- while(iter)
- {
- if(iter->data->pid == child->pid)
- return false;
- last = iter;
- iter = iter->next;
- }
-
- struct user_t *new = calloc(sizeof(struct user_t), 1);
-
- new->data = child;
- new->next = NULL;
-
- if(last)
- last->next = new;
+ if(hash_insert(room->users, &child->pid, child))
+ return false;
else
- room->users = new;
-
- ++room->num_users;
-
- return true;
+ return true;
}
bool room_user_del(room_id id, struct child_data *child)
{
struct room_t *room = room_get(id);
- struct user_t *iter = room->users, *last = NULL;
- while(iter)
- {
- if(iter->data->pid == child->pid)
- {
- if(last)
- last->next = iter->next;
- else
- room->users = iter->next;
- free(iter);
- --room->num_users;
- return true;
- }
- last = iter;
- iter = iter->next;
- }
- return false;
+ return hash_remove(room->users, &child->pid);
}
void write_roomid(int fd, room_id *id)
@@ -143,12 +111,8 @@ void world_save(const char *fname)
static void room_free(struct room_t *room)
{
- while(room->users)
- {
- struct user_t *old = room->users;
- room->users = room->users->next;
- free(old);
- }
+ hash_free(room->users);
+ room->users = NULL;
free(room->data.name);
free(room->data.desc);
}
@@ -168,6 +132,9 @@ void world_free(void)
}
}
+static SIMP_HASH(pid_t, pid_hash);
+static SIMP_EQUAL(pid_t, pid_equal);
+
/**
* Loads a world using data on disk and in memory.
*
@@ -205,6 +172,8 @@ bool world_load(const char *fname, const struct roomdata_t *data, size_t data_sz
for(unsigned i = 0; i < world_sz; ++i)
{
+ world[i].users = hash_init((userdb_size() + 1) / 2, pid_hash, pid_equal);
+
world[i].id = read_roomid(fd);
memcpy(&world[i].data, data + i, sizeof(struct roomdata_t));
world[i].data.name = read_string(fd);
@@ -255,6 +224,8 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name)
}
}
+ world[i].users = hash_init((userdb_size() + 1) / 2, pid_hash, pid_equal);
+
world_sz = i + 1;
}
diff --git a/src/room.h b/src/room.h
index 68ee413..c973b6a 100644
--- a/src/room.h
+++ b/src/room.h
@@ -18,16 +18,18 @@
#pragma once
+/* Our world is an array of rooms, each having a list of objects in
+ them, as well as actions that can be performed in the room. Objects
+ are added by hooks in rooms, which are provided by the world
+ module. */
+
typedef enum room_id { ROOM_NONE = -1 } room_id;
typedef unsigned __int128 obj_id;
-enum direction_t { DIR_N = 0, DIR_NE, DIR_E, DIR_SE, DIR_S, DIR_SW, DIR_W, DIR_NW, DIR_UP, DIR_DN, DIR_IN, DIR_OT, NUM_DIRECTIONS };
+typedef struct child_data user_t;
-struct user_t {
- struct child_data *data;
- struct user_t *next;
-};
+enum direction_t { DIR_N = 0, DIR_NE, DIR_E, DIR_SE, DIR_S, DIR_SW, DIR_W, DIR_NW, DIR_UP, DIR_DN, DIR_IN, DIR_OT, NUM_DIRECTIONS };
/* the data we get from a world module */
struct roomdata_t {
@@ -41,30 +43,33 @@ struct roomdata_t {
const char * const adjacent[NUM_DIRECTIONS];
void (* const hook_init)(room_id id);
- void (* const hook_enter)(room_id room, struct user_t *user);
- void (* const hook_leave)(room_id room, struct user_t *user);
+ void (* const hook_enter)(room_id room, user_t *user);
+ void (* const hook_leave)(room_id room, user_t *user);
};
struct object_t {
obj_id id;
- const char *class;
+
const char *name; /* no articles: "a", "an", "the" */
- bool proper; /* whether to use "the" in describing this object */
void *userdata;
+ bool can_take;
+ bool list;
+
void (*hook_serialize)(int fd, struct object_t*);
- void (*hook_take)(struct object_t*, struct user_t *user);
- void (*hook_drop)(struct object_t*, struct user_t *user);
- void (*hook_use)(struct object_t*, struct user_t *user);
+ void (*hook_take)(struct object_t*, user_t *user);
+ void (*hook_drop)(struct object_t*, user_t *user);
+ void (*hook_use)(struct object_t*, user_t *user);
void (*hook_destroy)(struct object_t*);
+ char* (*hook_desc)(struct object_t*, user_t*);
};
struct verb_t {
const char *name;
/* toks is strtok_r's pointer */
- void (*execute)(const char *toks, struct user_t *user);
+ void (*execute)(const char *toks, user_t *user);
};
struct room_t {
@@ -73,16 +78,10 @@ struct room_t {
room_id adjacent[NUM_DIRECTIONS];
- /* arrays instead of linked lists because insertion should be rare for these */
- size_t objects_sz;
- struct object_t *objects;
-
- size_t verbs_sz;
- struct verb_t *verbs;
-
- /* linked list for users, random access is rare */
- struct user_t *users;
- int num_users;
+ /* hash maps */
+ void *objects;
+ void *verbs;
+ void *users; /* PID -> user_t */
};
/* room/world */
@@ -94,6 +93,10 @@ struct room_t *room_get(room_id id);
bool room_user_add(room_id id, struct child_data *child);
bool room_user_del(room_id id, struct child_data *child);
+/* returns a new object */
struct object_t *obj_new(void);
+/* new should point to a statically allocated object */
+void obj_add(room_id room, struct object_t *new);
+
void world_free(void);
diff --git a/src/server.c b/src/server.c
index 4430f7e..6ce4de4 100644
--- a/src/server.c
+++ b/src/server.c
@@ -103,28 +103,10 @@ static void handle_client(int fd, struct sockaddr_in *addr,
static void __attribute__((noreturn)) serv_cleanup(void)
{
- debugf("Shutdown server.\n");
-
- /* kill all our children (usually init claims them and wait()'s
- for them, but not always) */
- if(child_map)
- {
- struct sigaction sa;
- sigfillset(&sa.sa_mask);
- sigaddset(&sa.sa_mask, SIGCHLD);
- sa.sa_handler = SIG_IGN;
- sa.sa_flags = 0;
- sigaction(SIGCHLD, &sa, NULL); /* kill all children */
- void *ptr = child_map, *save;
- do {
- struct child_data *child = hash_iterate(ptr, &save, NULL);
- if(!child)
- break;
- ptr = NULL;
- kill(child->pid, SIGKILL);
- } while(1);
- handle_disconnects();
- }
+ if(!are_child)
+ debugf("Shutdown server.\n");
+ else
+ debugf("Shutdown worker.\n");
if(shutdown(server_socket, SHUT_RDWR) > 0)
error("shutdown");
@@ -136,6 +118,10 @@ static void __attribute__((noreturn)) serv_cleanup(void)
hash_free(child_map);
child_map = NULL;
+ extern void *dir_map;
+ hash_free(dir_map);
+ dir_map = NULL;
+
userdb_shutdown();
extern char *current_user;
@@ -150,7 +136,7 @@ static void __attribute__((noreturn)) serv_cleanup(void)
static void __attribute__((noreturn)) sigint_handler(int s)
{
(void) s;
- serv_cleanup();
+ exit(0);
}
static void check_userfile(void)
@@ -208,9 +194,6 @@ static int server_bind(void)
return sock;
}
-static SIMP_HASH(pid_t, pid_hash);
-static SIMP_EQUAL(pid_t, pid_equal);
-
static void childreq_cb(EV_P_ ev_io *w, int revents)
{
(void) EV_A;
@@ -337,6 +320,9 @@ static void init_signals(void)
error("sigaction");
}
+static SIMP_HASH(pid_t, pid_hash);
+static SIMP_EQUAL(pid_t, pid_equal);
+
int server_main(int argc, char *argv[])
{
debugf("*** Starting NetCosm %s (libev %d.%d, %s) ***\n",
@@ -353,6 +339,7 @@ int server_main(int argc, char *argv[])
srand(time(0));
server_socket = server_bind();
+
userdb_init(USERFILE);
check_userfile();
@@ -374,28 +361,13 @@ int server_main(int argc, char *argv[])
* because libev grabs SIGCHLD */
init_signals();
- /* drop root privileges */
- if(getuid() == 0)
- {
- struct passwd *nobody = getpwnam("nobody");
- if(!nobody)
- error("couldn't get unprivileged user");
- if(setgid(nobody->pw_gid) != 0)
- error("setgid");
- if(setuid(nobody->pw_uid) != 0)
- error("setuid");
- if(setuid(0) >= 0)
- error("failed to drop root");
- if(access(USERFILE, R_OK) >= 0)
- error("failed to drop root");
- debugf("Dropped root privileges.\n");
- }
-
ev_io server_watcher;
ev_io_init(&server_watcher, new_connection_cb, server_socket, EV_READ);
ev_set_priority(&server_watcher, EV_MAXPRI);
ev_io_start(EV_A_ &server_watcher);
+ atexit(serv_cleanup);
+
ev_loop(loop, 0);
/* should never get here */
diff --git a/src/server_reqs.c b/src/server_reqs.c
index c7e9f09..bf661b9 100644
--- a/src/server_reqs.c
+++ b/src/server_reqs.c
@@ -30,7 +30,13 @@ static void send_packet(struct child_data *child, unsigned char cmd,
pkt[0] = cmd;
if(datalen)
memcpy(pkt + 1, data, datalen);
- write(child->outpipe[1], pkt, datalen + 1);
+tryagain:
+ if(write(child->outpipe[1], pkt, datalen + 1) < 0)
+ {
+ /* write can fail, so we try again */
+ if(errno == EAGAIN)
+ goto tryagain;
+ }
}
static void req_pass_msg(unsigned char *data, size_t datalen,
@@ -217,6 +223,13 @@ static void req_send_geninfo(unsigned char *data, size_t datalen, struct child_d
send_packet(sender, REQ_BCASTMSG, buf, len);
}
+static void req_kick_always(unsigned char *data, size_t datalen,
+ struct child_data *sender, struct child_data *child)
+{
+ (void) sender;
+ send_packet(child, REQ_KICK, data, datalen);
+}
+
static const struct child_request {
unsigned char code;
@@ -245,6 +258,7 @@ static const struct child_request {
{ REQ_GETUSERDATA, true, CHILD_NONE, NULL, req_send_user, },
{ REQ_DELUSERDATA, true, CHILD_NONE, NULL, req_del_user, },
{ REQ_ADDUSERDATA, true, CHILD_NONE, NULL, req_add_user, },
+ { REQ_KICKALL, true, CHILD_ALL_BUT_SENDER, req_kick_always, NULL },
//{ REQ_ROOMMSG, true, CHILD_ALL, req_send_room_msg, NULL, },
};
@@ -289,6 +303,8 @@ bool handle_child_req(int in_fd)
ssize_t packet_len = read(in_fd, packet, MSG_MAX);
+ struct child_data *sender = NULL;
+
if(packet_len <= 0)
goto fail;
@@ -296,7 +312,7 @@ bool handle_child_req(int in_fd)
memcpy(&sender_pid, packet, sizeof(pid_t));
debugf("servreq: Got request from PID %d\n", sender_pid);
- struct child_data *sender = hash_lookup(child_map, &sender_pid);
+ sender = hash_lookup(child_map, &sender_pid);
if(!sender)
{
@@ -343,6 +359,8 @@ bool handle_child_req(int in_fd)
if(child->pid == sender->pid)
continue;
+ debugf("iterating over child %d\n", child->pid);
+
switch(req->which)
{
case CHILD_ALL:
@@ -356,12 +374,19 @@ bool handle_child_req(int in_fd)
finish:
+ debugf("finalizing request\n");
+
if(req && req->finalize)
req->finalize(data, datalen, sender);
- if(req)
+ /* fall through */
+fail:
+ if(sender)
+ {
send_packet(sender, REQ_ALLDONE, NULL, 0);
-fail:
+ debugf("sending all done code\n");
+ }
+
return true;
}
diff --git a/src/server_reqs.h b/src/server_reqs.h
index 06e3f46..6ab093b 100644
--- a/src/server_reqs.h
+++ b/src/server_reqs.h
@@ -37,6 +37,7 @@
#define REQ_ADDUSERDATA 15 /* server: insert user data; child: success/fail */
#define REQ_PRINTNEWLINE 16 /* child: print a newline */
#define REQ_ALLDONE 17 /* child: break out of send_master() */
+#define REQ_KICKALL 18 /* server: kick everyone except the sender */
/* child states, sent as an int to the master */
#define STATE_INIT 0 /* initial state */
diff --git a/src/telnet.c b/src/telnet.c
index c605c2e..9963007 100644
--- a/src/telnet.c
+++ b/src/telnet.c
@@ -19,6 +19,8 @@
#include "globals.h"
#include "client.h"
+
+#define TELCMDS
#include "telnet.h"
static uint16_t term_width, term_height;
@@ -38,6 +40,7 @@ enum telnet_status telnet_parse_data(const unsigned char *buf, size_t buflen)
bool iac = false;
bool found_cmd = false;
bool in_sb = false;
+ bool line_done = false;
debugf("telnet: ");
@@ -45,67 +48,50 @@ enum telnet_status telnet_parse_data(const unsigned char *buf, size_t buflen)
{
unsigned char c = buf[i];
- const struct telnet_cmd {
- int val;
- const char *name;
- } commands[] = {
- { IAC, "IAC" },
- { DONT, "DONT" },
- { DO, "DO" },
- { WONT, "WONT" },
- { WILL, "WILL" },
- { GA, "GA" },
- { AYT, "AYT" },
- { NOP, "NOP" },
- { SB, "SB" },
- { SE, "SE" },
- { ECHO, "ECHO" },
- { SGA, "SGA" },
- { STATUS, "STATUS" },
- { NAWS, "NAWS" },
- { IP, "IP" },
- };
-
if(c == IAC)
iac = true;
+ else if(c == '\n' || c == '\r')
+ {
+ debugf("found newline, done reading.\n");
+ line_done = true;
+ }
if(iac)
{
- for(unsigned int cmd_idx = 0; cmd_idx < ARRAYLEN(commands); ++cmd_idx)
+ if(TELCMD_OK(c))
{
- if(c == commands[cmd_idx].val)
+ debugf("%s ", TELCMD(c));
+ found_cmd = true;
+ switch(c)
{
- debugf("%s ", commands[cmd_idx].name);
- found_cmd = true;
- switch(c)
+ case IP:
+ return TELNET_EXIT;
+ case SB:
+ in_sb = true;
+ break;
+ case TELOPT_NAWS:
+ if(in_sb)
{
- case IP:
- return TELNET_EXIT;
- case SB:
- in_sb = true;
- break;
- case NAWS:
- if(in_sb)
+ /* read height/width */
+ uint8_t bytes[4];
+ int j = 0;
+ while(j < 4 && i < buflen)
{
- /* read height/width */
- uint8_t bytes[4];
- int j = 0;
- while(j < 4 && i < buflen)
+ bytes[j++] = buf[++i];
+ debugf("%d ", buf[j - 1]);
+ if(bytes[j - 1] == 255) /* 255 is doubled to distinguish from IAC */
{
- bytes[j++] = buf[++i];
- debugf("%d ", buf[j - 1]);
- if(bytes[j - 1] == 255) /* 255 is doubled to distinguish from IAC */
- {
- ++i;
- }
+ ++i;
}
- term_width = ntohs(*((uint16_t*)bytes));
- term_height = ntohs(*((uint16_t*)(bytes+2)));
}
- break;
+ if(i >= buflen && j != 4)
+ error("client SB NAWS command to short");
+ term_width = ntohs(*((uint16_t*)bytes));
+ term_height = ntohs(*((uint16_t*)(bytes+2)));
}
- goto got_cmd;
+ break;
}
+ goto got_cmd;
}
}
debugf("%d ", c);
@@ -114,15 +100,17 @@ enum telnet_status telnet_parse_data(const unsigned char *buf, size_t buflen)
}
debugf("\n");
+ if(found_cmd)
+ debugf("telnet: is NOT data\n");
- return found_cmd ? TELNET_FOUNDCMD : TELNET_DATA;
+ return found_cmd ? TELNET_FOUNDCMD :
+ (line_done ? TELNET_LINEOVER : TELNET_DATA);
}
void telnet_echo_off(void)
{
const unsigned char seq[] = {
- IAC, DONT, ECHO,
- IAC, WILL, ECHO,
+ IAC, WILL, TELOPT_ECHO,
};
out_raw(seq, ARRAYLEN(seq));
}
@@ -130,8 +118,7 @@ void telnet_echo_off(void)
void telnet_echo_on(void)
{
const unsigned char seq[] = {
- IAC, DO, ECHO,
- IAC, WONT, ECHO,
+ IAC, WONT, TELOPT_ECHO,
};
out_raw(seq, ARRAYLEN(seq));
}
@@ -139,18 +126,17 @@ void telnet_echo_on(void)
void telnet_init(void)
{
const unsigned char init_seq[] = {
- IAC, WONT, SGA,
- IAC, DONT, SGA,
+ IAC, WONT, TELOPT_SGA,
+ IAC, DONT, TELOPT_SGA,
- IAC, DO, NAWS,
+ IAC, DO, TELOPT_NAWS,
- IAC, WONT, STATUS,
- IAC, DONT, STATUS,
+ IAC, WONT, TELOPT_STATUS,
+ IAC, DONT, TELOPT_STATUS,
- IAC, DO, ECHO,
- IAC, WONT, ECHO,
+ IAC, DO, TELOPT_ECHO,
- IAC, DONT, LINEMODE,
+ IAC, DONT, TELOPT_LINEMODE,
};
term_width = 80;
term_height = 24;
diff --git a/src/telnet.h b/src/telnet.h
index 2289e84..8669e87 100644
--- a/src/telnet.h
+++ b/src/telnet.h
@@ -18,32 +18,13 @@
#pragma once
-/* commands */
-#define IAC 255
-#define DONT 254
-#define DO 253
-#define WONT 252
-#define WILL 251
-#define SB 250
-#define GA 249
-#define EL 248
-#define EC 247
-#define AYT 246
-#define IP 244
-#define NOP 241
-#define SE 240
-
-/* options */
-#define ECHO 1
-#define SGA 3
-#define STATUS 5
-#define NAWS 31
-#define LINEMODE 34
+#include <arpa/telnet.h>
void telnet_init(void);
enum telnet_status { TELNET_DATA = 0,
TELNET_FOUNDCMD,
+ TELNET_LINEOVER,
TELNET_EXIT };
enum telnet_status telnet_parse_data(const unsigned char*, size_t);