source: trunk/src/sh_getopt.c@ 15

Last change on this file since 15 was 1, checked in by katerina, 19 years ago

Initial import

File size: 15.8 KB
RevLine 
[1]1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <limits.h>
26#include <errno.h>
27
28
29#include "samhain.h"
30#include "sh_error.h"
31#include "sh_getopt.h"
32#include "sh_files.h"
33#include "sh_utils.h"
34#include "sh_mail.h"
35#include "sh_forward.h"
36#include "sh_hash.h"
37
38#if defined(WITH_EXTERNAL)
39#include "sh_extern.h"
40#endif
41
42extern int sh_calls_set_bind_addr (char *);
43
44#undef FIL__
45#define FIL__ _("sh_getopt.c")
46
47#define HAS_ARG_NO 0
48#define HAS_ARG_YES 1
49#define DROP_PRIV_NO 0
50#define DROP_PRIV_YES 1
51
52
53typedef struct options {
54 char * longopt;
55 const char shortopt;
56 char * usage;
57 int hasArg;
58 int (*func)(char * opt);
59} opttable_t;
60
61/*@noreturn@*/
62static int sh_getopt_usage (char * dummy);
63#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
64static int sh_getopt_forever (char * dummy);
65#endif
66static int sh_getopt_copyright (char * dummy);
67
68static opttable_t op_table[] = {
69
70#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
71 { N_("set-checksum-test"),
72 't',
73 N_("Set checksum testing to 'init', 'update', or 'check'"),
74 HAS_ARG_YES,
75 sh_util_setchecksum },
76 { N_("interactive"),
77 'i',
78 N_("Run update in interactive mode"),
79 HAS_ARG_NO,
80 sh_util_set_interactive },
81#endif
82#ifdef SH_WITH_SERVER
83 { N_("server"),
84 'S',
85 N_("Run as log server (obsolete)"),
86 HAS_ARG_NO,
87 sh_util_setserver },
88 { N_("qualified"),
89 'q',
90 N_("Log fully qualified name of client host"),
91 HAS_ARG_NO,
92 sh_forward_set_strip },
93 { N_("chroot"),
94 '-',
95 N_("Chroot to specified directory"),
96 HAS_ARG_YES,
97 sh_unix_set_chroot },
98#endif
99 { N_("daemon"),
100 'D',
101 N_("Run as daemon"),
102 HAS_ARG_NO,
103 sh_unix_setdeamon },
104 { N_("foreground"),
105 '-',
106 N_("Stay in the foreground"),
107 HAS_ARG_NO,
108 sh_unix_setnodeamon },
109 { N_("bind-address"),
110 '-',
111 N_("Bind to this address (interface) for outgoing connections"),
112 HAS_ARG_YES,
113 sh_calls_set_bind_addr },
114#ifdef SH_WITH_CLIENT
115 { N_("set-export-severity"),
116 'e',
117 N_("Set severity threshold for export to remote log server"),
118 HAS_ARG_YES,
119 sh_error_setexport },
120#endif
121 { N_("set-syslog-severity"),
122 's',
123 N_("Set severity threshold for syslog"),
124 HAS_ARG_YES,
125 sh_error_set_syslog },
126#ifdef WITH_EXTERNAL
127 { N_("set-extern-severity"),
128 'x',
129 N_("Set severity threshold for logging by external program(s)"),
130 HAS_ARG_YES,
131 sh_error_set_external },
132#endif
133#ifdef HAVE_LIBPRELUDE
134 { N_("set-prelude-severity"),
135 '-',
136 N_("Set severity threshold for logging to prelude"),
137 HAS_ARG_YES,
138 sh_error_set_prelude },
139#endif
140#if defined(WITH_DATABASE)
141 { N_("set-database-severity"),
142 '-',
143 N_("Set severity threshold for logging to RDBMS"),
144 HAS_ARG_YES,
145 sh_error_set_database },
146#endif
147 { N_("set-log-severity"),
148 'l',
149 N_("Set severity threshold for logfile"),
150 HAS_ARG_YES,
151 sh_error_setlog },
152#if defined(SH_WITH_MAIL)
153 { N_("set-mail-severity"),
154 'm',
155 N_("Set severitythreshold for e-mail"),
156 HAS_ARG_YES,
157 sh_error_setseverity },
158#endif
159 { N_("set-print-severity"),
160 'p',
161 N_("Set the severity threshold for terminal/console log"),
162 HAS_ARG_YES,
163 sh_error_setprint },
164#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
165 { N_("recursion"),
166 'r',
167 N_("Set recursion level for directories"),
168 HAS_ARG_YES,
169 sh_files_setrecursion },
170#endif
171 { N_("verify-log"),
172 'L',
173 N_("Verify the audit trail"),
174 HAS_ARG_YES,
175 sh_error_logverify },
176 { N_("just-list"),
177 'j',
178 N_("Modify -L to just list the audit trail"),
179 HAS_ARG_NO,
180 sh_error_logverify_mod },
181#if defined(SH_WITH_MAIL)
182 { N_("verify-mail"),
183 'M',
184 N_("Verify the mailbox"),
185 HAS_ARG_YES,
186 sh_mail_sigverify
187 },
188#endif
189 { N_("add-key"),
190 'V',
191 N_("Add key for the mail/log signature"),
192 HAS_ARG_YES,
193 sh_util_set_newkey
194 },
195 { N_("hash-string"),
196 'H',
197 N_("Print the hash of a string"),
198 HAS_ARG_YES,
199 sh_error_verify },
200#if defined (SH_WITH_SERVER)
201 { N_("password"),
202 'P',
203 N_("Compute a client registry entry for password"),
204 HAS_ARG_YES,
205 sh_forward_make_client },
206 { N_("gen-password"),
207 'G',
208 N_("Generate a random password"),
209 HAS_ARG_NO,
210 sh_forward_create_password },
211#endif
212
213#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
214 { N_("forever"),
215 'f',
216 N_("Loop forever, even if not daemon"),
217 HAS_ARG_NO,
218 sh_getopt_forever},
219 { N_("full-detail"),
220 'a',
221 N_("Modify -d to list full details"),
222 HAS_ARG_NO,
223 set_full_detail},
224 { N_("delimited"),
225 '-',
226 N_("Modify -d to list full details, comma delimited"),
227 HAS_ARG_NO,
228 set_list_delimited},
229 { N_("list-database"),
230 'd',
231 N_("List database content (like ls -l)"),
232 HAS_ARG_YES,
233 sh_hash_list_db},
234 { N_("init2stdout"),
235 '-',
236 N_("Write database to stdout on init"),
237 HAS_ARG_NO,
238 sh_hash_pushdata_stdout},
239#endif
240 { N_("trace-logfile"),
241 '-',
242 N_("Logfile for trace"),
243 HAS_ARG_YES,
244 sl_trace_file },
245 { N_("trace-enable"),
246 '-',
247 N_("Enable tracing"),
248 HAS_ARG_NO,
249 sl_trace_use },
250 { N_("copyright"),
251 'c',
252 N_("Print copyright information"),
253 HAS_ARG_NO,
254 sh_getopt_copyright },
255 { N_("help"),
256 'h',
257 N_("Print usage information"),
258 HAS_ARG_NO,
259 sh_getopt_usage },
260 /* last entry -- required !! -- */
261 { NULL,
262 '\0',
263 NULL,
264 HAS_ARG_NO,
265 NULL }
266};
267
268static int sh_getopt_copyright (char * dummy)
269{
270 fprintf (stdout,
271 _("Copyright (C) 1999-2005 Rainer Wichmann"\
272 " (http://la-samhna.de).\n\n"));
273
274 fprintf (stdout,
275 _("This program is free software; "\
276 "you can redistribute it and/or modify\n"));
277 fprintf (stdout, _("it under the terms of the GNU General "\
278 "Public License as published by\n"));
279 fprintf (stdout, _("the Free Software Foundation; either version 2 "\
280 "of the License, or\n"));
281 fprintf (stdout, _("(at your option) any later version.\n\n"));
282
283 fprintf (stdout, _("This program is distributed in the hope "\
284 "that it will be useful,\n"));
285 fprintf (stdout, _("but WITHOUT ANY WARRANTY; "\
286 "without even the implied warranty of\n"));
287 fprintf (stdout, _("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."\
288 " See the\n"));
289 fprintf (stdout, _("GNU General Public License for more details.\n\n"));
290
291 fprintf (stdout, _("You should have received a copy of the "\
292 "GNU General Public License\n"));
293 fprintf (stdout, _("along with this program; "\
294 "if not, write to the Free Software\n"));
295 fprintf (stdout, _("Foundation, Inc., 59 Temple Place - Suite 330, "\
296 "Boston, MA 02111-1307, USA.\n\n"));
297
298 fprintf (stdout, _("This product makes use of the reference implementation "\
299 "of the TIGER message\n"));
300 fprintf (stdout, _("digest algorithm. This code is copyright Eli Biham "\
301 "(biham@cs.technion.ac.il)\n"));
302 fprintf (stdout, _("and Ross Anderson (rja14@cl.cam.ac.uk). It can be used "\
303 "freely without any\n"));
304 fprintf (stdout, _("restrictions.\n"));
305#if defined(USE_SRP_PROTOCOL) && !defined(SH_STANDALONE)
306#if (!defined(HAVE_LIBGMP) || !defined(HAVE_GMP_H))
307 fprintf (stdout, _("This product makes use of the 'bignum' library by "\
308 "Henrik Johansson\n"));
309 fprintf (stdout, _("(Henrik.Johansson@Nexus.Comm.SE). If you are including "\
310 "this library in a\n"));
311 fprintf (stdout, _("commercial product, be sure to distribute ALL of"\
312 " it with the product.\n"));
313#endif
314 fprintf (stdout, _("This product uses the 'Secure Remote Password' "\
315 "cryptographic\n"));
316 fprintf (stdout, _("authentication system developed by Tom Wu "\
317 "(tjw@CS.Stanford.EDU).\n"));
318#endif
319 fprintf (stdout, _("\nPlease refer to the file COPYING in the source "\
320 "distribution for a"));
321 fprintf (stdout, _("\nfull list of incorporated code and associated "\
322 "licenses.\n"));
323
324 if (dummy)
325 _exit (EXIT_SUCCESS);
326 else
327 _exit (EXIT_SUCCESS);
328 /*@notreached@*/
329 return 0; /* make compilers happy */
330}
331
332/*@noreturn@*/
333static int sh_getopt_usage (char * dummy)
334{
335 int i;
336 char fmt[64];
337
338 char opts[64];
339
340 for (i = 0; i < 64; ++i) /* splint does not grok char opts[64] = { '\0' }; */
341 opts[i] = '\0';
342
343 fprintf (stdout,
344 _("This is samhain (%s), "\
345 "(c) 1999-2005 Rainer Wichmann (http://la-samhna.de).\n"),
346 VERSION);
347 fprintf (stdout, _("This software comes with ABSOLUTELY NO WARRANTY. "));
348 fprintf (stdout, _("Use at own risk.\n"));
349
350 fprintf (stdout, _("Usage:\n\n"));
351
352 for (i = 0; op_table[i].longopt != NULL; ++i) {
353
354 if (i == 63)
355 break;
356
357 if (op_table[i].shortopt != '-' &&
358 strchr(opts, op_table[i].shortopt) != NULL)
359 fprintf (stdout, _("Short option char collision !\n"));
360 opts[i] = op_table[i].shortopt;
361
362
363 if (op_table[i].hasArg == HAS_ARG_NO) {
364 if (sl_strlen(op_table[i].longopt) < 10)
365 strcpy(fmt,_("%c%c%c --%-s,\t\t\t %s\n"));/* known to fit */
366 else if (sl_strlen(op_table[i].longopt) < 17)
367 strcpy(fmt, _("%c%c%c --%-s,\t\t %s\n")); /* known to fit */
368 else
369 strcpy(fmt, _("%c%c%c --%-s,\t %s\n")); /* known to fit */
370 /*@-formatconst@*/
371 fprintf (stdout,
372 fmt,
373 (op_table[i].shortopt == '-') ? ' ' : '-',
374 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
375 (op_table[i].shortopt == '-') ? ' ' : ',',
376 _(op_table[i].longopt),
377 _(op_table[i].usage));
378 /*@+formatconst@*/
379 } else {
380 if (sl_strlen(op_table[i].longopt) < 12)
381 strcpy(fmt, /* known to fit */
382 _("%c%c %s --%-s=<arg>,\t\t %s\n"));
383 else
384 strcpy(fmt, /* known to fit */
385 _("%c%c %s --%-s=<arg>,\t %s\n"));
386 /*@-formatconst@*/
387 fprintf (stdout,
388 fmt,
389 (op_table[i].shortopt == '-') ? ' ' : '-',
390 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
391 (op_table[i].shortopt == '-') ? _(" ") : _("<arg>,"),
392 _(op_table[i].longopt),
393 _(op_table[i].usage));
394 /*@+formatconst@*/
395 }
396 }
397
398 fprintf (stdout,
399 _("\nPlease report bugs to support@la-samhna.de.\n"));
400
401 (void) fflush(stdout);
402
403 if ( dummy != NULL)
404 {
405 if (sl_strcmp( dummy, _("fail")) == 0 )
406 _exit (EXIT_FAILURE);
407 }
408
409 _exit (EXIT_SUCCESS);
410 /*@notreached@*/
411 return 0; /* make compilers happy */
412}
413
414#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
415static int sh_getopt_forever (char * dummy)
416{
417 dummy = (void *) dummy;
418 SL_ENTER(_("sh_getopt_forever"));
419 sh.flag.loop = S_TRUE;
420 SL_RETURN(0, _("sh_getopt_forever"));
421}
422#endif
423
424int sh_getopt_get (int argc, char * argv[])
425{
426 int count = 0;
427 size_t len = 0;
428 int foundit = 0;
429 int i;
430 size_t k;
431 char * theequal;
432
433 SL_ENTER(_("sh_getopt_get"));
434
435 /* -- Return if no args. --
436 */
437 if (argc < 2)
438 SL_RETURN(0, _("sh_getopt_get"));
439
440 while (argc > 1 && argv[1][0] == '-')
441 {
442
443 /* Initialize
444 */
445 foundit = 0;
446 len = sl_strlen (argv[1]);
447
448 /* a '-' with no argument: error
449 */
450 if (len == 1)
451 (void) sh_getopt_usage(_("fail"));
452
453 /* a '--' with no argument: stop argument processing
454 */
455 if (len == 2 && argv[1][1] == '-')
456 SL_RETURN( count, _("sh_getopt_get"));
457
458 /* a short option: process it
459 */
460 if (len >= 2 && argv[1][1] != '-')
461 {
462 for (k = 1; k < len; ++k)
463 {
464 for (i = 0; op_table[i].shortopt != '\0'; ++i)
465 {
466
467 if ( op_table[i].shortopt == argv[1][k] )
468 {
469 foundit = 1;
470 if ( op_table[i].hasArg == HAS_ARG_YES )
471 {
472 if (k != (len - 1))
473 {
474 /* not last option
475 */
476 fprintf (stderr,
477 _("Error: short option with argument is not last in option string\n"));
478 (void) sh_getopt_usage(_("fail"));
479 }
480 if (argc < 3)
481 {
482 /* argument required, but no avail
483 */
484 fprintf (stderr, _("Error: missing argument\n"));
485 (void) sh_getopt_usage(_("fail"));
486 }
487 else
488 {
489 /* call function with argument */
490 --argc; ++argv;
491 if (0 != (* op_table[i].func )(argv[1]))
492 fprintf (stderr,
493 _("Error processing option -%c"),
494 op_table[i].shortopt);
495 break;
496 }
497 }
498 else
499 {
500 if (0 != (* op_table[i].func )(NULL))
501 fprintf (stderr,
502 _("Error processing option -%c"),
503 op_table[i].shortopt);
504 break;
505 }
506 }
507 }
508 }
509
510 /* 'break' should get here
511 */
512 if (foundit == 1)
513 {
514 --argc; ++argv;
515 continue;
516 }
517 else
518 {
519 /* unrecognized short option */
520 fprintf (stderr, _("Error: unrecognized short option\n"));
521 (void) sh_getopt_usage(_("fail"));
522 }
523 }
524
525 /* a long option: process it
526 */
527 if (len > 2)
528 {
529
530 for (i = 0; op_table[i].longopt != NULL; ++i)
531 {
532
533 if (sl_strncmp(_(op_table[i].longopt),
534 &argv[1][2],
535 sl_strlen(op_table[i].longopt)) == 0 )
536 {
537 foundit = 1;
538 if ( op_table[i].hasArg == HAS_ARG_YES )
539 {
540 if ( (theequal = strchr(argv[1], '=')) == NULL)
541 {
542 fprintf (stderr, _("Error: missing argument\n"));
543 /* argument required, but no avail */
544 (void) sh_getopt_usage(_("fail"));
545 }
546 else
547 {
548 if (sl_strlen (theequal) > 1)
549 {
550 ++theequal;
551 /* call function with argument */
552 if (0 != (* op_table[i].func )(theequal))
553 fprintf (stderr,
554 _("Error processing option -%s"),
555 op_table[i].longopt);
556 break;
557 }
558 else
559 {
560 fprintf (stderr, _("Error: invalid argument\n"));
561 /* argument required, but no avail */
562 (void) sh_getopt_usage(_("fail"));
563 }
564 }
565 }
566 else
567 {
568 if (0 != (* op_table[i].func )(NULL))
569 fprintf (stderr,
570 _("Error processing option -%s"),
571 op_table[i].longopt);
572 break;
573 }
574 }
575 }
576
577 /* 'break' should get here */
578 if (foundit == 1)
579 {
580 ++count;
581 --argc;
582 ++argv;
583 continue;
584 }
585 else
586 {
587 /* unrecognized long option */
588 fprintf (stderr, _("Error: unrecognized long option\n"));
589 (void) sh_getopt_usage(_("fail"));
590 }
591 }
592 }
593
594 SL_RETURN( count, _("sh_getopt_get"));
595}
Note: See TracBrowser for help on using the repository browser.