diff options
| author | Franklin Wei <git@fwei.tk> | 2016-02-16 21:17:46 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2016-02-16 21:17:46 -0500 |
| commit | 02de31c48c021742c6245b711790f6d853866c36 (patch) | |
| tree | d145f3ce9156de42064f8bceb3d0eb4362e3bb5a /src/client.c | |
| parent | 8c58ee885941af4c944995b029363f139b8f54bd (diff) | |
| download | netcosm-02de31c48c021742c6245b711790f6d853866c36.zip netcosm-02de31c48c021742c6245b711790f6d853866c36.tar.gz netcosm-02de31c48c021742c6245b711790f6d853866c36.tar.bz2 netcosm-02de31c48c021742c6245b711790f6d853866c36.tar.xz | |
refactor client_ module
Diffstat (limited to 'src/client.c')
| -rw-r--r-- | src/client.c | 275 |
1 files changed, 6 insertions, 269 deletions
diff --git a/src/client.c b/src/client.c index a90dc4b..7ed0df5 100644 --- a/src/client.c +++ b/src/client.c @@ -26,9 +26,9 @@ #include "telnet.h" #include "util.h" -static bool admin = false; +bool are_admin = false; -static int client_fd, to_parent, from_parent; +int client_fd, to_parent, from_parent; static room_id current_room = 0; @@ -114,63 +114,6 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...) free(line_buf); } -static volatile sig_atomic_t request_complete; - -/* for rate-limiting */ -static int reqs_since_ts; -static time_t ts = 0; - -void send_master(unsigned char cmd, const void *data, size_t sz) -{ - if(!admin) - { - time_t t = time(NULL); - if(ts != t) - { - ts = t; - reqs_since_ts = 0; - } - if(reqs_since_ts++ > 10) - { - out("Rate limit exceeded.\n"); - return; - } - } - - request_complete = 0; - - pid_t our_pid = getpid(); - - if(!data) - sz = 0; - - /* format of child->parent packets: - * | PID | CMD | DATA | - */ - - /* pack it all into one write so it's atomic */ - char *req = malloc(sizeof(pid_t) + 1 + sz); - - memcpy(req, &our_pid, sizeof(pid_t)); - memcpy(req + sizeof(pid_t), &cmd, 1); - if(data) - memcpy(req + sizeof(pid_t) + 1, data, sz); - - assert(1 + sizeof(pid_t) + sz <= MSG_MAX); - write(to_parent, req, 1 + sizeof(pid_t) + sz); - - /* poll till we get data */ - struct pollfd pfd; - pfd.fd = from_parent; - pfd.events = POLLIN; - - poll(&pfd, 1, -1); - - while(!request_complete) poll_requests(); - - free(req); -} - #define CLIENT_READ_SZ 128 char *client_read(void) @@ -249,211 +192,6 @@ char *client_read_password(void) return ret; } -enum reqdata_typespec reqdata_type = TYPE_NONE; -union reqdata_t returned_reqdata; - -bool poll_requests(void) -{ - if(!are_child) - return false; - - bool got_cmd = false; - - while(1) - { - unsigned char packet[MSG_MAX + 1]; - memset(packet, 0, sizeof(packet)); - - ssize_t packetlen = read(from_parent, packet, MSG_MAX); - - unsigned char *data = packet + 1; - size_t datalen = packetlen - 1; - packet[MSG_MAX] = '\0'; - - /* no data yet */ - if(packetlen < 0) - goto fail; - - /* parent closed pipe */ - if(!packetlen) - { - debugf("master process died\n"); - exit(0); - } - - got_cmd = true; - - unsigned char cmd = packet[0]; - - switch(cmd) - { - case REQ_BCASTMSG: - { - out((char*)data, datalen); - break; - } - case REQ_KICK: - - { - out((char*)data, datalen); - exit(EXIT_SUCCESS); - } - case REQ_MOVE: - { - int status = *((int*)data); - - reqdata_type = TYPE_BOOLEAN; - returned_reqdata.boolean = status; - if(!status) - out("You cannot go that way.\n"); - break; - } - case REQ_GETUSERDATA: - { - if(datalen == sizeof(struct userdata_t)) - reqdata_type = TYPE_USERDATA; - else - break; - - struct userdata_t *user = &returned_reqdata.userdata; - *user = *((struct userdata_t*)data); - break; - } - case REQ_DELUSERDATA: - { - reqdata_type = TYPE_BOOLEAN; - returned_reqdata.boolean = *((bool*)data); - break; - } - case REQ_ADDUSERDATA: - { - reqdata_type = TYPE_BOOLEAN; - returned_reqdata.boolean = *((bool*)data); - break; - } - case REQ_NOP: - break; - case REQ_PRINTNEWLINE: - { - out("\n"); - break; - } - case REQ_ALLDONE: - request_complete = 1; - return true; - default: - debugf("WARNING: client process received unknown code %d\n", cmd); - break; - } - } -fail: - - return got_cmd; -} - -void client_change_state(int state) -{ - send_master(REQ_CHANGESTATE, &state, sizeof(state)); -} - -void client_change_user(const char *user) -{ - send_master(REQ_CHANGEUSER, user, strlen(user) + 1); -} - -void client_change_room(room_id id) -{ - send_master(REQ_SETROOM, &id, sizeof(id)); -} - -void *dir_map = NULL; - -bool client_move(const char *dir) -{ - const struct dir_pair { - const char *text; - enum direction_t val; - } dirs[] = { - { "N", DIR_N }, - { "NORTH", DIR_N }, - { "NE", DIR_NE }, - { "NORTHEAST", DIR_N }, - { "E", DIR_E }, - { "EAST", DIR_E }, - { "SE", DIR_SE }, - { "SOUTHEAST", DIR_SE }, - { "S", DIR_S }, - { "SOUTH", DIR_S }, - { "SW", DIR_SW }, - { "SOUTHWEST", DIR_SW }, - { "W", DIR_W }, - { "WEST", DIR_W }, - { "NW", DIR_NW }, - { "NORTHWEST", DIR_NW }, - { "U", DIR_UP }, - { "UP", DIR_UP }, - { "D", DIR_DN }, - { "DOWN", DIR_DN }, - { "IN", DIR_IN }, - { "OUT", DIR_OT }, - }; - - if(!dir_map) - { - 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(dir_map, dir); - if(pair) - { - send_master(REQ_MOVE, &pair->val, sizeof(pair->val)); - if(reqdata_type == TYPE_BOOLEAN && returned_reqdata.boolean) - return true; - else - return false; - } - else - { - out("Unknown direction.\n"); - return false; - } -} - -void client_look(void) -{ - send_master(REQ_GETROOMNAME, NULL, 0); - out("\n"); - send_master(REQ_GETROOMDESC, NULL, 0); -} - -void client_look_at(char *obj) -{ - all_lower(obj); - send_master(REQ_LOOKAT, obj, strlen(obj) + 1); -} - -void client_take(char *obj) -{ - all_lower(obj); - send_master(REQ_TAKE, obj, strlen(obj) + 1); -} - -void client_inventory(void) -{ - send_master(REQ_PRINTINVENTORY, NULL, 0); -} - -void client_drop(char *what) -{ - send_master(REQ_DROP, what, strlen(what) + 1); -} - -void client_user_list(void) -{ - send_master(REQ_LISTUSERS, NULL, 0); -} - #define WSPACE " \t\r\n" #define CMD_OK 0 @@ -721,7 +459,6 @@ void client_shutdown(void) cmd_map = NULL; } - void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from) { client_fd = fd; @@ -797,8 +534,8 @@ auth: if(authlevel == PRIV_NONE) return; - admin = (authlevel == PRIV_ADMIN); - if(admin) + are_admin = (authlevel == PRIV_ADMIN); + if(are_admin) client_change_state(STATE_ADMIN); else client_change_state(STATE_LOGGEDIN); @@ -827,7 +564,7 @@ auth: all_upper(tok); const struct client_cmd *cmd = hash_lookup(cmd_map, tok); - if(cmd && cmd->cb && (!cmd->admin_only || (cmd->admin_only && admin))) + if(cmd && cmd->cb && (!cmd->admin_only || (cmd->admin_only && are_admin))) { int ret = cmd->cb(&save); switch(ret) @@ -846,7 +583,7 @@ auth: error("client: bad callback return value"); } } - else if(cmd && cmd->admin_only && !admin) + else if(cmd && cmd->admin_only && !are_admin) { out("You are not allowed to do that.\n"); goto next_cmd; |