/* * Copyright (c) 1991-1994 Sony Corporation * Copyright (c) 1996 Hidekazu Kuroki * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL SONY CORPORATION BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * Except as contained in this notice, the name of Sony Corporation * shall not be used in advertising or otherwise to promote the sale, use * or other dealings in this Software without prior written authorization * from Sony Corporation. * */ /* * $SonyRCSfile: setup.c,v $ * $SonyRevision: 1.3 $ * $SonyDate: 1994/12/09 11:27:07 $ * * $Id$ */ #include "sj_sysvdef.h" #include #include #include #include #include #include #include #include #include "sj_typedef.h" #include "sj_const.h" #include "sj_var.h" #include "sj_dict.h" #include "sj_struct.h" #include "sj_rename.h" #include "Const.h" #include "Struct.h" #include "sj_global.h" #include "kanakan.h" #define NO_GET_INT #include "server.h" typedef struct strlist { u_char *str1; u_char *str2; struct strlist *link; } StrList; char program_name [PathNameLen]; char runcmd_file [PathNameLen]; char *debug_file = NULL; int debug_level = -1; int fork_flag = -1; int max_client = -1; char *dict_dir = NULL; StrList *read_dict = NULL; StrList *open_dict = NULL; char *error_file = NULL; char *log_file = NULL; char *port_name = NULL; #ifdef TLI char *port_number = NULL; #else int port_number = -1; #endif char *socket_name = NULL; #ifdef LOCK_FILE char *lock_file = NULL; #endif int dir_mode = -1; int file_mode = S_IRUSR|S_IWUSR; StrList *allow_user = NULL; #ifdef TLI char *proto_name = NULL; #endif static int line_number; #ifdef OLD #else /* !OLD */ void RcError(char* p) { fprintf(stderr, "%s: \"%s\", line %d: %s\r\n", program_name, runcmd_file, line_number, p); fflush(stderr); exit(1); } void RcWarning(char* p) { fprintf(stderr, "%s: warning: \"%s\", line %d: %s\r\n", program_name, runcmd_file, line_number, p); fflush(stderr); } #endif /* !OLD */ static int cmpstr(u_char* src, u_char* dst) { int flg; int c; flg = (isupper(*src)) ? -1 : 0; while (*src) { c = flg ? *dst : (isupper(*dst) ? tolower(*dst) : *dst); if (*src != c) return -1; src += 1; dst += 1; } if (*dst) return -1; return 0; } static u_char *get_str(p, pv_dst) u_char *p; void *pv_dst; { char **dst; dst = pv_dst; if (!*dst) { *dst = malloc(strlen((char *)p) + 1); if (!*dst) RcError("no more memory"); strcpy(*dst, (char *)p); } while (*p++) ; return p; } static u_char *get_int(p, pv_dst) u_char *p; void *pv_dst; { register char *fmt; int *dst; dst = pv_dst; fmt = (*p == '0') ? "%o" : "%d"; if (sscanf((char *)p, fmt, dst) != 1) RcError("bad integer"); while (*p++) ; return p; } static u_char *get_flag(p, pv_dst) u_char *p; void *pv_dst; { int *dst; dst = pv_dst; if (sscanf((char *)p, "%d", dst) == 1) ; else if (!cmpstr("on", p)) *dst = -1; else if (!cmpstr("off", p)) *dst = 0; else RcError("bad flag"); while (*p++) ; return p; } static u_char* get_list(u_char* p, StrList** dst) { StrList *s1, *s2; if (*p) { s1 = (StrList *)malloc(sizeof(StrList)); if (!s1) RcError("no more memory"); s1 -> link = NULL; s1 -> str1 = (u_char *)malloc(strlen((char *)p) + 1); if (!(s1 -> str1)) RcError("no more memory"); strcpy((char *)s1 -> str1, (char *)p); while (*p++) ; if (*p) { s1 -> str2 = (u_char *)malloc(strlen((char *)p) + 1); if (!(s1 -> str2)) RcError("no more memory"); strcpy((char *)s1 -> str2, (char *)p); while (*p++) ; } else s1 -> str2 = NULL; if (*dst) { for (s2 = *dst ; s2 -> link ; s2 = s2 -> link) ; s2 -> link = s1; } else *dst = s1; } return p; } struct optlist { char *optname; u_char *(*optfunc)(); void *optarg; } option[] = { /* * Add option flag. * Because They are lacked in here. See document. * Patched by Hidekazu Kuroki(hidekazu@cs.titech.ac.jp) 1996/8/10 */ "DebugOut", get_str, &debug_file, "debugout", get_str, &debug_file, "DebugLevel", get_int, &debug_level, "debuglevel", get_int, &debug_level, "ForkFlag", get_flag, &fork_flag, "forkflag", get_flag, &fork_flag, "PortName", get_str, &port_name, "portname", get_str, &port_name, #ifdef TLI "PortNumber", get_str, &port_number, "portnumber", get_str, &port_number, "ProtoName", get_str, &proto_name, "protoname", get_str, &proto_name, #else "PortNumber", get_int, &port_number, "portnumber", get_int, &port_number, #endif "SocketName", get_str, &socket_name, "socketname", get_str, &socket_name, #ifdef LOCK_FILE "LockFile", get_str, &lock_file; "lockfile", get_str, &lock_file; #endif "MaxClient", get_int, &max_client, "maxclient", get_int, &max_client, "DictDir", get_str, &dict_dir, "dictdir", get_str, &dict_dir, "ReadDict", get_list, &read_dict, "readdict", get_list, &read_dict, "OpenDict", get_list, &open_dict, "opendict", get_list, &open_dict, "ErrorOut", get_str, &error_file, "errorout", get_str, &error_file, "LogOut", get_str, &log_file, "logout", get_str, &log_file, "DirMode", get_int, &dir_mode, "dirmode", get_int, &dir_mode, "FileMode", get_int, &file_mode, "filemode", get_int, &file_mode, "AllowUser", get_list, &allow_user, "allowuser", get_list, &allow_user, 0, 0, 0 }; static int skip_blank(fp) FILE *fp; { register int c; c = getc(fp); while (c == ' ' || c == '\t') c = getc(fp); return c; } static int skip_line(fp) FILE *fp; { register int c; c = getc(fp); while (c != '\n' && c != EOF) c = getc(fp); return c; } static readln(fp, p, len) FILE *fp; char *p; int len; { int c; int quote = EOF; int flg = 0; c = skip_blank(fp); while (c != '\n' && c != EOF) { if (c == '\\') { if ((c = getc(fp)) == EOF) break; if (c == '\n') { line_number++; c = getc(fp); continue; } switch (c) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'r': c = '\r'; break; default: break; } } else if (c == '^') { c = getc(fp); if (c < '@' || '_' < c) { ungetc(c, fp); c = '^'; } else c -= '@'; } else if (c == quote) { quote = EOF; c = getc(fp); continue; } else if (quote != EOF) ; else if (c == '\'' || c == '"') { quote = c; c = getc(fp); continue; } else if (c == '#') { len -= 1; *p++ = 0; flg = 0; c = skip_line(fp); continue; } else if (c == ' ' || c == '\t') { len -= 1; *p++ = 0; flg = 0; c = skip_blank(fp); continue; } if (len > 2) { len -= 1; *p++ = c; flg = -1; } c = getc(fp); } line_number++; if (flg) *p++ = 0; *p++ = 0; return c; } int read_line(FILE* fp, char* buf, int len) { int flg; do { flg = readln(fp, buf, len); if (*buf) return 0; } while (flg != EOF); return EOF; } void read_runcmd(void) { FILE *fp; u_char buf[BUFSIZ]; struct optlist *opt; u_char *p; if (!(fp = fopen(runcmd_file, "r"))) { warning_out("Can't open run-command file \"%s\"", runcmd_file); return; } line_number = 0; while (read_line(fp, buf, sizeof(buf)) != EOF) { for (opt = option ; (p = (u_char *)opt -> optname) != NULL ; opt++) if (!cmpstr(p, buf)) break; if (p) { p = buf; while (*p++) ; p = (*opt->optfunc)(p, opt->optarg); } else RcError("undefined option"); if (*p) RcError("too many argment"); } fclose(fp); } static void set_defstr(char** d, char* s) { if (*d == NULL && s) { *d = malloc(strlen(s) + 1); if (!*d) error_out("failed at memory allocation"); strcpy(*d, s); } } static void set_defint(int* d, int s) { if (*d < 0) *d = s; } void set_default(void) { set_defstr(&debug_file, DebugOutFile); set_defstr(&error_file, ErrorOutFile); set_defstr(&dict_dir, DictRootDir); set_defstr(&log_file, LogOutFile); set_defstr(&port_name, PortName); set_defstr(&socket_name, SocketName); #ifdef LOCK_FILE set_defstr(&lock_file, LockFile); #endif #ifdef TLI set_defstr(&proto_name, ProtoName); #endif set_defint(&debug_level, DebugLevel); set_defint(&fork_flag, ForkFlag); set_defint(&max_client, MaxClientNum); #ifdef TLI set_defstr(&port_number, PortNumber); #else set_defint(&port_number, PortNumber); #endif set_defint(&dir_mode, DirectryMode); set_defint(&file_mode, DictFileMode); } void parse_arg(int argc, char** argv) { int c; int errflg = 0; char *p; size_t ret; extern char *optarg, *strrchr(); extern int optind; p = (p = strrchr(argv[0], '/')) ? p + 1 : argv[0]; strlcpy(program_name, p, sizeof(program_name)); strlcpy(runcmd_file, RunCmdFile, sizeof(runcmd_file)); while ((c = getopt(argc, argv, "f:")) != EOF) { switch (c) { case 'f': ret = strlcpy(runcmd_file, optarg, sizeof(runcmd_file)); if (ret > sizeof(runcmd_file)) errflg++; break; case '?': default: errflg++; break; } } if (errflg || optind < argc) { fprintf(stderr, "Usage: %s [-f RunCmdFile]\n", program_name); exit(1); } } void preload_dict(void) { StrList *p; char filename[PathNameLen]; work_base = (Global *)malloc(sizeof(Global)); if (!work_base) { warning_out("can't load default dictionary(not enough memory)"); return; } for (p = read_dict ; p ; p = p -> link) { strncpy(filename, (char *)p -> str1, sizeof(filename)); filename[sizeof(filename) - 1] = '\0'; if (make_full_path(filename)) warning_out("too long filename \"%s\"", p -> str1); else if (opendict(filename, p -> str2)) logging_out("load dictionary \"%s\"", filename); else warning_out("can't open dictionary \"%s\"", filename); } free(work_base); } void preopen_dict(void) { StrList *p; char filename[PathNameLen]; DICT *dict; DICTL *dictl; work_base = global_work_base = (Global *)malloc(sizeof(Global)); if (!work_base) { warning_out("can't open default dictionary(not enough memory)"); return; } memset(work_base, 0, sizeof(Global)); for (p = open_dict ; p ; p = p -> link) { strncpy(filename, p -> str1, sizeof(filename)); filename[sizeof(filename) - 1] = '\0'; if (make_full_path(filename)) warning_out("too long filename \"%s\"", p -> str1); else if ((dict = (DICT *)opendict(filename, p -> str2)) != NULL) { logging_out("open dictionary \"%s\"", filename); if ((dictl = (DICTL *)malloc(sizeof *dictl)) == NULL) { closedict((DictFile *)dict); warning_out("can't open dictionary \"%s\"", filename); continue; } dictl -> dict = dict; dictl -> next = dictlist; dictlist = dictl; } else warning_out("can't open dictionary \"%s\"", filename); } } static int str_match(char* s, char* d) { while (*d) { if (*s == '*') { while (*s == '*') s++; if (!*s) return TRUE; while (*d) { if (str_match(s, d)) return TRUE; d++; } return FALSE; } if (*s != '?' && *s != *d) break; s++; d++; } return (!*s) ? TRUE : FALSE; } int check_user(char* user, char* host) { StrList *p; if (!allow_user) return TRUE; for (p = allow_user ; p ; p = p -> link) { if (!str_match(p -> str1, user)) continue; if (p -> str2) if (!str_match(p -> str2, host)) continue; return TRUE; } return FALSE; }