1 /*======================================================================*
2 * Copyright (C) 2008 Light Weight Event System *
3 * All rights reserved. *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
18 * Boston, MA 02110-1301 USA. *
19 *======================================================================*/
34 #include <sys/types.h>
37 /* Base program name from argv[0]. */
38 char* arg_basename
= 0;
40 /* Number of network reader processes/threads to run. */
43 /* Set default queue type, types in preferred order. */
45 const char* arg_queue_type
= ARG_MQ
;
47 const char* arg_queue_type
= ARG_MSG
;
49 #error No kernel message queue support on this platform.
52 /* Queue parameters. */
53 const char* arg_queue_name
= "/lwes_journal";
54 int arg_queue_max_sz
= 64*1024 - 1;
55 int arg_queue_max_cnt
= 10000;
59 const char* arg_journ_type
= ARG_GZ
;
61 const char* arg_journ_type
= ARG_FILE
;
63 char* arg_monitor_type
= NULL
;
66 const char* arg_proc_type
= ARG_THREAD
;
68 const char* arg_proc_type
= ARG_PROCESS
;
71 /* network transport parameters */
72 const char* arg_xport
= "udp";
73 const char* arg_ip
= "224.0.0.69";
75 const char* arg_interface
= "";
76 int arg_join_group
= 1;
77 int arg_sockbuffer
= 16*1024*1024;
80 /* Set the logging level, see log.h. */
81 int arg_log_level
= LOG_MASK_ERROR
84 const char* arg_log_file
= NULL
;
88 /* site ID used to set various config items from config file. */
91 /* intended owner of journal files */
92 int arg_journal_uid
= 0;
93 const char* arg_journal_user
= NULL
;
95 /* Queue report interval. */
96 /*TODO: int arg_interval = 60;*/
98 const char* arg_pid_file
= "/var/run/lwes-journaller.pid";
100 /* Journals specified and number of journals specified. */
101 char** arg_journalls
;
103 char* arg_disk_journals
[10];
105 int arg_nodaemonize
= 0;
107 /* Print version, then exit. */
110 /* Print args to sub-programs, then exit. */
113 #ifdef HAVE_MONDEMAND
114 const char* arg_mondemand_host
= NULL
;
115 const char* arg_mondemand_ip
= NULL
;
116 int arg_mondemand_port
= 20402;
119 void process_options(int argc
, const char* argv
[])
121 static const struct poptOption options
[] = {
122 { "args", 0, POPT_ARG_NONE
, &arg_args
, 0, "Print command line arguments, then exit", 0 },
123 { "nodaemonize", 0, POPT_ARG_NONE
, &arg_nodaemonize
, 0, "Don't run in the background", 0 },
124 { "log-level", 0, POPT_ARG_INT
, &arg_log_level
, 0, "Set the output logging level - OFF=(1), ERROR=(2), WARNING=(4), INFO=(8), PROGRESS=(16)", "mask" },
125 { "log-file", 0, POPT_ARG_STRING
, &arg_log_file
, 0, "Set the output log file", "file" },
126 { "interface", 'I', POPT_ARG_STRING
, &arg_interface
, 0, "Network interface to listen on", "ip" },
127 /*TODO: { "report-interval", 's', POPT_ARG_INT, &arg_interval, 0, "Queue report interval", "seconds" },*/
128 { "address", 'm', POPT_ARG_STRING
, &arg_ip
, 0, "IP address", "ip" },
129 { "join-group", 'g', POPT_ARG_INT
, &arg_join_group
, 0, "Join multicast group", "0/1" },
130 { "journal-type", 'j', POPT_ARG_STRING
, &arg_journ_type
, 0, "Journal type", "{" ARG_GZ
"," ARG_FILE
"}" },
131 { "monitor-type", 'j', POPT_ARG_STRING
, &arg_monitor_type
, 0, "Monitor type", 0 },
132 { "nreaders", 'r', POPT_ARG_INT
, &arg_nreaders
, 0, "Number of network reading threads, dflt=1, max=5", 0 },
133 { "pid-file", 'f', POPT_ARG_STRING
, &arg_pid_file
, 0, "PID file, dflt=NULL", "path" },
134 { "port", 'p', POPT_ARG_INT
, &arg_port
, 0, "Port number to listen on, dflt=9191", "short" },
135 { "thread-type", 't', POPT_ARG_STRING
, &arg_proc_type
, 0, "Threading model, '" ARG_THREAD
"' or '" ARG_PROCESS
"' or '" ARG_SERIAL
"', dflt="
142 { "queue-max-cnt", 0, POPT_ARG_INT
, &arg_queue_max_cnt
, 0, "Max messages for queue, dflt=10000", "int" },
143 { "queue-max-sz", 0, POPT_ARG_INT
, &arg_queue_max_sz
, 0, "Max message size for queue, dflt=65535", "int" },
144 { "queue-name", 'Q', POPT_ARG_STRING
, &arg_queue_name
, 0, "Queue name, should start with '/', dflt='/lwes_journal'", "string" },
145 { "queue-type", 'q', POPT_ARG_STRING
, &arg_queue_type
, 0, "Queue type", "{" ARG_MSG
"," ARG_MQ
"}" },
146 { "real-time", 'R', POPT_ARG_NONE
, &arg_rt
, 0, "Run threads with real-time priority", 0 },
147 { "site", 'n', POPT_ARG_INT
, &arg_site
, 0, "Site id", "int" },
148 { "sockbuffer", 0, POPT_ARG_INT
, &arg_sockbuffer
, 0, "Receive socket buffer size", "bytes" },
149 { "ttl", 0, POPT_ARG_INT
, &arg_ttl
, 0, "Emitting TTL value", "hops" },
150 { "user", 0, POPT_ARG_STRING
, &arg_journal_user
, 0, "Owner of journal files", "user" },
151 { "version", 'v', POPT_ARG_NONE
, &arg_version
, 0, "Display version, then exit", 0 },
152 { "xport-type", 'x', POPT_ARG_STRING
, &arg_xport
, 0, "Transport, dflt=udp", "{" ARG_UDP
", ...}" },
153 #ifdef HAVE_MONDEMAND
154 { "mondemand-host", 0, POPT_ARG_STRING
, &arg_mondemand_host
, 0, "Mondemand monitoring host", "string" },
155 { "mondemand-ip", 0, POPT_ARG_STRING
, &arg_mondemand_ip
, 0, "Mondemand monitoring ip", "ip-address" },
156 { "mondemand-port", 0, POPT_ARG_INT
, &arg_mondemand_port
, 0, "Mondemand monitoring port dflt=20402", "port" },
160 { NULL
, 0, 0, NULL
, 0, NULL
, NULL
}};
166 arg_basename
= basename((char*)argv
[0]);
168 arg_basename
= (char*)argv
[0];
171 poptContext optCon
= poptGetContext(NULL
, argc
, argv
, options
, 0);
172 poptSetOtherOptionHelp(optCon
, "");
174 while ( (rc
= poptGetNextOpt(optCon
)) != -1 )
180 case POPT_ERROR_BADOPT
:
181 /* You might waht to check options of other types here... */
185 poptBadOption(optCon
, POPT_BADOPTION_NOALIAS
),
192 arg_journalls
= (char**) poptGetArgs(optCon
);
194 /* Count the journals specified on the command line. */
197 for ( arg_njournalls
=0; arg_journalls
[arg_njournalls
]; ++arg_njournalls
)
201 /* Use default journal spec if none provided on the command line. */
202 if ( 0 == arg_njournalls
)
204 static const char* default_arg_journalls
[] = { "/tmp/all_events.log.gz",
206 arg_journalls
= (char**) default_arg_journalls
;
210 /* convert the journal file username to a uid */
211 if ( arg_journal_user
!= NULL
)
213 struct passwd
*pw_entry
= getpwnam(arg_journal_user
);
216 LOG_ER("%s was told to use a file owner (%s) that could not be found\n",
217 arg_basename
, arg_journal_user
);
222 arg_journal_uid
= pw_entry
->pw_uid
;
228 printf("The packet journaller is a program for recording LWES\n"
229 "messages for later processing.\n"
231 "It listens for UDP packets on an interface/IP address/port\n"
232 "combination and writes them to an optionally compressed\n"
233 "packet journal file.\n"
235 "It adds a 22 bytes header with the packet size and sender\n"
236 "information. See the README file for additional details.\n"
238 "The journaller looks at the \"message type\" in each received\n"
239 "packet and will rotate the logs if it matches\n"
240 "\"Command::Rotate\".\n"
244 printf("Compile time features: \n"
246 " process model(s): "
270 " scheduling type(s): FIFO "
277 printf("Bug reports to %s\n\n", PACKAGE_BUGREPORT
);
284 char log_level_string
[100];
286 log_get_mask_string(log_level_string
, sizeof(log_level_string
));
288 log_msg(LOG_INFO
, __FILE__
, __LINE__
,
290 " arg_basename == \"%s\"\n"
291 " arg_interface == \"%s\"\n"
292 " arg_ip == \"%s\"\n"
293 " arg_journ_type == \"%s\"\n"
294 " arg_monitor_type == \"%s\"\n"
295 " arg_pid_file == \"%s\"\n"
296 " arg_proc_type == \"%s\"\n"
297 " arg_queue_name == \"%s\"\n"
298 " arg_queue_type == \"%s\"\n"
299 " arg_xport == \"%s\"\n"
300 /*" arg_interval == %d\n"*/
301 " arg_join_group == %d\n"
302 " arg_log_level == %s (%d)\n"
303 " arg_log_file == %s\n"
304 " arg_njournalls == %d\n"
305 " arg_nreaders == %d\n"
307 " arg_queue_max_cnt == %d\n"
308 " arg_queue_max_sz == %d\n"
312 " arg_journal_user == %s\n"
313 " arg_journal_uid == %d\n",
324 /*TODO: arg_interval,*/
340 for ( arg_njournalls
=0; arg_journalls
[arg_njournalls
]; ++arg_njournalls
)
342 log_msg(LOG_INFO
, __FILE__
, __LINE__
,
343 "journall[%d] == %s\n",
345 arg_journalls
[arg_njournalls
]);
350 #ifdef HAVE_MONDEMAND
351 if ( arg_mondemand_host
== NULL
352 && arg_mondemand_ip
!= NULL
)
354 /* mondemand was requested, but no hostname was specified. Choose one. */
356 if ( gethostname(host
,sizeof(host
)-1) == 0 )
358 /* this strndup is an intentional one-time memory leak. */
359 arg_mondemand_host
= strndup(host
,sizeof(host
)-1);
363 LOG_WARN("Mondemand requires a hostname, but none was provided or"
364 " available. Disabling mondemand.");
365 arg_mondemand_ip
= NULL
;
370 if ( arg_journalls
== NULL
371 || ! arg_journalls
[0]
372 || ! strrchr(arg_journalls
[0],'/') )
374 LOG_ER("%s requires output pathnames in form "
375 "'/path/to/archive/file.gz'\n", arg_basename
);