/* * $Id: ftp-main.c,v 1.6.6.1 2003/05/07 11:08:55 mt Exp $ * * Main program of the FTP Proxy * * Author(s): Jens-Gero Boehm * Pieter Hollants * Marius Tomaschewski * Volker Wiegand * * This file is part of the SuSE Proxy Suite * See also http://proxy-suite.suse.de/ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * A history log can be found at the end of this file. */ #ifndef lint static char rcsid[] = "$Id: ftp-main.c,v 1.6.6.1 2003/05/07 11:08:55 mt Exp $"; #endif #include #if defined(STDC_HEADERS) # include # include # include # include # include #endif #if defined(HAVE_UNISTD_H) # include #endif #if defined(TIME_WITH_SYS_TIME) # include # include #else # if defined(HAVE_SYS_TIME_H) # include # else # include # endif #endif #include #include "com-config.h" #include "com-debug.h" #include "com-misc.h" #include "com-socket.h" #include "com-syslog.h" #include "ftp-client.h" #include "ftp-daemon.h" #include "ftp-main.h" /* ------------------------------------------------------------ */ #include "ftp-vers.c" /* We need the version strings */ #define SELECT_TIMEOUT 60 /* Wake up regularly */ #if defined(COMPILE_DEBUG) # define DEBUG_FILE "/tmp/ftp-proxy.debug" # define OPTS_LIST "cdinf:v:V?" #else # define OPTS_LIST "cdinf:V?" #endif /* ------------------------------------------------------------ */ static char progname[1024]; static char *usage_arr[] = { progname, " -c Dump Config-File contents and exit", " -d Forced to run in standalone mode", " -i Forced to run in inetd mode", " -n Do not detach from controlling terminal", " -f file Name of the configuration file", " (Default: " DEFAULT_CONFIG ")", #if defined(COMPILE_DEBUG) " -v level Send debuging output to " DEBUG_FILE, " (Level: 0 = silence, 4 = chatterbox)", " !!! DO NOT USE -v FOR PRODUCTION !!!", #endif " -V Display program version and exit", "", NULL }; /* ------------------------------------------------------------ */ static RETSIGTYPE main_signal(int signo); static char *cfg_file = 0; /* Name of the config file */ static int close_flag = 0; /* Program termination request */ static int config_flag = 0; /* Config refresh request */ static int rotate_flag = 0; /* Log file rotation request */ /* ------------------------------------------------------------ */ #define ST_NONE 0 /* Unknown ServerType */ #define ST_INETD 1 /* Run from (x)inetd */ #define ST_DAEMON 2 /* Run as daemon */ static int srv_type; /* The actual server type */ /* ------------------------------------------------------------ ** ** ** Function......: config_filename ** ** Parameters....: (none) ** ** Return........: name of current config file ** ** Purpose.......: read-only access to config file name ** ** ------------------------------------------------------------ */ const char* config_filename() { return cfg_file; } /* ------------------------------------------------------------ ** ** ** Function......: main_signal ** ** Parameters....: signo Signal to be handled ** ** Return........: (most probably, none) ** ** Purpose.......: Handler for signals, mainly killing. ** ** ------------------------------------------------------------ */ static RETSIGTYPE main_signal(int signo) { #if defined(COMPILE_DEBUG) debug(2, "server signal %d", signo); #endif switch (signo) { case SIGHUP: config_flag = 1; break; case SIGUSR1: rotate_flag = 1; break; default: close_flag = 1; } signal(signo, main_signal); #if RETSIGTYPE != void return 0; #endif } /* ------------------------------------------------------------ ** ** ** Function......: main ** ** Parameters....: argc & argv As usual ** ** Return........: EXIT_SUCCESS or EXIT_FAILURE ** ** Purpose.......: Yes. ** ** ------------------------------------------------------------ */ int main(int argc, char *argv[]) { int c, detach, cfg_dump; char *p; #if defined(SIGWINCH) /* ** Make sure we don't get confused by resizing windows */ signal(SIGWINCH, SIG_IGN); #endif /* ** Set a reasonable program name for debug/logging */ p = misc_setprog(argv[0], usage_arr); #if defined(HAVE_SNPRINTF) snprintf(progname, sizeof(progname), "Usage: %s [option ...]", p); #else sprintf(progname, "Usage: %s [option ...]", p); #endif misc_setvers(prog_vers); misc_setdate(prog_date); /* ** Preset some variables */ cfg_file = DEFAULT_CONFIG; cfg_dump = 0; srv_type = ST_NONE; /* Undetermined yet */ detach = 1; /* Usually detach from CtlTerm */ /* ** Read the command line options */ while ((c = getopt(argc, argv, OPTS_LIST)) != EOF) { switch (c) { case 'c': cfg_dump = 1; /* Dump config */ break; case 'd': srv_type = ST_DAEMON; /* Force daemon */ break; case 'i': srv_type = ST_INETD; /* Force inetd */ break; case 'n': detach = 0; /* Don't detach (e.g. AIX) */ break; case 'f': cfg_file = misc_strtrim(optarg); break; #if defined(COMPILE_DEBUG) case 'v': debug_init(atoi(misc_strtrim(optarg)), DEBUG_FILE); break; #endif case 'V': fprintf(stderr, "%s\n", misc_getvsdt()); exit(EXIT_SUCCESS); break; case '?': default: misc_usage(NULL); } } /* ** Redirect errors and faults to stderr durring the ** initialisation phase. The log file will be opened ** after the chroot is done and uid/gid are dropped ** (if they are requested....) */ syslog_stderr(); /* ** Read the configuration file (this will die on error) */ config_read(cfg_file, cfg_dump); /* ** Complain if no default DestinationAddress is given ** while the AllowTransProxy feature is disabled... ** ** FIXME: is this really needed? */ if( (NULL == config_str(NULL, "DestinationAddress", NULL)) && (0 == config_bool(NULL, "AllowTransProxy", 0)) && (0 == config_bool(NULL, "AllowMagicUser", 0))) { syslog_error("can't run without an destination address"); exit(EXIT_FAILURE); } /* ** Determine ServerType (inetd/standalone) */ if (srv_type == ST_NONE) { p = config_str(NULL, "ServerType", "inetd"); if (strcasecmp(p, "standalone") == 0) srv_type = ST_DAEMON; else srv_type = ST_INETD; } if (srv_type == ST_INETD) { #if defined(COMPILE_DEBUG) debug(1, "{{{{{ %s client-start", misc_getprog()); #endif /* ** Change root directory */ misc_chroot(config_str(NULL, "ServerRoot", NULL)); /* ** Change our user- and group-id if requested */ misc_uidgid(CONFIG_UID, CONFIG_GID); /* ** Open the log if requested */ if ((p = config_str(NULL, "LogDestination", NULL)) != NULL) syslog_open(p, config_str(NULL, "LogLevel", NULL)); else syslog_close(); client_run(); exit(EXIT_SUCCESS); } #if defined(COMPILE_DEBUG) debug(1, "{{{{{ %s daemon-start", misc_getprog()); #endif /* ** The rest of this file is "daemon only" code ... */ daemon_init(detach); /* ** Setup signal handling (mostly graceful exit) */ signal(SIGINT, main_signal); signal(SIGTERM, main_signal); signal(SIGQUIT, main_signal); signal(SIGHUP, main_signal); signal(SIGUSR1, main_signal); /* ** Well, it's time for the main loop now ... */ while (close_flag == 0) { /* ** Shall we re-read the config file? */ if (config_flag) { /* ** reread config */ config_flag = 0; config_read(cfg_file, 0); /* ** reopen / rotate log */ syslog_open(config_str(NULL, "LogDestination", NULL), config_str(NULL, "LogLevel", NULL)); } /* ** Check for log file rotation */ if (rotate_flag) { rotate_flag = 0; syslog_rotate(); } /* ** Now perform the "real" main loop work */ socket_exec(SELECT_TIMEOUT, &close_flag); } #if defined(COMPILE_DEBUG) debug(1, "}}}}} %s daemon-exit", misc_getprog()); #endif exit(EXIT_SUCCESS); } /* ------------------------------------------------------------ * $Log: ftp-main.c,v $ * Revision 1.6.6.1 2003/05/07 11:08:55 mt * added strtrim arround optarg * * Revision 1.6 2002/01/14 19:24:46 mt * reordered config reading, chroot and syslog opening * added config_filename function for runtime queries * added snprintf usage if supported on built-platform * * Revision 1.5 2001/11/06 23:04:44 mt * applied / merged with transparent proxy patches v8 * see ftp-proxy/NEWS for more detailed release news * * Revision 1.4 1999/09/29 09:58:25 wiegand * complain about missing DestAddr after LogOpen (incl. stderr) * * Revision 1.3 1999/09/21 07:13:07 wiegand * syslog / abort cleanup and review * * Revision 1.2 1999/09/16 16:29:57 wiegand * minor updates improving code quality * * Revision 1.1 1999/09/15 14:06:22 wiegand * initial checkin * * ------------------------------------------------------------ */