mud/fluffos-2.23-ds03/rc.c
2020-09-06 05:43:07 -07:00

384 lines
11 KiB
C

/*
* rc.c
* description: runtime configuration for lpmud
* author: erikkay@mit.edu
* last modified: July 4, 1994 [robo]
* Mar 26, 1995: edited heavily by Beek
* Aug 29, 1998: modified by Gorta
*/
#include "std.h"
#include "rc.h"
#include "include/runtime_config.h"
#include "main.h"
#define MAX_LINE_LENGTH 120
char *config_str[NUM_CONFIG_STRS];
int config_int[NUM_CONFIG_INTS];
static char *buff;
static int buff_size;
static void read_config_file (FILE *);
static int scan_config_line (const char *, void *, int);
static void config_init (void); /* don't ask */
static void config_init() {
int i;
for (i = 0; i < NUM_CONFIG_INTS; i++) {
config_int[i] = 0;
}
for (i = 0; i < NUM_CONFIG_STRS; i++) {
config_str[i] = 0;
}
}
static void read_config_file (FILE * file)
{
char str[MAX_LINE_LENGTH * 4];
int size = 2, len, tmp;
char *p;
buff_size = MAX_LINE_LENGTH * (NUM_CONFIG_INTS + 1) * (NUM_CONFIG_STRS + 1);
p = buff = CALLOCATE(buff_size, char, TAG_CONFIG, "read_config_file: 1");
*p++ = '\n';
while (1) {
if (fgets(str, MAX_LINE_LENGTH * 4, file) == NULL)
break;
len = strlen(str); /* ACK! */
if (len > MAX_LINE_LENGTH) {
fprintf(stderr, "*Error in config file: line too long:\n%s...\n", str);
exit(-1);
}
if (str[0] != '#' && str[0] != '\n') {
size += len + 1;
if (size > buff_size) {
tmp = p - buff;
buff = RESIZE(buff, buff_size *= 2, char,
TAG_CONFIG, "read_config_file: 2");
p = buff + tmp;
}
strncpy(p, str, len);
p += len;
*p++ = '\n';
}
}
*p = 0;
}
/*
* If the required flag is 0, it will only give a warning if the line is
* missing from the config file. Otherwise, it will give an error and exit
* if the line isn't there.
*/
/* required:
1 : Must have
0 : optional
-1 : warn if missing */
static int scan_config_line (const char * fmt, void * dest, int required)
{
char *tmp, *end;
char missing_line[MAX_LINE_LENGTH];
/* zero the destination. It is either a pointer to an int or a char
buffer, so this will work */
*((int *)dest) = 0;
tmp = buff;
while (tmp) {
while ((tmp = (char *) strchr(tmp, '\n'))) {
if (*(++tmp) == fmt[0]) break;
}
/* don't allow sscanf() to scan to next line for blank entries */
end = (tmp ? strchr(tmp, '\n') : 0);
if (end) *end = '\0';
if (tmp && sscanf(tmp, fmt, dest) == 1) {
if (end) *end = '\n';
break;
}
if (end) *end = '\n';
}
if (!tmp) {
strcpy(missing_line, fmt);
tmp = (char *) strchr(missing_line, ':');
*tmp = '\0';
if (required == -1) {
fprintf(stderr, "*Warning: Missing line in config file:\n\t%s\n",
missing_line);
return 0;
}
if (!required) return 0;
fprintf(stderr, "*Error in config file. Missing line:\n\t%s\n",
missing_line);
exit(-1);
}
return 1;
}
#if 0
static char *process_config_string(char *str) {
char *p = str;
char *q;
int n;
while (*p && isspace(*p))
p++;
n = strlen(p);
if (!n) return alloc_cstring("", "config_file: blank string");
q = p + n - 1;
while (q > p && isspace(*q))
q--;
q[1] = 0;
return alloc_cstring(p, "process_config_string()");
}
#endif
void set_defaults (char * filename)
{
FILE *def;
char defaults[SMALL_STRING_SIZE];
char *p;
char tmp[MAX_LINE_LENGTH];
char kind[MAX_LINE_LENGTH];
int i, port, port_start = 0;
max_string_length = 120; /* needed for string_copy() below */
config_init();
def = fopen(filename, "r");
if (def) {
fprintf(stderr, "using config file: %s\n", filename);
} else {
sprintf(defaults, "%s/%s", CONFIG_FILE_DIR, filename);
def = fopen(defaults, "r");
if (def) {
fprintf(stderr, "using config file: %s\n", defaults);
}
}
if (!def) {
fprintf(stderr, "*Error: couldn't find or open config file: '%s'\n", filename);
exit(-1);
}
read_config_file(def);
scan_config_line("global include file : %[^\n]", tmp, 0);
p = CONFIG_STR(__GLOBAL_INCLUDE_FILE__) = alloc_cstring(tmp, "config file: gif");
/* check if the global include file is quoted */
if (*p && *p != '"' && *p != '<') {
char *ptr;
fprintf(stderr, "Missing '\"' or '<' around global include file name; adding quotes.\n");
for (ptr = p; *ptr; ptr++)
;
ptr[2] = 0;
ptr[1] = '"';
while (ptr > p) {
*ptr = ptr[-1];
ptr--;
}
*p = '"';
}
scan_config_line("name : %[^\n]", tmp, 1);
CONFIG_STR(__MUD_NAME__) = alloc_cstring(tmp, "config file: mn");
scan_config_line("address server ip : %[^\n]", tmp, 0);
CONFIG_STR(__ADDR_SERVER_IP__) = alloc_cstring(tmp, "config file: asi");
scan_config_line("mudlib directory : %[^\n]", tmp, 1);
CONFIG_STR(__MUD_LIB_DIR__) = alloc_cstring(tmp, "config file: mld");
scan_config_line("binary directory : %[^\n]", tmp, 1);
CONFIG_STR(__BIN_DIR__) = alloc_cstring(tmp, "config file: bd");
scan_config_line("log directory : %[^\n]", tmp, 1);
CONFIG_STR(__LOG_DIR__) = alloc_cstring(tmp, "config file: ld");
scan_config_line("include directories : %[^\n]", tmp, 1);
CONFIG_STR(__INCLUDE_DIRS__) = alloc_cstring(tmp, "config file: id");
scan_config_line("master file : %[^\n]", tmp, 1);
CONFIG_STR(__MASTER_FILE__) = alloc_cstring(tmp, "config file: mf");
scan_config_line("simulated efun file : %[^\n]", tmp, 0);
CONFIG_STR(__SIMUL_EFUN_FILE__) = alloc_cstring(tmp, "config file: sef");
scan_config_line("swap file : %[^\n]", tmp, 1);
CONFIG_STR(__SWAP_FILE__) = alloc_cstring(tmp, "config file: sf");
scan_config_line("debug log file : %[^\n]", tmp, -1);
CONFIG_STR(__DEBUG_LOG_FILE__) = alloc_cstring(tmp, "config file: dlf");
scan_config_line("default error message : %[^\n]", tmp, 0);
CONFIG_STR(__DEFAULT_ERROR_MESSAGE__) = alloc_cstring(tmp, "config file: dem");
scan_config_line("default fail message : %[^\n]", tmp, 0);
CONFIG_STR(__DEFAULT_FAIL_MESSAGE__) = alloc_cstring(tmp, "config file: dfm");
scan_config_line("mud ip : %[^\n]", tmp, 0);
CONFIG_STR(__MUD_IP__) = alloc_cstring(tmp, "config file: mi");
if (scan_config_line("fd6 kind : %[^\n]", tmp, 0)) {
if (!strcasecmp(tmp, "telnet"))
FD6_KIND = PORT_TELNET;
else if (!strcasecmp(tmp, "mud"))
FD6_KIND = PORT_MUD;
else if (!strcasecmp(tmp, "ascii"))
FD6_KIND = PORT_ASCII;
else if (!strcasecmp(tmp, "binary"))
FD6_KIND = PORT_BINARY;
else {
fprintf(stderr, "Unknown port type for fd6 kind. fd6 support disabled.\n");
FD6_KIND = PORT_UNDEFINED;
}
} else {
FD6_KIND = PORT_UNDEFINED;
}
if (scan_config_line("port number : %d\n", &CONFIG_INT(__MUD_PORT__), 0)) {
external_port[0].port = PORTNO;
external_port[0].kind = PORT_TELNET;
port_start = 1;
}
scan_config_line("address server port : %d\n",
&CONFIG_INT(__ADDR_SERVER_PORT__), 0);
scan_config_line("fd6 port : %d\n", &CONFIG_INT(__FD6_PORT__), 0);
scan_config_line("time to clean up : %d\n",
&CONFIG_INT(__TIME_TO_CLEAN_UP__), 1);
scan_config_line("time to reset : %d\n",
&CONFIG_INT(__TIME_TO_RESET__), 1);
scan_config_line("time to swap : %d\n",
&CONFIG_INT(__TIME_TO_SWAP__), 1);
#if 0
/*
* not currently used...see options.h
*/
scan_config_line("evaluator stack size : %d\n",
&CONFIG_INT(__EVALUATOR_STACK_SIZE__), 0);
scan_config_line("maximum local variables : %d\n",
&CONFIG_INT(__MAX_LOCAL_VARIABLES__), 0);
scan_config_line("maximum call depth : %d\n",
&CONFIG_INT(__MAX_CALL_DEPTH__), 0);
scan_config_line("living hash table size : %d\n",
&CONFIG_INT(__LIVING_HASH_TABLE_SIZE__), 0);
#endif
scan_config_line("inherit chain size : %d\n",
&CONFIG_INT(__INHERIT_CHAIN_SIZE__), 1);
scan_config_line("maximum evaluation cost : %d\n",
&CONFIG_INT(__MAX_EVAL_COST__), 1);
scan_config_line("maximum array size : %d\n",
&CONFIG_INT(__MAX_ARRAY_SIZE__), 1);
#ifndef NO_BUFFER_TYPE
scan_config_line("maximum buffer size : %d\n",
&CONFIG_INT(__MAX_BUFFER_SIZE__), 1);
#endif
scan_config_line("maximum mapping size : %d\n",
&CONFIG_INT(__MAX_MAPPING_SIZE__), 1);
scan_config_line("maximum string length : %d\n",
&CONFIG_INT(__MAX_STRING_LENGTH__), 1);
scan_config_line("maximum bits in a bitfield : %d\n",
&CONFIG_INT(__MAX_BITFIELD_BITS__), 1);
scan_config_line("maximum byte transfer : %d\n",
&CONFIG_INT(__MAX_BYTE_TRANSFER__), 1);
scan_config_line("maximum read file size : %d\n",
&CONFIG_INT(__MAX_READ_FILE_SIZE__), 1);
scan_config_line("reserved size : %d\n",
&CONFIG_INT(__RESERVED_MEM_SIZE__), 0);
scan_config_line("hash table size : %d\n",
&CONFIG_INT(__SHARED_STRING_HASH_TABLE_SIZE__), 1);
scan_config_line("object table size : %d\n",
&CONFIG_INT(__OBJECT_HASH_TABLE_SIZE__), 1);
/* check for ports */
if (port_start == 1) {
if (scan_config_line("external_port_1 : %[^\n]", tmp, 0)) {
int port = CONFIG_INT(__MUD_PORT__);
fprintf(stderr, "Warning: external_port_1 already defined to be 'telnet %i' by the line\n 'port number : %i'; ignoring the line 'external_port_1 : %s'\n", port, port, tmp);
}
}
for (i = port_start; i < 5; i++) {
external_port[i].kind = 0;
external_port[i].fd = -1;
sprintf(kind, "external_port_%i : %%[^\n]", i + 1);
if (scan_config_line(kind, tmp, 0)) {
if (sscanf(tmp, "%s %d", kind, &port) == 2) {
external_port[i].port = port;
if (!strcmp(kind, "telnet"))
external_port[i].kind = PORT_TELNET;
else
if (!strcmp(kind, "binary")) {
#ifdef NO_BUFFER_TYPE
fprintf(stderr, "binary ports unavailable with NO_BUFFER_TYPE defined.\n");
exit(-1);
#endif
external_port[i].kind = PORT_BINARY;
} else
if (!strcmp(kind, "ascii"))
external_port[i].kind = PORT_ASCII;
else
if (!strcmp(kind, "MUD"))
external_port[i].kind = PORT_MUD;
else
{
fprintf(stderr, "Unknown kind of external port: %s\n",
kind);
exit(-1);
}
} else {
fprintf(stderr, "Syntax error in port specification\n");
exit(-1);
}
}
}
#ifdef PACKAGE_EXTERNAL
/* check for commands */
for (i = 0; i < NUM_EXTERNAL_CMDS; i++) {
sprintf(kind, "external_cmd_%i : %%[^\n]", i + 1);
if (scan_config_line(kind, tmp, 0))
external_cmd[i] = alloc_cstring(tmp, "external cmd");
else
external_cmd[i] = 0;
}
#endif
FREE(buff);
fclose(def);
/*
* from options.h
*/
config_int[__EVALUATOR_STACK_SIZE__ - BASE_CONFIG_INT] = CFG_EVALUATOR_STACK_SIZE;
config_int[__MAX_LOCAL_VARIABLES__ - BASE_CONFIG_INT] = CFG_MAX_LOCAL_VARIABLES;
config_int[__MAX_CALL_DEPTH__ - BASE_CONFIG_INT] = CFG_MAX_CALL_DEPTH;
config_int[__LIVING_HASH_TABLE_SIZE__ - BASE_CONFIG_INT] = CFG_LIVING_HASH_SIZE;
}
int get_config_item (svalue_t * res, svalue_t * arg)
{
int num;
num = arg->u.number;
if (num < 0 || num >= RUNTIME_CONFIG_NEXT) {
return 0;
}
if (num >= BASE_CONFIG_INT) {
res->type = T_NUMBER;
res->u.number = config_int[num - BASE_CONFIG_INT];
} else {
if(!config_str[num]) //obsolete value, less muds break if we don't renumber!
return 0;
res->type = T_STRING;
res->subtype = STRING_CONSTANT;
res->u.string = config_str[num];
}
return 1;
}