384 lines
11 KiB
C
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;
|
|
}
|