aboutsummaryrefslogtreecommitdiff
path: root/src/client.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-02-16 21:17:46 -0500
committerFranklin Wei <git@fwei.tk>2016-02-16 21:17:46 -0500
commit02de31c48c021742c6245b711790f6d853866c36 (patch)
treed145f3ce9156de42064f8bceb3d0eb4362e3bb5a /src/client.c
parent8c58ee885941af4c944995b029363f139b8f54bd (diff)
downloadnetcosm-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.c275
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;