Added two configuration parameters:
[gnucomo.git] / src / gcm_input / gcm_input.cpp
1 /**************************************************************************
2 **  (c) Copyright 2002, Andromeda Technology & Automation
3 ** This is free software; you can redistribute it and/or modify it under the
4 ** terms of the GNU General Public License, see the file COPYING.
5 ***************************************************************************
6 ** MODULE INFORMATION *
7 ***********************
8 **      FILE NAME      : gcm_input.cpp
9 **      SYSTEM NAME    : Gnucomo - Gnu Computer Monitoring
10 **      VERSION NUMBER : $Revision: 1.5 $
11 **
12 **  DESCRIPTION      :  Application to store client messages into the database
13 **                      The client message contains a log file from one of the
14 **                      system logs. Gcm_input parses the log file and enters
15 **                      the raw data into the 'log' table of the gnucomo database.
16 **
17 **                      The system log may arrive in one of several forms:
18 **                      1. Log file (archived or not) from a client machine.
19 **                      2. Log file from a client system, arriving in a clear Email.
20 **                      3. Log file from a client machine, arriving in an
21 **                         encrypted Email.
22 **
23 **                      additional information we need that may not be availble in
24 **                      the content of the log is:
25 **                      - FQDN of the client.
26 **                      - Time of arrival of the log
27 **                      - Service that created the log.
28 **
29 **                      If the log arrives in an Email, these items probably are
30 **                      available in the mail header. Otherwise, they have to be
31 **                      provided as command line arguments.
32 **
33 **                      Command line arguments:
34 **                      -c <name>        Configuration name (default = gnucomo).
35 **                      -d <date>        Date and time of log arrival.
36 **                      -h <hostname>    FQDN of the client.
37 **                      -i               Incremental - partial list of parameters.
38 **                      -s <service>     Service that created the log.
39 **                      -T               Test mode. Do not alter the database.
40 **                      -v               Verbose (debug) output.
41 **                      -V               Print version and exit.
42 **
43 **  EXPORTED OBJECTS : 
44 **  LOCAL    OBJECTS : 
45 **  MODULES  USED    :
46 ***************************************************************************
47 **  ADMINISTRATIVE INFORMATION *
48 ********************************
49 **      ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl
50 **      CREATION DATE   : Aug 29, 2002
51 **      LAST UPDATE     : Jul 24, 2003
52 **      MODIFICATIONS   : 
53 **************************************************************************/
54
55 /*****************************
56    $Log: gcm_input.cpp,v $
57    Revision 1.5  2003-08-05 08:11:06  arjen
58    Added two configuration parameters:
59       logfile   - Log to this file instead of stderr.
60       verbosity - Verbose output if greater than 0.
61    Added '-i' option for incremental parameter updates
62
63    Revision 1.4  2003/03/29 08:42:00  arjen
64    Exit without reading any input if the database connection fails.
65
66    Revision 1.3  2002/11/09 08:04:27  arjen
67    Added a reference to the GPL
68
69    Revision 1.2  2002/11/04 10:13:36  arjen
70    Use proper namespace for iostream classes
71
72    Revision 1.1  2002/10/05 10:25:49  arjen
73    Creation of gcm_input and a first approach to a web interface
74
75 *****************************/
76
77 static const char *RCSID = "$Id: gcm_input.cpp,v 1.5 2003-08-05 08:11:06 arjen Exp $";
78
79 #include <fstream>
80
81 #include <getopt.h>
82
83 #include "message.h"
84
85 bool verbose = false;
86 bool testmode = false;
87 bool incremental = false;
88 std::ostream *log = &std::cerr;
89
90 static char *Version = "gcm_input version 0.0.7 - Jul 24, 2003";
91
92
93 /*=========================================================================
94 **  NAME           : main
95 **  SYNOPSIS       : int main(int argc, char *argv[])
96 **  PARAMETERS     : 
97 **  RETURN VALUE   : 
98 **
99 **  DESCRIPTION    : Parse command line arguments and establish a connection
100 **                   to the database.
101 **                   When we have a database connection, parse the log file
102 **                   from stdin.
103 **
104 **  VARS USED      :
105 **  VARS CHANGED   :
106 **  FUNCTIONS USED :
107 **  SEE ALSO       :
108 **  LAST MODIFIED  : Jul 24, 2003
109 **=========================================================================
110 */
111
112 int main(int argc, char *argv[])
113 {
114    const char *usage = "Usage: gcm_input [-c configname] [-h hostname] [-i] [-d date]"
115                        " [-s service] [-T] [-v] [-V]\n";
116
117    gnucomo_config    cfg;
118    char             *config_name = "gnucomo";
119    std::ofstream    logfile;
120
121
122    /*   Parse command line arguments */
123
124    UTC    arrival = Now();
125    String  hostname(""), service("");
126    int     option;
127
128
129    while ((option = getopt(argc, argv, "c:h:d:s:iTvV")) != -1)
130    {
131       switch (option)
132       {
133       case 'c':
134          config_name = optarg;
135          break;
136
137       case 'h':
138          hostname = optarg;
139          break;
140
141       case 'd':
142          arrival = String(optarg);
143          if (!arrival.proper())
144          {
145             std::cerr << "gcm_input: Invalid date string: " << optarg << ".\n";
146             exit(1);
147          }
148          break;
149
150       case 's':
151          service = optarg;
152          break;
153
154       case 'i':
155          incremental = true;
156          break;
157
158       case 'T':
159          testmode = true;
160          break;
161
162       case 'v':
163          verbose = true;
164          break;
165
166       case 'V':
167          std::cout << Version << "\n";
168          exit(0);
169
170       case '?':
171       case ':':
172          std::cerr << usage;
173          exit(1);
174       }
175    }
176    /*  Get the configuration file */
177
178    if (!cfg.read(config_name))
179    {
180       std::cerr << "Can not read Gnucomo configuration file for " << config_name << ".\n";
181       exit(1);
182    }
183
184    String logfile_name = cfg.find_parameter("gcm_input", "logfile");
185    int    verbosity    = cfg.find_parameter("gcm_input", "verbosity");
186
187    if (logfile_name != "")
188    {
189       std::cerr << "Logging to " << logfile_name << ".\n";
190       logfile.open(logfile_name, _IO_APPEND); // for gcc 2
191       //logfile.open(logfile_name, std::ios_base::app); // for gcc 3
192       if (!logfile)
193       {
194          std::cerr << "Can't open logfile " << logfile_name << " for writing.\n";
195       }
196       else
197       {
198          log = &logfile;
199          verbose = verbose || verbosity > 0;
200       }
201    }
202
203    *log << "Gcm_input starting at " << Now() << ".\n";
204
205    if (verbose)
206    {
207       *log << "Hostname = " << hostname;
208       *log << " Arrival = " << arrival;
209       *log << " Service = " << service << "\n";
210       *log << "Config OK.\n";
211    }
212
213    /*  Try to connect to the database */
214
215    gnucomo_database db(&cfg);
216
217    if (db.is_connected())
218    {
219
220       client_message  msg(&std::cin, db);
221
222       if (msg.classify(hostname, arrival, service) > 0.9)
223       {
224          msg.enter();
225       }
226       *log << "Gcm_input finished at " << Now() << ".\n";
227       return 0;
228    }
229    else
230    {
231       *log << "gcm_input: Can not connect to database.\n";
232       *log << "Gcm_input finished at " << Now() << ".\n";
233       return 1;
234    }
235 }
236