main.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2004 by Michael Moritz                                  *
00003  *   mimo@restoel.net                                                      *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #ifdef HAVE_CONFIG_H
00022 #include <config.h>
00023 #endif
00024 
00025 #include <pthread.h>
00026 #include <iostream>
00027 #include <iomanip>
00028 #include <fstream>
00029 #include <sstream>
00030 #include <syslog.h>
00031 #include "defs.h"
00032 #include "triplet.h"
00033 #include "read.h"
00034 #include "configreader.h"
00035 #include "cfg.h"
00036 #include "db.h"
00037 #include "action.h"
00038 #include "signals.h"
00039 using namespace std;
00040 
00041 const static char s_gpsname[] = PACKAGE; //from config.h
00042 
00043 typedef out_of_range EndOfInputException;
00044 
00045 
00046 void usage()
00047 {
00048         cerr << "usage: gps [-v] configfile" << endl;
00049 }
00050 int end_usage(const std::string& msg)
00051 {
00052         syslog(LOG_ERR, "Error: %s",msg.c_str());
00053         cerr << "Error: " << msg << "\n" << endl;
00054         usage();
00055         closelog();
00056         return -1;
00057 }
00058 
00059 DB *get_db() {
00060         DB *greydb = 0;
00061         // try block for initialising phase
00062         // - parse config file
00063         // - connect to db
00064         try {
00065 //              g_getCfgNonConst().init(reader);
00066                 //FIXME uses global Cfg object!!
00067                 greydb = new DB; 
00068                 if(greydb) {
00069                         Signal_Handler::instance()->register_handler(SIGINT, greydb);
00070                         Signal_Handler::instance()->register_handler(SIGTERM, greydb);
00071                         Signal_Handler::instance()->register_handler(SIGQUIT, greydb);
00072                 }
00073         // this should not exit, but continue with dunno
00074         // otherwise we see in the log files:
00075         //   "warning: problem talking to server private/policy: Success"
00076         // and a REJECT
00077         // This usually happens when the db is down
00078         } catch (exception &e) {
00079                 greydb = 0;
00080                 syslog(LOG_ERR, "error while initialising db: %s, NO GREYLISTING WILL BE DONE",e.what());
00086         }
00087         return greydb;
00088 }
00089 void read_config(const std::string filename) {
00090         syslog(LOG_DEBUG,"reading config: %s",filename.c_str());
00091         ifstream cfgfile(filename.c_str());
00092         if(!cfgfile) {
00093                 syslog(LOG_ERR, "error opening config: %s",filename.c_str());
00094                 return;
00095                 //cerr << "Error opening config: " << argv[cfgindex] << ", exiting" << endl;
00096         }
00097 //      cfgfile.setf(ios::skipws);
00098         // parse in config file
00099         
00100         try {
00101                 ConfigReader reader(cfgfile);
00102                 g_getCfgNonConst().init(reader);
00103         } catch (exception &e) {
00104                 syslog(LOG_ERR, "error while initialising config: %s",e.what());
00110         }
00111 }
00113 int main(char argc,char* argv[])
00114 {
00115 //      Watchdog harakiri;
00116         openlog(::s_gpsname, LOG_PID, GPS_LOG_FACILITY);
00117         syslog(LOG_INFO,"started (ver.: %s built: %s %s) by %i",VERSION,__DATE__,__TIME__,getppid());
00118         if(argc < 2)
00119                 return end_usage("too few parameters");
00120 
00121         int cfgindex = 1;
00122         if(string(argv[1]) == string("-v")) {
00123                 setlogmask(LOG_UPTO(LOG_DEBUG));
00124                 g_getCfgNonConst().setVerbose(true);
00125                 cfgindex = 2;
00126                 if(argc < 3)
00127                         return end_usage("parameter configfile missing");
00128         } else {
00129                 setlogmask(LOG_UPTO(LOG_INFO));
00130         }
00131         // read configuration file
00132         // initialise global cfg object
00133         read_config(argv[cfgindex]);
00134         
00135         // create db connection
00136         // if something goes wrong set to 0     
00137         DB *greydb = get_db();
00138         
00139         // general try block for std::exception
00140         try { 
00141                 Reader::AttributeSet attrSet;
00142                 attrSet.insert(Reader::AttributeSet::value_type(ATTR_CLIENT,true)); // required input
00143                 attrSet.insert(Reader::AttributeSet::value_type(ATTR_SENDER,true)); // required input
00144                 attrSet.insert(Reader::AttributeSet::value_type(ATTR_RECIPIENT,true)); // required input
00145                 attrSet.insert(Reader::AttributeSet::value_type(ATTR_RCLNAME,false)); // optional, postfix
00146 
00147                 while(true) {
00148                         try {
00149                                 Reader inputReader;
00150                                 int irResult = 0;
00151                                 bool bHaveRequired = false;
00152 //                              do {
00153                                 inputReader.reset();
00154                                 // get the result -- returns -1 if eof
00155                                 irResult = inputReader.parse(attrSet,cin);
00156                                 bHaveRequired = inputReader.haveAllRequired(attrSet);
00157                                         
00158                                 if((irResult < 0) && !bHaveRequired ) { // eof
00159                                         if(greydb) {
00160 //                                              greydb->close();
00161                                                 delete greydb;
00162                                                 greydb = 0;
00163                                         }
00164                                         closelog();
00165                                         exit(0);
00166                                 //              throw EndOfInputException("End of File, broken pipe?");
00167                                 }
00168                                 if( g_getCfg().isVerbose() ) {
00169                                         if( ! bHaveRequired ) {
00170                                                 syslog(LOG_DEBUG,"ignoring garbage: %s", inputReader.getInput().c_str());
00171                                         } else {
00172                                                 syslog(LOG_DEBUG,"input: %s", inputReader.getInput().c_str());
00173                                                 syslog(LOG_DEBUG,"parsed: %s", inputReader.getParsedString().c_str());
00174                                         }
00175                                 }
00176                                 // we got something but not what we need
00177                                 if(!bHaveRequired && (irResult != -1) )
00178                                         continue;
00179                                         
00180                                 // last check
00181                                 if(!bHaveRequired) 
00182                                         continue;
00183                                         
00184 //                              } while(irSize != int(attrSet.size()));
00185                                 // see if something went wrong during init
00186                                 if(!greydb) {
00187                                         greydb = get_db();
00188                                         if(!greydb) { 
00189                                                 Action act(Action::dunno); 
00190                                                 continue; //skip greylisting
00191                                         }
00192                                 }
00193                                 Triplet triplet(inputReader);
00194                                 DB::RecordStatus status = greydb->update(triplet);
00195                                 if(g_getCfg().isModeInit()) {
00196                                         Action act(Action::dunno);
00197                                 } else {
00198                                         switch(status) {
00199                                                 default:
00200                                                 case DB::registered:
00201                                                         { Action act(Action::dunno); }
00202                                                         break;
00203                                                 case DB::unknown:
00204                                                 case DB::waiting:
00205                                                         { Action act(Action::defer); }
00206                                                         break;
00207 
00208                                         }
00209                                 }
00210                         } catch (EndOfInputException &e) {
00211                                 //throw it on
00212                                 throw e;
00213                         } catch (exception &e) {
00214                                 syslog(LOG_WARNING, "exception caught: %s, continuing with \'dunno\'",e.what());
00215                                 Action act(Action::dunno);
00216                         }
00217                 } //while
00218         } catch (EndOfInputException &e) {
00219                 syslog(LOG_INFO, "FATAL: %s, exiting",e.what());
00224                 return 0;
00225         } catch (exception &e) {
00226                 syslog(LOG_ERR, "unexcepted error: %s, exiting",e.what());
00227                 Action act(Action::dunno);
00228                 //cerr << "Error while initialising:\n\t" << e.what() << endl;
00229                 closelog();
00230                 return 0;
00231         }
00232         return 0;
00233 }

Generated on Tue Jul 24 16:36:53 2007 for gps by  doxygen 1.5.1