From 2c83198580a3b28067d74126374091c99eeb1e71 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Fri, 15 Jan 2016 17:25:16 -0500 Subject: refactor headers --- src/auth.c | 6 +- src/auth.h | 2 + src/client.c | 14 +++- src/client.h | 45 ++++++++++++ src/globals.h | 89 +++++++++++++++++++++++ src/hash.c | 6 +- src/netcosm.h | 214 ------------------------------------------------------ src/room.c | 6 +- src/room.h | 88 ++++++++++++++++++++++ src/server.c | 32 +++++++- src/server.h | 47 ++++++++++++ src/server_reqs.c | 6 +- src/telnet.c | 5 +- src/userdb.c | 7 +- src/userdb.h | 28 ++++++- src/util.c | 2 +- src/util.h | 26 +++++++ 17 files changed, 391 insertions(+), 232 deletions(-) create mode 100644 src/client.h create mode 100644 src/globals.h delete mode 100644 src/netcosm.h create mode 100644 src/room.h create mode 100644 src/server.h create mode 100644 src/util.h (limited to 'src') diff --git a/src/auth.c b/src/auth.c index 5e716ac..b5f8942 100644 --- a/src/auth.c +++ b/src/auth.c @@ -16,7 +16,11 @@ * along with this program. If not, see . */ -#include "netcosm.h" +#include "globals.h" + +#include "auth.h" +#include "client.h" +#include "userdb.h" static bool valid_login_name(const char *name); diff --git a/src/auth.h b/src/auth.h index b771152..908d043 100644 --- a/src/auth.h +++ b/src/auth.h @@ -33,6 +33,8 @@ struct authinfo_t { /* makes admin account */ void first_run_setup(void); +struct userdata_t; + /* NULL on failure, user data struct on success */ struct userdata_t *auth_check(const char *user, const char *pass); diff --git a/src/client.c b/src/client.c index 7b4a9cc..37f9c23 100644 --- a/src/client.c +++ b/src/client.c @@ -16,7 +16,15 @@ * along with this program. If not, see . */ -#include "netcosm.h" +#include "globals.h" + +#include "auth.h" +#include "client.h" +#include "hash.h" +#include "server.h" +#include "room.h" +#include "telnet.h" +#include "util.h" static bool admin = false; @@ -178,6 +186,9 @@ void sig_rt_0_handler(int s, siginfo_t *info, void *v) (void) s; (void) v; + if(!are_child) + return; + /* we only listen to requests from our parent */ if(info->si_pid != getppid()) { @@ -212,6 +223,7 @@ void sig_rt_0_handler(int s, siginfo_t *info, void *v) returned_reqdata.boolean = status; if(!status) out("Cannot go that way.\n"); + break; } case REQ_GETUSERDATA: { diff --git a/src/client.h b/src/client.h new file mode 100644 index 0000000..be75c03 --- /dev/null +++ b/src/client.h @@ -0,0 +1,45 @@ +/* + * NetCosm - a MUD server + * Copyright (C) 2016 Franklin Wei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* You should use #pragma once everywhere. */ +#pragma once + +#include "room.h" +#include "userdb.h" + +enum reqdata_typespec { TYPE_NONE = 0, TYPE_USERDATA, TYPE_BOOLEAN } reqdata_type; + +union reqdata_t { + struct userdata_t userdata; + bool boolean; +}; + +extern enum reqdata_typespec reqdata_type; +extern union reqdata_t returned_reqdata; + +/* call from child process ONLY */ +void send_master(unsigned char cmd, const void *data, size_t sz); + +/* the master sends the child SIGRTMIN+0 */ +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); + +/* 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 new file mode 100644 index 0000000..35db514 --- /dev/null +++ b/src/globals.h @@ -0,0 +1,89 @@ +/* + * NetCosm - a MUD server + * Copyright (C) 2016 Franklin Wei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* You should use #pragma once everywhere. */ +#pragma once + +#define _GNU_SOURCE + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* convenience macros */ +#define ARRAYLEN(x) (sizeof(x)/sizeof(x[0])) +#define MAX(a,b) ((a>b)?(a):(b)) +#define MIN(a,b) ((a. */ -#include "netcosm.h" +#include "hash.h" #include #include @@ -83,7 +83,6 @@ void hash_setfreedata_cb(void *ptr, void (*cb)(void *data)) void hash_free(void *ptr) { - sig_debugf("freeing map\n"); if(ptr) { struct hash_map *map = ptr; @@ -95,10 +94,7 @@ void hash_free(void *ptr) struct hash_node *next = node->next; if(map->free_data) - { - debugf("freeing data\n"); map->free_data((void*)node->data); - } if(map->free_key) map->free_key((void*)node->key); free(node); diff --git a/src/netcosm.h b/src/netcosm.h deleted file mode 100644 index 34e2f3d..0000000 --- a/src/netcosm.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * NetCosm - a MUD server - * Copyright (C) 2016 Franklin Wei - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* You should use #pragma once everywhere. */ -#pragma once - -#define _GNU_SOURCE - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define USERFILE "users.dat" -#define WORLDFILE "world.dat" -#define WORLD_MAGIC 0xff467777 -#define MAX_FAILURES 3 -#define NETCOSM_VERSION "0.2" - -#define MAX_NAME_LEN 32 - -#define PRIV_NONE -1 -#define PRIV_USER 0 -#define PRIV_ADMIN 1337 - -/* for convenience when writing world specs */ -#define NONE_N NULL -#define NONE_NE NULL -#define NONE_E NULL -#define NONE_SE NULL -#define NONE_S NULL -#define NONE_SW NULL -#define NONE_W NULL -#define NONE_NW NULL -#define NONE_UP NULL -#define NONE_DN NULL -#define NONE_IN NULL -#define NONE_OT NULL - -/* needs to be less than PIPE_BUF, which is 4096 */ -#define MSG_MAX 2048 - -#define ARRAYLEN(x) (sizeof(x)/sizeof(x[0])) -#define MAX(a,b) ((a>b)?(a):(b)) -#define MIN(a,b) ((a. */ -#include "netcosm.h" +#include "globals.h" + +#include "hash.h" +#include "server.h" +#include "room.h" /* processed world data */ static struct room_t *world; diff --git a/src/room.h b/src/room.h new file mode 100644 index 0000000..ad7898f --- /dev/null +++ b/src/room.h @@ -0,0 +1,88 @@ +/* + * NetCosm - a MUD server + * Copyright (C) 2016 Franklin Wei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +typedef enum room_id { ROOM_NONE = -1 } room_id; + +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 }; + +/* the data we get from a world module */ +struct roomdata_t { + /* the non-const pointers can be modified by the world module */ + const char * const uniq_id; + + /* mutable properties */ + char *name; + char *desc; + + 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; +}; + +struct object_t { + const char *class; + obj_id id; +}; + +struct verb_t { + const char *name; + + /* toks is strtok_r's pointer */ + void (*execute)(const char *toks); +}; + +struct room_t { + room_id id; + struct roomdata_t data; + + room_id adjacent[NUM_DIRECTIONS]; + + /* arrays instead of linked lists because insertion should be rare for these */ + size_t objects_sz; + struct object_t *objects; + + size_t verbs_sz; + struct verb_t *verbs; + + /* linked list for users, random access is rare */ + struct user_t *users; + int num_users; +}; + +/* room/world */ +void world_init(const struct roomdata_t *data, size_t sz, const char *name); +bool world_load(const char *fname, const struct roomdata_t *data, size_t data_sz, const char *world_name); +void world_save(const char *fname); + +struct room_t *room_get(room_id id); +bool room_user_add(room_id id, struct child_data *child); +bool room_user_del(room_id id, struct child_data *child); + +void world_free(void); diff --git a/src/server.c b/src/server.c index b04e7d1..5b963b6 100644 --- a/src/server.c +++ b/src/server.c @@ -16,7 +16,13 @@ * along with this program. If not, see . */ -#include "netcosm.h" +#include "globals.h" + +#include "client.h" +#include "hash.h" +#include "server.h" +#include "userdb.h" +#include "util.h" #define PORT 1234 #define BACKLOG 100 @@ -97,6 +103,21 @@ static void __attribute__((noreturn)) serv_cleanup(void) { sig_debugf("Shutdown server.\n"); + /* kill all our children (usually init claims them and wait()'s + for them, but not always) */ + struct sigaction sa; + sigfillset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGCHLD); + sigaction(SIGCHLD, &sa, NULL); /* kill all children */ + void *ptr = child_map, *save; + do { + struct child_data *child = hash_iterate(ptr, &save, NULL); + if(!child) + break; + ptr = NULL; + kill(child->pid, SIGKILL); + } while(1); + handle_disconnects(); + if(shutdown(server_socket, SHUT_RDWR) > 0) error("shutdown"); @@ -179,6 +200,10 @@ static void check_userfile(void) static void load_worldfile(void) { + extern const struct roomdata_t netcosm_world[]; + extern const size_t netcosm_world_sz; + extern const char *netcosm_world_name; + if(access(WORLDFILE, F_OK) < 0) { world_init(netcosm_world, netcosm_world_sz, netcosm_world_name); @@ -323,6 +348,9 @@ static void new_connection_cb(EV_P_ ev_io *w, int revents) int main(int argc, char *argv[]) { + assert(ev_version_major() == EV_VERSION_MAJOR && + ev_version_minor() >= EV_VERSION_MINOR); + if(argc != 2) port = PORT; else @@ -353,7 +381,7 @@ int main(int argc, char *argv[]) ev_io server_watcher; ev_io_init(&server_watcher, new_connection_cb, server_socket, EV_READ); - //ev_set_priority(&server_watcher, EV_MAXPRI); + ev_set_priority(&server_watcher, EV_MAXPRI); ev_io_start(EV_A_ &server_watcher); ev_loop(loop, 0); diff --git a/src/server.h b/src/server.h new file mode 100644 index 0000000..3117955 --- /dev/null +++ b/src/server.h @@ -0,0 +1,47 @@ +/* + * NetCosm - a MUD server + * Copyright (C) 2016 Franklin Wei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* You should use #pragma once everywhere. */ +#pragma once + +#include +#include +#include + +#include "server_reqs.h" +#include "room.h" + +struct child_data { + pid_t pid; + int readpipe[2]; + int outpipe[2]; + + int state; + room_id room; + char *user; + + ev_io *io_watcher; + ev_child *sigchld_watcher; + struct ev_loop *loop; + + struct in_addr addr; +}; + +extern volatile int num_clients; +extern void *child_map; +extern bool are_child; diff --git a/src/server_reqs.c b/src/server_reqs.c index cdafe7b..fd92b00 100644 --- a/src/server_reqs.c +++ b/src/server_reqs.c @@ -1,4 +1,8 @@ -#include "netcosm.h" +#include "globals.h" + +#include "hash.h" +#include "server.h" +#include "userdb.h" static volatile sig_atomic_t num_acks_wanted, num_acks_recvd, inc_acks = 0; diff --git a/src/telnet.c b/src/telnet.c index 038c54c..9e664ea 100644 --- a/src/telnet.c +++ b/src/telnet.c @@ -16,7 +16,10 @@ * along with this program. If not, see . */ -#include "netcosm.h" +#include "globals.h" + +#include "client.h" +#include "telnet.h" int telnet_handle_command(const unsigned char *buf) { diff --git a/src/userdb.c b/src/userdb.c index ddf1ced..a98a33e 100644 --- a/src/userdb.c +++ b/src/userdb.c @@ -1,4 +1,9 @@ -#include "netcosm.h" +#include "globals.h" + +#include "client.h" +#include "hash.h" +#include "server.h" +#include "userdb.h" static void *map = NULL; static char *db_file = NULL; diff --git a/src/userdb.h b/src/userdb.h index a941e9a..36c4558 100644 --- a/src/userdb.h +++ b/src/userdb.h @@ -1,7 +1,29 @@ +/* + * NetCosm - a MUD server + * Copyright (C) 2016 Franklin Wei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #pragma once -#include "netcosm.h" #include "auth.h" +#include "room.h" + +/*** functions for the master process ONLY ***/ + +typedef enum priv_t { PRIV_NONE = -1, PRIV_USER = 0, PRIV_ADMIN = 1337 } priv_t; struct userdata_t { char username[MAX_NAME_LEN + 1]; @@ -11,12 +33,10 @@ struct userdata_t { /* in hex + NULL terminator */ char passhash[AUTH_HASHLEN * 2 + 1]; - int priv; + priv_t priv; room_id room; }; -/*** functions for the master process ONLY ***/ - /* call before using anything else */ void userdb_init(const char *dbfile); diff --git a/src/util.c b/src/util.c index 103b4f9..2c10eef 100644 --- a/src/util.c +++ b/src/util.c @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#include "netcosm.h" +#include "globals.h" void remove_cruft(char *str) { diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..8cc44d5 --- /dev/null +++ b/src/util.h @@ -0,0 +1,26 @@ +/* + * NetCosm - a MUD server + * Copyright (C) 2016 Franklin Wei + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/* You should use #pragma once everywhere. */ +#pragma once + +/* utility functions */ +void __attribute__((noreturn,format(printf,1,2))) error(const char *fmt, ...); +void debugf_real(const char*, int, const char*, const char *fmt, ...); +void remove_cruft(char*); +void all_upper(char*); -- cgit v1.1