aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-01-16 20:05:58 -0500
committerFranklin Wei <git@fwei.tk>2016-01-16 20:05:58 -0500
commit98896de83ffa7380404e41b6ed80cfc6ba3bf8f0 (patch)
tree427f48b92d647c6278df083f86d33a7545710a6c
parent056220075ca575c17899abea7b3a2fb55e64b561 (diff)
downloadnetcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.zip
netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.tar.gz
netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.tar.bz2
netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.tar.xz
packetized requests
-rw-r--r--Makefile1
-rw-r--r--README.md2
-rw-r--r--src/auth.c5
-rw-r--r--src/client.c216
-rw-r--r--src/client.h2
-rw-r--r--src/globals.h6
-rw-r--r--src/room.h26
-rw-r--r--src/server.c15
-rw-r--r--src/server_reqs.c126
-rw-r--r--src/server_reqs.h1
-rw-r--r--src/userdb.c1
-rw-r--r--src/util.c9
-rw-r--r--worlds/test.c57
13 files changed, 262 insertions, 205 deletions
diff --git a/Makefile b/Makefile
index ca121ed..ebbbca0 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,6 @@ $(OUT)/$(PLATFORM).bin: $(NETCOSM_OBJ) $(HEADERS) Makefile
# automatically generate dependency rules
%.d : %.c
- @echo "MKDEP $<"
@$(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"
# -MF write the generated dependency rule to a file
diff --git a/README.md b/README.md
index 8640d02..4fbf6d7 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ features might drift out of existence without prior warning!
libgcrypt
libev
-linux >= 2.6.27
+linux >= 3.4 (need "packet mode" pipes)
glibc >= 2.9
### Compiling
diff --git a/src/auth.c b/src/auth.c
index b5f8942..80a6583 100644
--- a/src/auth.c
+++ b/src/auth.c
@@ -58,6 +58,8 @@ static char *hash_pass_hex(const char *pass, const char *salt)
char *ptr = hex;
for(unsigned int i = 0; i < hash_len; ++i, ptr += 2)
snprintf(ptr, 3, "%02x", hash[i]);
+ hex[hash_len * 2] = '\0';
+ sig_debugf("hash is %s\n", hex);
gcry_free(hash);
@@ -194,6 +196,7 @@ struct userdata_t *auth_check(const char *name2, const char *pass2)
if(data)
{
+ sig_debugf("auth module: user %s found\n", name2);
char *new_hash_hex = hash_pass_hex(pass, salt);
memset(pass, 0, strlen(pass));
@@ -208,6 +211,8 @@ struct userdata_t *auth_check(const char *name2, const char *pass2)
return data;
}
+ sig_debugf("auth failure: username not found\n");
+
/* failure */
sleep(2);
return NULL;
diff --git a/src/client.c b/src/client.c
index 0a131d1..fff08a6 100644
--- a/src/client.c
+++ b/src/client.c
@@ -36,9 +36,13 @@ static volatile sig_atomic_t output_locked = 0;
char *current_user = NULL;
-void out_raw(const unsigned char *buf, size_t len)
+void out_raw(const void *buf, size_t len)
{
+ if(!len)
+ return;
+
try_again:
+
while(output_locked);
/* something weird happened and the value changed between the loop and here */
@@ -52,19 +56,58 @@ try_again:
goto try_again;
}
+#define WRAP_COLS 80
+
void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
{
- char buf[128];
+ char buf[1024];
memset(buf, 0, sizeof(buf));
va_list ap;
va_start(ap, fmt);
- int len = vsnprintf(buf, sizeof(buf), fmt, ap);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- out_raw((unsigned char*)buf, len);
+
+ /* do some line wrapping */
+
+ int x = 0;
+
+ char word_buf[sizeof(buf)], *ptr = buf;
+
+ char newline = '\n';
+
+ int word_idx = 0;
+ while(1)
+ {
+ char c = *ptr++;
+ if(!c)
+ break;
+ word_buf[word_idx++] = c;
+ x++;
+ if(c == ' ' || c == '\n')
+ {
+ if(x >= WRAP_COLS - 1)
+ {
+ sig_debugf("Wrapping...\n");
+ out_raw(&newline, 1);
+ x = 0;
+ }
+ out_raw(word_buf, word_idx);
+ word_idx = 0;
+ }
+ }
+
+ if(x >= WRAP_COLS - 1)
+ {
+ sig_debugf("Wrapping...\n");
+ out_raw(&newline, 1);
+ x = 0;
+ }
+ out_raw(word_buf, word_idx);
}
static volatile sig_atomic_t request_complete;
+/* for rate-limiting */
static int reqs_since_ts;
static time_t ts = 0;
@@ -93,20 +136,22 @@ void send_master(unsigned char cmd, const void *data, size_t sz)
sigprocmask(SIG_BLOCK, &block, &old);
pid_t our_pid = getpid();
- size_t total_len = (data?sz:0) + 1;
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(1 + sizeof(pid_t) + sizeof(size_t) + sz);
+ char *req = malloc(sizeof(pid_t) + 1 + sz);
memcpy(req, &our_pid, sizeof(pid_t));
- memcpy(req + sizeof(pid_t), &total_len, sizeof(size_t));
- memcpy(req + sizeof(pid_t) + sizeof(size_t), &cmd, 1);
- memcpy(req + sizeof(pid_t) + sizeof(size_t) + 1, data, sz);
+ memcpy(req + sizeof(pid_t), &cmd, 1);
+ memcpy(req + sizeof(pid_t) + 1, data, sz);
- write(to_parent, req, 1 + sizeof(pid_t) + sizeof(size_t) + sz);
+ write(to_parent, req, 1 + sizeof(pid_t) + sz);
sigsuspend(&old);
sigprocmask(SIG_SETMASK, &old, NULL);
@@ -154,18 +199,6 @@ char *client_read_password(void)
return ret;
}
-static void print_all(int fd)
-{
- unsigned char buf[MSG_MAX + 1];
- do {
- ssize_t len = read(fd, &buf, MSG_MAX);
- if(len <= 0)
- break;
- buf[MSG_MAX] = '\0';
- out_raw(buf, len);
- } while(1);
-}
-
enum reqdata_typespec reqdata_type = TYPE_NONE;
union reqdata_t returned_reqdata;
@@ -189,6 +222,8 @@ void sig_rt_0_handler(int s, siginfo_t *info, void *v)
if(!are_child)
return;
+ sig_debugf("Master process sends SIG\n");
+
/* we only listen to requests from our parent */
if(info->si_pid != getppid())
{
@@ -196,74 +231,91 @@ void sig_rt_0_handler(int s, siginfo_t *info, void *v)
return;
}
+
reqdata_type = TYPE_NONE;
- unsigned char cmd;
- read(from_parent, &cmd, 1);
- switch(cmd)
- {
- case REQ_BCASTMSG:
- {
- print_all(from_parent);
- break;
- }
- case REQ_KICK:
- {
- print_all(from_parent);
- union sigval junk = { 0 };
- /* the master still expects an ACK */
- sigqueue(getppid(), SIGRTMIN+1, junk);
- exit(EXIT_SUCCESS);
- }
- case REQ_MOVE:
- {
- bool status;
- read(from_parent, &status, sizeof(status));
- reqdata_type = TYPE_BOOLEAN;
- returned_reqdata.boolean = status;
- if(!status)
- out("Cannot go that way.\n");
- break;
- }
- case REQ_GETUSERDATA:
+ while(1)
{
- sig_debugf("got user data\n");
- bool success;
- read(from_parent, &success, sizeof(success));
- if(success)
- reqdata_type = TYPE_USERDATA;
- else
+ unsigned char packet[MSG_MAX + 1];
+ memset(packet, 0, sizeof(packet));
+ ssize_t packetlen = read(from_parent, packet, MSG_MAX);
+ sig_debugf("done reading data\n");
+ unsigned char *data = packet + 1;
+ size_t datalen = packetlen - 1;
+ packet[MSG_MAX] = '\0';
+
+ if(packetlen <= 0)
+ goto fail;
+
+ unsigned char cmd = packet[0];
+
+ sig_debugf("child got code %d\n", cmd);
+
+ switch(cmd)
{
- sig_debugf("failure\n");
+ case REQ_BCASTMSG:
+ {
+ out((char*)data, datalen);
break;
}
+ case REQ_KICK:
+ {
+ out((char*)data, datalen);
+ union sigval junk = { 0 };
+ /* the master still expects an ACK */
+ sigqueue(getppid(), SIGRTMIN+1, junk);
+ exit(EXIT_SUCCESS);
+ }
+ case REQ_MOVE:
+ {
+ bool status = *((bool*)data);
- struct userdata_t *user = &returned_reqdata.userdata;
- if(read(from_parent, user, sizeof(*user)) != sizeof(*user))
- error("user data too short");
- break;
- }
- case REQ_DELUSERDATA:
- {
- reqdata_type = TYPE_BOOLEAN;
- if(read(from_parent, &returned_reqdata.boolean, sizeof(bool)) != sizeof(bool))
- error("error reading bool");
- break;
- }
- case REQ_ADDUSERDATA:
- {
- reqdata_type = TYPE_BOOLEAN;
- if(read(from_parent, &returned_reqdata.boolean, sizeof(bool)) != sizeof(bool))
- error("error reading bool");
- break;
- }
- case REQ_NOP:
- break;
- default:
- sig_debugf("WARNING: client process received unknown code %d\n", cmd);
- break;
- }
+ reqdata_type = TYPE_BOOLEAN;
+ returned_reqdata.boolean = status;
+ if(!status)
+ out("Cannot go that way.\n");
+ break;
+ }
+ case REQ_GETUSERDATA:
+ {
+ sig_debugf("got user data\n");
+ if(datalen == sizeof(struct userdata_t))
+ reqdata_type = TYPE_USERDATA;
+ else
+ {
+ sig_debugf("failure %d %d\n", datalen, sizeof(struct userdata_t));
+ 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_PRINT_NL:
+ {
+ out("\n");
+ break;
+ }
+ default:
+ sig_debugf("WARNING: client process received unknown code %d\n", cmd);
+ break;
+ }
+ }
+fail:
sig_debugf("Client finishes handling request.\n");
request_complete = 1;
diff --git a/src/client.h b/src/client.h
index be75c03..eeb515d 100644
--- a/src/client.h
+++ b/src/client.h
@@ -39,7 +39,7 @@ void send_master(unsigned char cmd, const void *data, size_t sz);
void sig_rt_0_handler(int s, siginfo_t *info, void *v);
void out(const char *fmt, ...) __attribute__((format(printf,1,2)));
-void out_raw(const unsigned char*, size_t);
+void out_raw(const void*, size_t);
/* called for every client */
void client_main(int sock, struct sockaddr_in *addr, int, int to_parent, int from_parent);
diff --git a/src/globals.h b/src/globals.h
index 35db514..1eed1d4 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -29,6 +29,7 @@
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <netdb.h>
#include <netinet/in.h>
#include <poll.h>
@@ -55,6 +56,8 @@
/* global constants */
#define USERFILE "users.dat"
#define WORLDFILE "world.dat"
+#define LOGFILE "netcosm.log"
+
#define WORLD_MAGIC 0xff467777
#define MAX_FAILURES 3
#define NETCOSM_VERSION "0.2"
@@ -78,8 +81,7 @@
#include "util.h"
-/* needs to be less than PIPE_BUF, which is 4096 */
-#define MSG_MAX 2048
+#define MSG_MAX PIPE_BUF
#ifndef NDEBUG
#define debugf(fmt,...) debugf_real(__func__, __LINE__, __FILE__, fmt, ##__VA_ARGS__)
#define sig_debugf debugf
diff --git a/src/room.h b/src/room.h
index 6568643..d1cf510 100644
--- a/src/room.h
+++ b/src/room.h
@@ -24,6 +24,11 @@ typedef enum obj_id { OBJ_NONE = -1 } 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 };
+struct user_t {
+ struct child_data *data;
+ struct user_t *next;
+};
+
/* the data we get from a world module */
struct roomdata_t {
/* the non-const pointers can be modified by the world module */
@@ -36,27 +41,30 @@ struct roomdata_t {
const char * const adjacent[NUM_DIRECTIONS];
void (* const hook_init)(room_id id);
- void (* const hook_enter)(room_id room, pid_t player);
- void (* const hook_say)(room_id room, pid_t player, const char *msg);
- void (* const hook_leave)(room_id room, pid_t player);
-};
-
-struct user_t {
- struct child_data *data;
- struct user_t *next;
+ void (* const hook_enter)(room_id room, struct user_t *user);
+ void (* const hook_leave)(room_id room, struct 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;
+
+ 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_destroy)(struct object_t*);
};
struct verb_t {
const char *name;
/* toks is strtok_r's pointer */
- void (*execute)(const char *toks);
+ void (*execute)(const char *toks, struct user_t *user);
};
struct room_t {
diff --git a/src/server.c b/src/server.c
index 5b963b6..50f055f 100644
--- a/src/server.c
+++ b/src/server.c
@@ -114,7 +114,7 @@ static void __attribute__((noreturn)) serv_cleanup(void)
if(!child)
break;
ptr = NULL;
- kill(child->pid, SIGKILL);
+ //kill(child->pid, SIGKILL);
} while(1);
handle_disconnects();
@@ -275,15 +275,11 @@ static void new_connection_cb(EV_P_ ev_io *w, int revents)
int readpipe[2]; /* child->parent */
int outpipe [2]; /* parent->child */
- if(pipe(readpipe) < 0)
+ if(pipe2(readpipe, O_DIRECT) < 0)
error("pipe");
- if(pipe(outpipe) < 0)
+ if(pipe2(outpipe, O_NONBLOCK | O_DIRECT) < 0)
error("pipe");
- int flags = fcntl(outpipe[0], F_GETFL, 0);
- if(fcntl(outpipe[0], F_SETFL, flags | O_NONBLOCK) < 0)
- error("fcntl");
-
pid_t pid = fork();
if(pid < 0)
error("fork");
@@ -348,9 +344,14 @@ static void new_connection_cb(EV_P_ ev_io *w, int revents)
int main(int argc, char *argv[])
{
+ debugf("*** Starting NetCosm "NETCOSM_VERSION" (libev %d.%d, libgcrypt "GCRYPT_VERSION") ***\n",
+ EV_VERSION_MAJOR, EV_VERSION_MINOR);
+
assert(ev_version_major() == EV_VERSION_MAJOR &&
ev_version_minor() >= EV_VERSION_MINOR);
+ assert(!strcmp(GCRYPT_VERSION, gcry_check_version(GCRYPT_VERSION)));
+
if(argc != 2)
port = PORT;
else
diff --git a/src/server_reqs.c b/src/server_reqs.c
index 7856ac0..01e8e16 100644
--- a/src/server_reqs.c
+++ b/src/server_reqs.c
@@ -24,25 +24,26 @@
static volatile sig_atomic_t num_acks_wanted, num_acks_recvd, inc_acks = 0;
+static void send_packet(struct child_data *child, unsigned char cmd,
+ void *data, size_t datalen)
+{
+ unsigned char pkt[MSG_MAX];
+ pkt[0] = cmd;
+ if(datalen)
+ memcpy(pkt + 1, data, datalen);
+ write(child->outpipe[1], pkt, datalen + 1);
+}
+
static void req_pass_msg(unsigned char *data, size_t datalen,
struct child_data *sender, struct child_data *child)
{
(void) sender;
- if(sender->pid != child->pid)
- {
- unsigned char cmd = REQ_BCASTMSG;
- write(child->outpipe[1], &cmd, 1);
- }
+ send_packet(child, REQ_BCASTMSG, data, datalen);
- write(child->outpipe[1], data, datalen);
union sigval nothing = { 0 };
-
- if(sender->pid != child->pid)
- {
- sigqueue(child->pid, SIGRTMIN, nothing);
- ++num_acks_wanted;
- }
+ sigqueue(child->pid, SIGRTMIN, nothing);
+ ++num_acks_wanted;
}
static void req_send_clientinfo(unsigned char *data, size_t datalen,
@@ -72,7 +73,7 @@ static void req_send_clientinfo(unsigned char *data, size_t datalen,
else
strncat(buf, "\n", sizeof(buf) - 1);
- write(sender->outpipe[1], buf, strlen(buf));
+ send_packet(sender, REQ_BCASTMSG, buf, strlen(buf));
}
static void req_change_state(unsigned char *data, size_t datalen,
@@ -86,9 +87,7 @@ static void req_change_state(unsigned char *data, size_t datalen,
}
else
{
- debugf("State data is of the wrong size\n");
- for(size_t i = 0; i < datalen; ++i)
- debugf("%02x\n", data[i]);
+ debugf("State data is of the wrong size %*s\n", datalen, data);
}
}
@@ -110,15 +109,14 @@ 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)
{
+ /* format is | PID | Message | */
(void) data; (void) datalen; (void) child; (void) sender;
if(datalen >= sizeof(pid_t))
{
pid_t kicked_pid = *((pid_t*)data);
if(kicked_pid == child->pid)
{
- unsigned char cmd = REQ_KICK;
- write(child->outpipe[1], &cmd, 1);
- write(child->outpipe[1], data + sizeof(pid_t), datalen - sizeof(pid_t));
+ send_packet(child, REQ_BCASTMSG, data + sizeof(pid_t), datalen - sizeof(pid_t));
union sigval nothing = { 0 };
sigqueue(child->pid, SIGRTMIN, nothing);
}
@@ -135,20 +133,18 @@ static void req_send_desc(unsigned char *data, size_t datalen, struct child_data
{
(void) data; (void) datalen; (void) sender;
struct room_t *room = room_get(sender->room);
- write(sender->outpipe[1], room->data.desc, strlen(room->data.desc) + 1);
+ send_packet(sender, REQ_BCASTMSG, room->data.desc, strlen(room->data.desc));
- char newline = '\n';
- write(sender->outpipe[1], &newline, 1);
+ send_packet(sender, REQ_PRINT_NL, NULL, 0);
}
static void req_send_roomname(unsigned char *data, size_t datalen, struct child_data *sender)
{
(void) data; (void) datalen; (void) sender;
struct room_t *room = room_get(sender->room);
- write(sender->outpipe[1], room->data.name, strlen(room->data.name) + 1);
+ send_packet(sender, REQ_BCASTMSG, room->data.name, strlen(room->data.name));
- char newline = '\n';
- write(sender->outpipe[1], &newline, 1);
+ send_packet(sender, REQ_PRINT_NL, NULL, 0);
}
static void child_set_room(struct child_data *child, room_id id)
@@ -186,7 +182,7 @@ static void req_move_room(unsigned char *data, size_t datalen, struct child_data
{
status = false;
}
- write(sender->outpipe[1], &status, sizeof(status));
+ send_packet(sender, REQ_MOVE, &status, sizeof(status));
}
static void req_send_user(unsigned char *data, size_t datalen, struct child_data *sender)
@@ -197,19 +193,15 @@ static void req_send_user(unsigned char *data, size_t datalen, struct child_data
if(user)
{
- bool confirm = true;
- write(sender->outpipe[1], &confirm, sizeof(confirm));
- write(sender->outpipe[1], user, sizeof(*user));
+ send_packet(sender, REQ_GETUSERDATA, user, sizeof(*user));
return;
}
+ sig_debugf("looking up user %s failed\n", data);
sig_debugf("failure 2\n");
}
sig_debugf("failure 1\n");
-
- bool fail = false;
- write(sender->outpipe[1], &fail, sizeof(fail));
}
static void req_del_user(unsigned char *data, size_t datalen, struct child_data *sender)
@@ -219,7 +211,7 @@ static void req_del_user(unsigned char *data, size_t datalen, struct child_data
{
success = userdb_remove((char*)data);
}
- write(sender->outpipe[1], &success, sizeof(success));
+ send_packet(sender, REQ_DELUSERDATA, &success, sizeof(success));
}
static void req_add_user(unsigned char *data, size_t datalen, struct child_data *sender)
@@ -229,7 +221,7 @@ static void req_add_user(unsigned char *data, size_t datalen, struct child_data
{
success = userdb_add((struct userdata_t*)data);
}
- write(sender->outpipe[1], &success, sizeof(success));
+ send_packet(sender, REQ_ADDUSERDATA, &success, sizeof(success));
}
static void req_send_geninfo(unsigned char *data, size_t datalen, struct child_data *sender)
@@ -238,7 +230,7 @@ static void req_send_geninfo(unsigned char *data, size_t datalen, struct child_d
(void) datalen;
char buf[128];
int len = snprintf(buf, sizeof(buf), "Total clients: %d\n", num_clients);
- write(sender->outpipe[1], buf, len);
+ send_packet(sender, REQ_BCASTMSG, buf, len);
}
static const struct child_request {
@@ -312,22 +304,14 @@ void reqmap_free(void)
bool handle_child_req(int in_fd)
{
- pid_t sender_pid;
+ unsigned char packet[MSG_MAX + 1];
- if(read(in_fd, &sender_pid, sizeof(sender_pid)) != sizeof(sender_pid))
- {
- sig_debugf("Couldn't get sender PID\n");
- return false;
- }
+ ssize_t packet_len = read(in_fd, packet, MSG_MAX);
+ pid_t sender_pid;
+ memcpy(&sender_pid, packet, sizeof(pid_t));
sig_debugf("Got request from PID %d\n", sender_pid);
- size_t msglen;
- const struct child_request *req = NULL;
- size_t datalen;
-
- unsigned char cmd, msg[MSG_MAX + 1];
-
struct child_data *sender = hash_lookup(child_map, &sender_pid);
if(!sender)
@@ -336,44 +320,12 @@ bool handle_child_req(int in_fd)
goto fail;
}
- if(read(in_fd, &msglen, sizeof(msglen)) != sizeof(msglen))
- {
- sig_debugf("Couldn't read message length, dropping.\n");
- goto fail;
- }
+ unsigned char cmd = packet[sizeof(pid_t)];
- if(msglen < 1)
- {
- sig_debugf("message too short to be valid, ignoring.\n");
- goto fail;
- }
- else if(msglen > MSG_MAX)
- {
- sig_debugf("message too long, ignoring.\n");
- goto fail;
- }
+ unsigned char *data = packet + sizeof(pid_t) + 1;
+ size_t datalen = packet_len - sizeof(pid_t) - 1;
- unsigned char *msgptr = msg;
- size_t have = 0;
- while(have < msglen)
- {
- ssize_t ret = read(sender->readpipe[0], msgptr, msglen - have);
- if(ret < 0)
- {
- sig_debugf("unexpected EOF\n");
- goto fail;
- }
- msgptr += ret;
- have += ret;
- }
-
- cmd = msg[0];
- msg[MSG_MAX] = '\0';
-
- unsigned char *data = msg + 1;
-
- datalen = msglen - 1;
- req = hash_lookup(request_map, &cmd);
+ struct child_request *req = hash_lookup(request_map, &cmd);
sigset_t old, block;
@@ -391,8 +343,6 @@ bool handle_child_req(int in_fd)
goto fail;
}
- write(sender->outpipe[1], &req->cmd_to_send, 1);
-
switch(req->which)
{
case CHILD_SENDER:
@@ -432,6 +382,11 @@ bool handle_child_req(int in_fd)
finish:
+ //if(req)
+ //{
+ // send_packet(sender, req->cmd_to_send, NULL, 0);
+ //}
+
if(req && req->finalize)
req->finalize(data, datalen, sender);
@@ -458,7 +413,6 @@ finish:
sigprocmask(SIG_SETMASK, &old, NULL);
- return true;
fail:
return true;
}
diff --git a/src/server_reqs.h b/src/server_reqs.h
index 1c15d12..9502c11 100644
--- a/src/server_reqs.h
+++ b/src/server_reqs.h
@@ -35,6 +35,7 @@
#define REQ_GETUSERDATA 13 /* server: send user data; child: get user data */
#define REQ_DELUSERDATA 14 /* server: delete user data; child: success/failure */
#define REQ_ADDUSERDATA 15 /* server: insert user data; child: success/fail */
+#define REQ_PRINT_NL 16 /* child: print a newline */
/* child states, sent as an int to the master */
#define STATE_INIT 0 /* initial state */
diff --git a/src/userdb.c b/src/userdb.c
index 569ad92..9c7343a 100644
--- a/src/userdb.c
+++ b/src/userdb.c
@@ -153,6 +153,7 @@ struct userdata_t *userdb_request_lookup(const char *name)
if(are_child)
{
send_master(REQ_GETUSERDATA, name, strlen(name) + 1);
+ sig_debugf("returned reqdata is of type %d\n", reqdata_type);
if(reqdata_type == TYPE_USERDATA)
return &returned_reqdata.userdata;
return NULL;
diff --git a/src/util.c b/src/util.c
index 2c10eef..6d2d184 100644
--- a/src/util.c
+++ b/src/util.c
@@ -25,7 +25,7 @@ void remove_cruft(char *str)
}
/**
- * WARNING: not signal-safe
+ * WARNING: not signal-safe AT ALL
* TODO: rewrite to avoid calling *printf()
*/
void debugf_real(const char *func, int line, const char *file, const char *fmt, ...)
@@ -33,6 +33,11 @@ void debugf_real(const char *func, int line, const char *file, const char *fmt,
(void) func;
(void) line;
(void) file;
+ static int fd = -1;
+ if(fd < 0)
+ fd = open(LOGFILE, O_APPEND | O_WRONLY | O_CREAT, 0600);
+ if(fd < 0)
+ error("unknown");
int len;
#if 0
char *prefix;
@@ -48,6 +53,8 @@ void debugf_real(const char *func, int line, const char *file, const char *fmt,
len = vasprintf(&buf, fmt, ap);
write(STDOUT_FILENO, buf, len);
+ write(fd, buf, len);
+ fflush(fdopen(fd, "a"));
free(buf);
diff --git a/worlds/test.c b/worlds/test.c
index 5a7e020..3bb9287 100644
--- a/worlds/test.c
+++ b/worlds/test.c
@@ -2,38 +2,65 @@
const struct roomdata_t netcosm_world[] = {
{
- "starting_room",
- "Starting Room",
- "You are in the starting room.\nThere are exits to the west and the east.",
- { NONE_N, NONE_NE, "east_room", NONE_SE, NONE_S, NONE_SW, "west_room", NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ "portal_room",
+ "Portal Room",
+ "You stand in the middle of a stone room. In to the east lies a portal to the world. Above it, there is a sign that reads `Alacron, 238 A.B.A.`.",
+ { NONE_N, NONE_NE, "world_start", NONE_SE, NONE_S, NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, "world_start", NONE_OT },
NULL,
NULL,
NULL,
- NULL
},
{
- "west_room",
- "West Room",
- "You are in the west room.\nThere is an exit to the east.",
- { NONE_N, NONE_NE, "starting_room", NONE_SE, NONE_S, NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ "world_start",
+ "Beride Town Square",
+ "You are in the Beride town square. All around you there are people hurrying to get along. To the north stands a statue of the late King Ajax IV. There are exits in all four directions.",
+ { "beride_square_n_statue", NONE_NE, "beride_square_e", NONE_SE, "beride_square_s", NONE_SW, "beride_square_w", NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
NULL,
NULL,
NULL,
- NULL
},
{
- "east_room",
- "East Room",
- "You are in the east room.\nThere is an exit to the west.",
- { NONE_N, NONE_NE, NONE_E, NONE_SE, NONE_S, NONE_SW, "starting_room", NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ "beride_square_n_statue",
+ "King Ajax IV Statue",
+ "Your path is blocked by an enormous bronze statue. A plaque on the pedestal reads,\n\nKing Ajax IV\n\n182 - 238 A.B.A. To the south is the Beride Town Square.",
+ { NONE_N, NONE_NE, NONE_E, NONE_SE, "world_start", NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
NULL,
NULL,
NULL,
+ },
+
+ {
+ "beride_square_e",
+ "Bottomless Pit",
+ "You take a step onto what seems to be solid rock, but your foot unexplicably slips through it, leading you to lose your balance and slip into the bottomless abyss...",
+ { NONE_N, NONE_NE, NONE_E, NONE_SE, NONE_S, NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ NULL,
+ NULL,
+ NULL,
+ },
+
+ {
+ "beride_square_w",
+ "Bottomless Pit",
+ "You take a step onto what seems to be solid rock, but your foot unexplicably slips through it, leading you to lose your balance and slip into the bottomless abyss...",
+ { NONE_N, NONE_NE, NONE_E, NONE_SE, NONE_S, NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ NULL,
+ NULL,
+ NULL,
+ },
+
+ {
+ "beride_square_s",
+ "Bottomless Pit",
+ "You take a step onto what seems to be solid rock, but your foot unexplicably slips through it, leading you to lose your balance and slip into the bottomless abyss...",
+ { NONE_N, NONE_NE, NONE_E, NONE_SE, NONE_S, NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ NULL,
+ NULL,
NULL,
},
};
const size_t netcosm_world_sz = ARRAYLEN(netcosm_world);
-const char *netcosm_world_name = "Test World 1.1";
+const char *netcosm_world_name = "Alacron 0.1";