aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.c58
-rw-r--r--src/netcosm.h3
-rw-r--r--src/server.c44
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;