/*********************************************************************\ * Copyright (c) 2003 by Radim Kolar (hsn@cybermail.net) * * Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) * * * * You may copy or modify this file in any manner you wish, provided * * that this notice is always included, and that you hold the author * * harmless for any loss or damage resulting from the installation or * * use of this software. * \*********************************************************************/ #include "tweak.h" #include #ifdef STDC_HEADERS #include #endif #include #include "server_def.h" #include "s_extern.h" #include "co_extern.h" #include "my-string.h" static int conf_read = 0; int daemonize = 1; int use_prebuild_dirlists = #ifdef OS_CYGWIN 0; #else 1; #endif int grab_enabled = 1; int ver_enabled = 1; int read_only = 0; unsigned short udp_port = 21; int dbug = 0; uid_t run_uid = 0; gid_t run_gid = 0; int priv_mode = 0; int no_unnamed = 0; int logging = 0; int use_access_files = 1; int use_directory_mtime = #ifdef OS_CYGWIN 0; #else 1; #endif unsigned int maxthcallowed = 0; unsigned short packetsize = UBUF_SPACE; time_t retry_timeout = 3; time_t session_timeout = 60; time_t stat_cache_timeout = 25; char *logname = NULL; char *tlogname = NULL; char *dumpname = NULL; char *home_dir = NULL; char *tmp_dir = NULL; int homedir_restricted = 1; int permit_passwordless_owners = 0; char *readme_file = NULL; unsigned int dir_cache_limit = DEFAULT_DIRLISTCACHE_SIZE; unsigned int stat_cache_limit = DEFAULT_DIRSTATCACHE_SIZE; mode_t upload_umask = 0033; mode_t system_umask = 0077; /**************************************************************************** * Set this value to the maximum number of open files you wish your system * * to keep around at any given time. The smaller this number is, the more * * likely the server is to be opening and closing files, but the less file * * descriptors need to be taken up by the server itself * * Five seems to work reasonably well on my system * ****************************************************************************/ unsigned int fp_cache_limit=10; static void log_set PROTO2(int, flag, int, neg) { if(neg) logging &= ~flag; else logging |= flag; } static int get_boolean PROTO1(const char, *q) { if(strcmp(q, "0") == 0) return 0; else if(strcasecmp(q, "no") == 0) return 0; else if(strcasecmp(q, "off") == 0) return 0; else if(strcasecmp(q, "on") == 0) return 1; else if(strcasecmp(q, "yes") == 0) return 1; else if(strcmp(q, "1") == 0) return 1; else fprintf(stderr,"Bogus boolean value '%s'. Exiting.\n",q); exit(1); return -1; } static void read_configuration PROTO1(const char *, name) { FILE *fp; char buf[1024], *p, *q; fp = fopen(name,"r"); if(!fp) { fprintf(stderr, "Warning: Unable to open configuration file: %s.\n", name); return; } while(fgets(buf, sizeof(buf), fp)) { if(buf[0] == '\n' || buf[0] == '#') continue; buf[strlen(buf)-1] = '\0'; /* strip off the newline */ p = buf; while(*p && isspace(*p)) p++; q = p; while(*q && !isspace(*q)) q++; if(!*p || !*q) { fprintf(stderr,"Bogus line in configuration file: %s. Exiting.\n",name); exit(1); } *q = '\0'; q++; if(strcasecmp(p, "conf") == 0) { if(conf_read) { fprintf(stderr, "No recursion of conf commands allowed. Skipping.\n"); continue; } conf_read = 1; fclose(fp); read_configuration(q); return; } else if(strcasecmp(p, "readme") == 0) { if(readme_file) free(readme_file); readme_file = strdup(q); } else if(strcasecmp(p, "homedir") == 0) { if(home_dir) free(home_dir); home_dir = strdup(q); } else if(strcasecmp(p, "tmpdir") == 0) { if(tmp_dir) free(tmp_dir); tmp_dir = strdup(q); } else if(strcasecmp(p, "logfile") == 0) { if(logname) free(logname); logname = strdup(q); } else if(strcasecmp(p, "xferlog") == 0) { if(tlogname) free(tlogname); tlogname = strdup(q); } else if(strcasecmp(p, "dumpfile") == 0) { if(dumpname) free(dumpname); dumpname = strdup(q); } else if(strcasecmp(p, "host") == 0) { add_ipline(q,&iptab); } else if(strcasecmp(p, "log") == 0) { char *r; int neg; do { /* skip to next token */ r = q; while(*r && !isspace(*r)) r++; if (*r) { *r++ = 0 ; while(*r && isspace(*r)) r++; } if(strcasecmp(q, "none") == 0) { logging = L_NONE; break; } else if(strcasecmp(q, "all") == 0) { logging = L_ALL; } else { if(*q == '!') { neg = 1; q++;} else neg = 0; if(strcasecmp(q, "transfers") == 0) { log_set(L_GETFILE, neg); log_set(L_INSTALL, neg); } else if(strcasecmp(q, "version") == 0) log_set(L_VER, neg); else if(strcasecmp(q, "errors") == 0) log_set(L_ERR, neg); else if(strcasecmp(q, "getdir") == 0) log_set(L_GETDIR, neg); else if(strcasecmp(q, "getfile") == 0) log_set(L_GETFILE, neg); else if(strcasecmp(q, "upload") == 0) log_set(L_UPLOAD, neg); else if(strcasecmp(q, "install") == 0) log_set(L_INSTALL, neg); else if(strcasecmp(q, "delfile") == 0) log_set(L_DELFILE, neg); else if(strcasecmp(q, "deldir") == 0) log_set(L_DELDIR, neg); else if(strcasecmp(q, "setpro") == 0) log_set(L_SETPRO, neg); else if(strcasecmp(q, "getpro") == 0) log_set(L_GETPRO, neg); else if(strcasecmp(q, "makedir") == 0) log_set(L_MAKEDIR, neg); else if(strcasecmp(q, "grabfile") == 0) log_set(L_GRABFILE, neg); else if(strcasecmp(q, "readonly") == 0) log_set(L_RDONLY, neg); else if(strcasecmp(q, "stat") == 0) log_set(L_STAT, neg); else if(strcasecmp(q, "rename") == 0) log_set(L_RENAME, neg); } q = r; } while (*q); } else if(strcasecmp(p, "port") == 0) { udp_port = atoi(q); } else if(strcasecmp(p, "packetsize") == 0) { packetsize = atoi(q); if(packetsize <= 64 || packetsize > UBUF_SPACE ) packetsize = UBUF_SPACE; } else if(strcasecmp(p, "filecache") == 0) { fp_cache_limit = atoi(q); if(fp_cache_limit < 10 ) fp_cache_limit = 10; } else if(strcasecmp(p, "dircache") == 0) { dir_cache_limit = atoi(q); if( dir_cache_limit < 16 ) dir_cache_limit = DEFAULT_DIRLISTCACHE_SIZE; } else if(strcasecmp(p, "statcache") == 0) { stat_cache_limit = atoi(q); if( stat_cache_limit < 10 ) stat_cache_limit = DEFAULT_DIRSTATCACHE_SIZE; } else if(strcasecmp(p, "retry") == 0) { retry_timeout = atoi(q); if(retry_timeout < 1 ) retry_timeout = 3; } else if(strcasecmp(p, "timeout") == 0) { session_timeout = atoi(q); if(session_timeout <= 5 ) session_timeout = 60; } else if(strcasecmp(p, "statcache_timeout") == 0) { session_timeout = atoi(q); if(stat_cache_timeout <= 0 ) stat_cache_timeout = 20; } else if(strcasecmp(p, "thruput") == 0) { if(strcasecmp(q, "off") == 0) maxthcallowed = 0; else maxthcallowed = atoi(q); } else if(strcasecmp(p, "setuid") == 0) { if(strcasecmp(q, "off") == 0) run_uid = 0; else run_uid = atoi(q); } else if(strcasecmp(p, "setgid") == 0) { if(strcasecmp(q, "off") == 0) run_gid = 0; else run_gid = atoi(q); } else if(strcasecmp(p, "umask") == 0) { upload_umask = strtol(q,NULL,8); } else if(strcasecmp(p, "serverumask") == 0) { system_umask = strtol(q,NULL,8); } else if(strcasecmp(p, "daemonize") == 0) { daemonize = get_boolean(q); } else if(strcasecmp(p, "debug") == 0) { dbug = get_boolean(q); } else if(strcasecmp(p, "restricted") == 0) { priv_mode = get_boolean(q); } else if(strcasecmp(p, "homedir_restricted") == 0) { homedir_restricted = get_boolean(q); } else if(strcasecmp(p, "grabcommand") == 0) { grab_enabled = get_boolean(q); } else if(strcasecmp(p, "vercommand") == 0) { ver_enabled = get_boolean(q); } else if(strcasecmp(p, "permit_passwordless_owners") == 0) { permit_passwordless_owners = get_boolean(q); } else if(strcasecmp(p, "reverse_name") == 0) { no_unnamed = get_boolean(q); } else if(strcasecmp(p, "use_prebuild_dirlists") == 0) { use_prebuild_dirlists = get_boolean(q); } else if(strcasecmp(p, "use_access_files") == 0) { use_access_files = get_boolean(q); } else if(strcasecmp(p, "use_directory_mtime") == 0) { use_directory_mtime = get_boolean(q); } else if(strcasecmp(p, "read_only") == 0) { read_only = get_boolean(q); } else { fprintf(stderr, "Invalid command (%s) in config file, skipping.\n", p); } } fclose(fp); } void load_configuration PROTO1(const char *,config_file) { if(config_file == NULL) return; /* destroy_configuration(); */ /* destroying iptab should be enough */ if(iptab) { free_ip_table(iptab); iptab = NULL; } read_configuration(config_file); } void destroy_configuration PROTO0((void)) { if(readme_file) free(readme_file); if(home_dir) free(home_dir); if(logname) free(logname); if(tlogname) free(tlogname); if(tmp_dir) free(tmp_dir); if(dumpname) free(dumpname); if(iptab) free_ip_table(iptab); readme_file = home_dir = logname = tmp_dir = dumpname = NULL; iptab = NULL; }