/* $Id: exact.c,v 1.18 2004/03/27 13:05:10 doug Exp $ * * This file is part of EXACT. * * EXACT 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. * * EXACT 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 EXACT; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "config.h" #include #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_H #include #else #include "getopt.h" #endif #include "tail.h" #include "logger.h" #include "match.h" #include "conffile.h" #include "auth.h" #include "daemon.h" #include "errno.h" typedef struct { int foreground; int sleep; int debug; int preserve; int tables; } command_line; command_line cmd; int onepass() { int i; int start=0; match_login *l; tail_read(); for(i=0;iusername, l->hostname); start=i+1; } } return 0; } void usage() { fprintf(stderr,"Usage: exact [-h] [-d] [-f] [-p] [-c filename]\n"); fprintf(stderr," -h | --help show this usage information\n"); fprintf(stderr," -d | --debug more than you ever want to know\n"); fprintf(stderr," -f | --foreground don't background\n"); fprintf(stderr," -p | --preserve don't remove the relay file on exit\n"); fprintf(stderr," -c | --config configuration filename\n"); fprintf(stderr," -V | --version print the version of exact and exit\n"); fprintf(stderr," (default %s)\n", conffile_name()); fprintf(stderr,"see the manual page exact(8) for more information\n"); } void version() { fprintf(stderr, "Exact Version 1.41 (c) 2004, Doug Winter\n"); } void cmdline(int argc, char *argv[]) { int c; cmd.foreground=0; cmd.sleep=0; cmd.debug=0; cmd.preserve=0; while(1) { int option_index=0; static struct option long_options[] = { {"help", 0, NULL, 'h'}, {"foreground", 0, NULL, 'f'}, {"sleep", 0, NULL, 's'}, {"debug", 0, NULL, 'd'}, {"preserver", 0, NULL, 'p'}, {"config", 1, NULL, 'c'}, {"version", 0, NULL, 'V'}, {0,0,0,0} }; c=getopt_long(argc,argv,"phsfdc:V",long_options, &option_index); if(c==-1) break; switch(c) { case 'h': usage(); exit(0); case 'V': version(); exit(0); case 'f': cmd.foreground=1; break; case 's': cmd.sleep=1; break; case 'd': cmd.debug=1; break; case 'p': cmd.preserve=1; break; case 'c': conffile_setname(optarg); break; default: fprintf(stderr, "Unknown argument: %c\n",c); usage(); exit(40); break; } } } void checkpid() { FILE *f; f=fopen(conffile_param("pidfile"),"r"); if(f) { int opid=0; fscanf(f,"%d",&opid); fclose(f); if(opid) { int kr=kill(opid,0); if(kr != -1) { logger(LOG_ERR, "Exact is already running, with pid %d\n", opid); exit(41); } } } logger(LOG_DEBUG, "exact is not already running\n"); } void writepid() { FILE *f=fopen(conffile_param("pidfile"),"w"); if(!f) { logger(LOG_ERR, "Cannot write to pid file %s\n", conffile_param("pidfile")); exit(42); } chmod(conffile_param("pidfile"),0640); logger(LOG_DEBUG, "Writing pid to %s\n", conffile_param("pidfile")); fprintf(f,"%d",(int)getpid()); fclose(f); } void exit_handler(int s) { unlink(conffile_param("pidfile")); auth_exit(); if(!cmd.preserve) unlink(conffile_param("authfile")); logger(LOG_ERR, "terminated\n"); exit(0); } int main(int argc, char *argv[]) { int use_syslog=0; cmdline(argc,argv); logger_init(0,cmd.debug,NULL); conffile_read(); conffile_check(); checkpid(); match_init(); daemonize(cmd.foreground, cmd.sleep); auth_init(); if(!strcmp("syslog",conffile_param("logging"))) use_syslog=1; else { if(!strcmp("internal",conffile_param("logging"))) use_syslog=0; else { logger(LOG_ERR, "logging parameter is neither syslog nor internal\n"); exit(100); } } if(cmd.foreground) { logger_init(0,cmd.debug,NULL); // use stderr } else { // never debug using syslog, because you might // get a loop logger_init(use_syslog,!use_syslog && cmd.debug,conffile_param("logfile")); logger(LOG_DEBUG, "Daemonized\n"); } writepid(); signal(1,conffile_reload); signal(10,auth_dump); signal(15,exit_handler); if(!tail_open()) { logger(LOG_ERR,"open of %s failed. Quitting.\n", conffile_param("maillog")); return 2; } logger(LOG_NOTICE, "running\n"); while(1) { onepass(); } assert(0); return 0; }