#include <stdio.h> #include <string.h> #include <ctype.h> #include "externs.h" #include "config.h" struct global_config_struct config; struct config_types { char *name; char **sptr; int *nptr; char *sdefault; int ndefault; bool type; /* 0 = char *, 1 = int */ } configs[] = { { "inet_port", NULL, &config.inet_port, NULL, 4201, 1 }, { "root", NULL, &config.root, NULL, 1, 1 }, { "connect_channel", &config.connect_channel, NULL, "Connections", 0, 0 }, { "adm_connect_channel", &config.adm_connect_channel, NULL, "*connect", 0, 0 }, { "maze_name", &config.maze_name, NULL, "TinyMAZE", 0, 0 }, { "auto_create", NULL, &config.auto_create, NULL, 0, 1 }, { "player_start", NULL, &config.player_start, NULL, 0, 1 }, { "guest_start", NULL, &config.guest_start, NULL, 0, 1 }, { "currency_name", &config.currency_name, NULL, "Credit", 0, 0 }, { "currency_plural", &config.currency_plural, NULL, "Credits", 0, 0 }, { "initial_wealth", NULL, &config.initial_wealth, NULL, 0, 1 }, { "default_quota", NULL, &config.default_quota, NULL, 0, 1 }, { "default_channel_quota", NULL, &config.default_channel_quota, NULL, 0, 1 }, { "max_guests", NULL, &config.max_guests, NULL, 0, 1 }, { "guest_prefix", &config.guest_prefix, NULL, "Guest", 0, 0 }, { "guest_description", &config.guest_description, NULL, "Please help me if I need assistance.", 0, 0 }, { "dump_interval", NULL, &config.dump_interval, NULL, 1800, 1 }, { "dbck_interval", NULL, &config.dbck_interval, NULL, 600, 1 }, { "max_output", NULL, &config.max_output, NULL, 16384, 1 }, { "max_input", NULL, &config.max_input, NULL, 1024, 1 }, { "max_server_io", NULL, &config.max_server_io, NULL, 0, 1 }, { "max_player_io", NULL, &config.max_player_io, NULL, 0, 1 }, { "max_users", NULL, &config.max_users, NULL, 50, 1 }, { "max_queue", NULL, &config.max_queue, NULL, 100, 1 }, { "db_name", &config.db_name, NULL, "db/mdb", 0, 0 }, { "maildb_name", &config.maildb_name, NULL, "db/maildb", 0, 0 }, { "connect_msg_file", &config.connect_msg_file, NULL, "msgs/connect.txt", 0, 0 }, { "guest_msg_file", &config.guest_msg_file, NULL, "msgs/guest.txt", 0, 0 }, { "leave_msg_file", &config.leave_msg_file, NULL, "msgs/leave.txt", 0, 0 }, { "announce_cost", NULL, &config.announce_cost, NULL, 250, 1 }, { "player_name_limit", NULL, &config.player_name_limit, NULL, 32, 1 }, { "player_alias_limit", NULL, &config.player_alias_limit, NULL, 5, 1 }, { "max_mail_age", NULL, (int *)&config.max_mail_age, NULL, 1800, 1 }, { "old_mail_interval", NULL, &config.old_mail_interval, NULL, 1800, 1 }, { "idle_boot_time", NULL, &config.idle_boot_time, NULL, 900, 1 }, { NULL, NULL, NULL, 0 } }; static void parse_line(char *str, char *setting, char *value) { char buf[4096]; char *b, *s, *v; strcpy(buf, str); *setting = *value = '\0'; for(b = buf;isspace(*b);++b); /* Whole loop */ for(s = setting;*b && !isspace(*b);++b, ++s) *s = *b; *s = '\0'; while(isspace(*b)) b++; strcpy(value, b); v = value+strlen(value); if(v > value) v--; while(v > value && isspace(*v)) v--; *(v+1) = '\0'; } static int set_config(char *setting, char *value) { struct config_types *c; for(c = configs;c->name;c++) if(!string_compare(c->name, setting)) break; if(!c->name) return(0); switch(c->type) { case 0: stack_free(*(c->sptr)); SET(*(c->sptr), value); break; case 1: *(c->nptr) = atoi(value); break; default: return(0); } return(1); } static void init_configs() { struct config_types *c; for(c = configs;c->name;c++) { switch(c->type) { case 0: SET(*(c->sptr), c->sdefault); break; case 1: *(c->nptr) = c->ndefault; break; default: log_error(tprintf("GLOBAL CONFIG ERROR: Unknown type for config: %s", c->name)); exit_nicely(1); } } } void read_global_config_file() { char setting[4096], value[4096]; char *read; FILE *fp; const char *filename = "../config/global_config"; if(!(fp = fopen(filename, "r"))) { log_error(tprintf("Couldn't open \"%s\" for reading!", filename)); exit_nicely(1); } init_configs(); while((read = get_next_line(fp))) { parse_line(read, setting, value); if(!set_config(setting, value)) log_error(tprintf("GLOBAL CONFIG ERROR: Setting: %s, Value: %s", setting, value)); } fclose(fp); } static void show_config_entry(OBJ *player, struct config_types *c) { char buf[4096]; if(c->type == 1) sprintf(buf, "%d", *(c->nptr)); else strcpy(buf, *(c->sptr)); notify(player, tprintf("|+B|%s|+W|: |+C|%s", c->name, buf)); } static void write_config_file(void) { FILE *fp; const char *filename = "../config/global_config"; struct config_types *c; rename(filename, "../config/global_config.old"); if(!(fp = fopen(filename, "w"))) { log_error(tprintf("Couldn't open \"%s\" for writing!", filename)); rename("../config/global_config.old", filename); return; } for(c = &configs[0];c->name;c++) fprintf(fp, "%s %s\n", c->name, (c->type == 1)?tprintf("%d", *(c->nptr)):*(c->sptr)); fclose(fp); } void do_config(OBJ *player, char *arg1, char *arg2) { struct config_types *c, *one = NULL; OBJ *o; if(*arg1) { for(one = &configs[0];one->name;one++) if(!string_compare(one->name, arg1)) break; if(!one->name) { notify(player, tprintf("No such config field: %s", arg1)); return; } } if(!*arg2) /* They're not trying to modify anything */ { if(!one) { for(c = &configs[0];c->name;c++) show_config_entry(player, c); return; } show_config_entry(player, one); return; } if(!power(player, POW_SECURITY)) { notify(player, perm_denied()); return; } if(!one) { notify(player, "Modify which config field?"); return; } if(!strcmp(one->name, "inet_port")) { notify(player, "That config field may not be modified online."); return; } if(one->type == 1) { if(!isdigit(*arg2)) { notify(player, tprintf("Illegal value '%s' for config field '%s'.", arg2, one->name)); return; } *(one->nptr) = atoi(arg2); } else { if(!strcmp(one->name, "guest_prefix")) { for(o = player_list;o;o = o->next) if(Guest(o)) { do_name(root_obj, tprintf("#%d", o->dbref), tprintf("%s%d", arg2, atoi(o->name+strlen(*(one->sptr))))); atr_add(o, "ALIAS", tprintf("%c%s", *arg2, atr_get(o, "ALIAS")+1)); } } stack_free(*(one->sptr)); SET(*(one->sptr), arg2); } write_config_file(); show_config_entry(player, one); log_important(tprintf("Global config for '%s' has been changed to '%s' by %s", one->name, (one->type == 1)?tprintf("%d", *(one->nptr)):*(one->sptr), unparse_object(player, player))); } void free_global_config(void) { struct config_types *c; for(c = &configs[0];c->name;c++) if(c->type == 0) stack_free(*(c->sptr)); }