diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.c | 58 | ||||
| -rw-r--r-- | src/netcosm.h | 3 | ||||
| -rw-r--r-- | src/server.c | 44 |
3 files changed, 64 insertions, 41 deletions
diff --git a/src/client.c b/src/client.c index 8006154..7639273 100644 --- a/src/client.c +++ b/src/client.c @@ -2,7 +2,7 @@ static int client_fd, to_parent, from_parent; -static room_id client_room; +static room_id current_room = 0; static volatile sig_atomic_t output_locked = 0; @@ -59,9 +59,11 @@ static void signal_master(void) printf("Request completely done.\n"); } -void send_master(unsigned char cmd) +void send_master(unsigned char cmd, const void *data, size_t sz) { write(to_parent, &cmd, 1); + if(data) + write(to_parent, data, sz); signal_master(); } @@ -154,22 +156,21 @@ void sigusr2_handler(int s, siginfo_t *info, void *vp) request_complete = 1; } -void client_change_state(int state) +static void client_change_state(int state) { printf("Client requesting state transition\n"); - unsigned char cmdcode = REQ_CHANGESTATE; - write(to_parent, &cmdcode, sizeof(cmdcode)); - write(to_parent, &state, sizeof(state)); - signal_master(); + send_master(REQ_CHANGESTATE, &state, sizeof(state)); printf("State transition completed.\n"); } -void client_change_user(const char *user) +static void client_change_user(const char *user) { - unsigned char cmdcode = REQ_CHANGEUSER; - write(to_parent, &cmdcode, sizeof(cmdcode)); - write(to_parent, user, strlen(user) + 1); - signal_master(); + send_master(REQ_CHANGEUSER, user, strlen(user) + 1); +} + +static void client_change_room(room_id id) +{ + send_master(REQ_CHANGEROOM, &id, sizeof(id)); } #define WSPACE " \t\r\n" @@ -257,6 +258,7 @@ auth: /* authenticated */ printf("Authenticated as %s\n", current_user); client_change_user(current_user); + client_change_room(current_room); while(1) { out(">> "); @@ -362,23 +364,22 @@ auth: if(!strcmp(what, "LIST")) { - unsigned char cmd_code = REQ_LISTCLIENTS; - write(to_parent, &cmd_code, sizeof(cmd_code)); - signal_master(); + send_master(REQ_LISTCLIENTS, NULL, 0); } else if(!strcmp(what, "KICK")) { char *pid_s = strtok_r(NULL, WSPACE, &save); if(pid_s) { - unsigned char cmd_code = REQ_KICK; - write(to_parent, &cmd_code, sizeof(cmd_code)); + /* weird pointer voodoo */ + /* TODO: simplify */ + char buf[MSG_MAX]; pid_t pid = strtol(pid_s, NULL, 0); - write(to_parent, &pid, sizeof(pid)); - char buf[128]; - int len = snprintf(buf, sizeof(buf), "You were kicked.\n"); - write(to_parent, buf, len); - signal_master(); + *((pid_t*)buf) = pid; + int len = sizeof(pid_t) + snprintf(buf + sizeof(pid_t), + sizeof(buf) - sizeof(pid_t), + "You were kicked.\n"); + send_master(REQ_KICK, buf, len); printf("Success.\n"); } else @@ -398,11 +399,11 @@ auth: } else if(!strcmp(tok, "SAY")) { + char buf[MSG_MAX]; char *what = strtok_r(NULL, "", &save); - unsigned char cmd_code = REQ_BCASTMSG; - write(to_parent, &cmd_code, sizeof(cmd_code)); - dprintf(to_parent, "%s says %s", current_user, what); - signal_master(); + int len = snprintf(buf, sizeof(buf), "%s says %s", current_user, what); + + send_master(REQ_BCASTMSG, buf, len); } else if(!strcmp(tok, "DATE")) { @@ -416,12 +417,11 @@ auth: } else if(!strcmp(tok, "LOOK")) { - //out(room_get(client_room)->data.desc); - //out("\n"); + send_master(REQ_LOOK, NULL, 0); } else if(!strcmp(tok, "WAIT")) { - send_master(REQ_WAIT); + send_master(REQ_WAIT, NULL, 0); } next_cmd: diff --git a/src/netcosm.h b/src/netcosm.h index ac2c72c..8482e90 100644 --- a/src/netcosm.h +++ b/src/netcosm.h @@ -40,6 +40,8 @@ #define REQ_HANG 5 #define REQ_KICK 6 #define REQ_WAIT 7 +#define REQ_LOOK 8 +#define REQ_CHANGEROOM 9 /* child states */ #define STATE_INIT 0 @@ -144,3 +146,4 @@ void remove_cruft(char*); void auth_list_users(void); void world_init(const struct roomdata_t *data, size_t sz); void sig_printf(const char *fmt, ...); +void world_free(void); diff --git a/src/server.c b/src/server.c index abbad30..f82502d 100644 --- a/src/server.c +++ b/src/server.c @@ -88,7 +88,7 @@ static void sigchld_handler(int s, siginfo_t *info, void *vp) int port; static void handle_client(int fd, struct sockaddr_in *addr, - int nclients, int to, int from) + int nclients, int to, int from) { client_main(fd, addr, nclients, to, from); } @@ -110,7 +110,7 @@ static void sigint_handler(int s) } static void req_pass_msg(unsigned char *data, size_t datalen, - struct child_data *sender, struct child_data *child) + struct child_data *sender, struct child_data *child) { (void) sender; @@ -125,7 +125,7 @@ static void req_pass_msg(unsigned char *data, size_t datalen, } static void req_send_clientinfo(unsigned char *data, size_t datalen, - struct child_data *sender, struct child_data *child) + struct child_data *sender, struct child_data *child) { (void) data; (void) datalen; @@ -142,16 +142,16 @@ static void req_send_clientinfo(unsigned char *data, size_t datalen, if(child->user) len = snprintf(buf, sizeof(buf), "Client %s PID %d [%s] USER %s\n", - inet_ntoa(child->addr), child->pid, state[child->state], child->user); + inet_ntoa(child->addr), child->pid, state[child->state], child->user); else len = snprintf(buf, sizeof(buf), "Client %s PID %d [%s]\n", - inet_ntoa(child->addr), child->pid, state[child->state]); + inet_ntoa(child->addr), child->pid, state[child->state]); write(sender->outpipe[1], buf, len); } static void req_change_state(unsigned char *data, size_t datalen, - struct child_data *sender, struct child_data *child) + struct child_data *sender, struct child_data *child) { (void) child; if(datalen == sizeof(sender->state)) @@ -168,7 +168,7 @@ static void req_change_state(unsigned char *data, size_t datalen, } static void req_change_user(unsigned char *data, size_t datalen, - struct child_data *sender, struct child_data *child) + struct child_data *sender, struct child_data *child) { (void) data; (void) datalen; @@ -185,7 +185,7 @@ static void req_change_user(unsigned char *data, size_t datalen, //} static void req_kick_client(unsigned char *data, size_t datalen, - struct child_data *sender, struct child_data *child) + struct child_data *sender, struct child_data *child) { (void) sender; if(datalen >= sizeof(pid_t)) @@ -201,11 +201,27 @@ static void req_kick_client(unsigned char *data, size_t datalen, } } -static void req_wait(struct child_data *sender) +static void req_wait(unsigned char *data, size_t len, struct child_data *sender) { sleep(10); } +static void req_send_desc(unsigned char *data, size_t len, struct child_data *sender) +{ + struct room_t *room = room_get(sender->room); + write(sender->outpipe[1], room->data.desc, strlen(room->data.desc) + 1); + + char newline = '\n'; + write(sender->outpipe[1], &newline, 1); +} + +static void req_change_room(unsigned char *data, size_t len, struct child_data *sender) +{ + room_id id = *((room_id*)data); + + sender->room = id; +} + static const struct child_request { unsigned char code; @@ -218,7 +234,7 @@ static const struct child_request { void (*handle_child)(unsigned char *data, size_t len, struct child_data *sender, struct child_data *child); - void (*finalize)(struct child_data *sender); + void (*finalize)(unsigned char *data, size_t len, struct child_data *sender); /* byte to write back to the sender */ unsigned char cmd_to_send; @@ -228,9 +244,10 @@ static const struct child_request { { REQ_LISTCLIENTS, false, CHILD_ALL, req_send_clientinfo, NULL, REQ_BCASTMSG }, { REQ_CHANGESTATE, true, CHILD_SENDER, req_change_state, NULL, REQ_NOP }, { REQ_CHANGEUSER, true, CHILD_SENDER, req_change_user, NULL, REQ_NOP }, - //{ REQ_HANG, false, CHILD_SENDER, req_hang, NULL, REQ_NOP }, { REQ_KICK, true, CHILD_ALL, req_kick_client, NULL, REQ_NOP }, { REQ_WAIT, false, CHILD_NONE, NULL, req_wait, REQ_NOP }, + { REQ_LOOK, false, CHILD_NONE, NULL, req_send_desc, REQ_BCASTMSG }, + { REQ_CHANGEROOM, true, CHILD_NONE, NULL, req_change_room, REQ_NOP }, }; void sig_printf(const char *fmt, ...) @@ -343,7 +360,7 @@ static void sigusr1_handler(int s, siginfo_t *info, void *vp) finish: if(req && req->finalize) - req->finalize(sender); + req->finalize(data, datalen, sender); if(sender) kill(sender->pid, SIGUSR2); @@ -469,6 +486,9 @@ int main(int argc, char *argv[]) close(outpipe[1]); close(server_socket); + /* only the master process controls the world */ + world_free(); + printf("Child with PID %d spawned\n", getpid()); server_socket = new_sock; |