sj3/setup.c

557 lines
12 KiB
C

/*
* Copyright (c) 1991-1994 Sony Corporation
* Copyright (c) 1996 Hidekazu Kuroki <hidekazu at cs.titech.ac.jp>
*
* 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.
*
*/
#include "sj_sysvdef.h"
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <unistd.h>
#include "sj_typedef.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 {
unsigned char* str1;
unsigned 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(unsigned char* src, unsigned 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 unsigned char* get_str(p, pv_dst)
unsigned 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 unsigned char* get_int(p, pv_dst)
unsigned char* p;
void* pv_dst;
{
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 unsigned char* get_flag(p, pv_dst)
unsigned 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 unsigned char*
get_list(unsigned 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 = (unsigned 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 = (unsigned 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;
unsigned 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;
{
int c;
c = getc(fp);
while(c == ' ' || c == '\t') c = getc(fp);
return c;
}
static int skip_line(fp)
FILE* fp;
{
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;
unsigned char buf[BUFSIZ];
struct optlist* opt;
unsigned 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 = (unsigned 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;
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;
}