diff options
| author | Franklin Wei <git@fwei.tk> | 2016-01-16 20:05:58 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2016-01-16 20:05:58 -0500 |
| commit | 98896de83ffa7380404e41b6ed80cfc6ba3bf8f0 (patch) | |
| tree | 427f48b92d647c6278df083f86d33a7545710a6c | |
| parent | 056220075ca575c17899abea7b3a2fb55e64b561 (diff) | |
| download | netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.zip netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.tar.gz netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.tar.bz2 netcosm-98896de83ffa7380404e41b6ed80cfc6ba3bf8f0.tar.xz | |
packetized requests
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | src/auth.c | 5 | ||||
| -rw-r--r-- | src/client.c | 216 | ||||
| -rw-r--r-- | src/client.h | 2 | ||||
| -rw-r--r-- | src/globals.h | 6 | ||||
| -rw-r--r-- | src/room.h | 26 | ||||
| -rw-r--r-- | src/server.c | 15 | ||||
| -rw-r--r-- | src/server_reqs.c | 126 | ||||
| -rw-r--r-- | src/server_reqs.h | 1 | ||||
| -rw-r--r-- | src/userdb.c | 1 | ||||
| -rw-r--r-- | src/util.c | 9 | ||||
| -rw-r--r-- | worlds/test.c | 57 |
13 files changed, 262 insertions, 205 deletions
@@ -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 @@ -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 @@ -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 @@ -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; @@ -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"; |