source: trunk/src/sh_getopt.c@ 323

Last change on this file since 323 was 295, checked in by katerina, 14 years ago

Support for IPv6 (ticket #222).

File size: 24.6 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
[20]42extern int sh_calls_set_bind_addr (const char *);
[1]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 {
[170]54 const char * longopt;
[1]55 const char shortopt;
[170]56 const char * usage;
[1]57 int hasArg;
[20]58 int (*func)(const char * opt);
[1]59} opttable_t;
60
61/*@noreturn@*/
[20]62static int sh_getopt_usage (const char * dummy);
[1]63#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
[20]64static int sh_getopt_forever (const char * dummy);
[1]65#endif
[20]66static int sh_getopt_copyright (const char * dummy);
[76]67static int sh_getopt_version (const char * dummy);
[1]68
69static opttable_t op_table[] = {
70
71#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
72 { N_("set-checksum-test"),
73 't',
74 N_("Set checksum testing to 'init', 'update', or 'check'"),
75 HAS_ARG_YES,
76 sh_util_setchecksum },
77 { N_("interactive"),
78 'i',
79 N_("Run update in interactive mode"),
80 HAS_ARG_NO,
81 sh_util_set_interactive },
82#endif
[27]83#if defined(SH_WITH_SERVER) || defined(SH_WITH_CLIENT)
84 { N_("server-port"),
85 '-',
86 N_("Set the server port to connect to"),
87 HAS_ARG_YES,
88 sh_forward_server_port },
89#endif
[1]90#ifdef SH_WITH_SERVER
91 { N_("server"),
92 'S',
93 N_("Run as log server (obsolete)"),
94 HAS_ARG_NO,
95 sh_util_setserver },
96 { N_("qualified"),
97 'q',
98 N_("Log fully qualified name of client host"),
99 HAS_ARG_NO,
100 sh_forward_set_strip },
101 { N_("chroot"),
102 '-',
103 N_("Chroot to specified directory"),
104 HAS_ARG_YES,
105 sh_unix_set_chroot },
106#endif
107 { N_("daemon"),
108 'D',
109 N_("Run as daemon"),
110 HAS_ARG_NO,
111 sh_unix_setdeamon },
112 { N_("foreground"),
113 '-',
114 N_("Stay in the foreground"),
115 HAS_ARG_NO,
116 sh_unix_setnodeamon },
117 { N_("bind-address"),
118 '-',
119 N_("Bind to this address (interface) for outgoing connections"),
120 HAS_ARG_YES,
121 sh_calls_set_bind_addr },
[27]122#if defined(SH_WITH_SERVER) || defined(SH_WITH_CLIENT)
[1]123 { N_("set-export-severity"),
124 'e',
125 N_("Set severity threshold for export to remote log server"),
126 HAS_ARG_YES,
127 sh_error_setexport },
128#endif
129 { N_("set-syslog-severity"),
130 's',
131 N_("Set severity threshold for syslog"),
132 HAS_ARG_YES,
133 sh_error_set_syslog },
134#ifdef WITH_EXTERNAL
135 { N_("set-extern-severity"),
136 'x',
137 N_("Set severity threshold for logging by external program(s)"),
138 HAS_ARG_YES,
139 sh_error_set_external },
140#endif
141#ifdef HAVE_LIBPRELUDE
142 { N_("set-prelude-severity"),
143 '-',
144 N_("Set severity threshold for logging to prelude"),
145 HAS_ARG_YES,
146 sh_error_set_prelude },
147#endif
148#if defined(WITH_DATABASE)
149 { N_("set-database-severity"),
150 '-',
151 N_("Set severity threshold for logging to RDBMS"),
152 HAS_ARG_YES,
153 sh_error_set_database },
154#endif
155 { N_("set-log-severity"),
156 'l',
157 N_("Set severity threshold for logfile"),
158 HAS_ARG_YES,
159 sh_error_setlog },
160#if defined(SH_WITH_MAIL)
161 { N_("set-mail-severity"),
162 'm',
163 N_("Set severitythreshold for e-mail"),
164 HAS_ARG_YES,
165 sh_error_setseverity },
166#endif
167 { N_("set-print-severity"),
168 'p',
169 N_("Set the severity threshold for terminal/console log"),
170 HAS_ARG_YES,
171 sh_error_setprint },
172#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
173 { N_("recursion"),
174 'r',
175 N_("Set recursion level for directories"),
176 HAS_ARG_YES,
177 sh_files_setrecursion },
178#endif
179 { N_("verify-log"),
180 'L',
181 N_("Verify the audit trail"),
182 HAS_ARG_YES,
183 sh_error_logverify },
184 { N_("just-list"),
185 'j',
186 N_("Modify -L to just list the audit trail"),
187 HAS_ARG_NO,
188 sh_error_logverify_mod },
189#if defined(SH_WITH_MAIL)
190 { N_("verify-mail"),
191 'M',
192 N_("Verify the mailbox"),
193 HAS_ARG_YES,
194 sh_mail_sigverify
195 },
196#endif
197 { N_("add-key"),
198 'V',
199 N_("Add key for the mail/log signature"),
200 HAS_ARG_YES,
201 sh_util_set_newkey
202 },
203 { N_("hash-string"),
204 'H',
205 N_("Print the hash of a string"),
206 HAS_ARG_YES,
207 sh_error_verify },
208#if defined (SH_WITH_SERVER)
209 { N_("password"),
210 'P',
211 N_("Compute a client registry entry for password"),
212 HAS_ARG_YES,
213 sh_forward_make_client },
214 { N_("gen-password"),
215 'G',
216 N_("Generate a random password"),
217 HAS_ARG_NO,
218 sh_forward_create_password },
219#endif
220
221#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
222 { N_("forever"),
223 'f',
224 N_("Loop forever, even if not daemon"),
225 HAS_ARG_NO,
226 sh_getopt_forever},
[169]227 { N_("list-file"),
228 '-',
229 N_("Modify -d to list content of a single file"),
230 HAS_ARG_YES,
231 set_list_file},
[1]232 { N_("full-detail"),
233 'a',
234 N_("Modify -d to list full details"),
235 HAS_ARG_NO,
236 set_full_detail},
237 { N_("delimited"),
238 '-',
239 N_("Modify -d to list full details, comma delimited"),
240 HAS_ARG_NO,
241 set_list_delimited},
242 { N_("list-database"),
243 'd',
244 N_("List database content (like ls -l)"),
245 HAS_ARG_YES,
246 sh_hash_list_db},
247 { N_("init2stdout"),
248 '-',
249 N_("Write database to stdout on init"),
250 HAS_ARG_NO,
251 sh_hash_pushdata_stdout},
252#endif
253 { N_("trace-logfile"),
254 '-',
255 N_("Logfile for trace"),
256 HAS_ARG_YES,
257 sl_trace_file },
258 { N_("trace-enable"),
259 '-',
260 N_("Enable tracing"),
261 HAS_ARG_NO,
262 sl_trace_use },
263 { N_("copyright"),
264 'c',
265 N_("Print copyright information"),
266 HAS_ARG_NO,
267 sh_getopt_copyright },
268 { N_("help"),
269 'h',
270 N_("Print usage information"),
271 HAS_ARG_NO,
272 sh_getopt_usage },
[76]273 { N_("version"),
274 'v',
275 N_("Show version and compiled-in options"),
276 HAS_ARG_NO,
277 sh_getopt_version },
[181]278#if defined(HAVE_LIBPRELUDE)
[20]279 /* need to skip over these */
280 { N_("prelude"),
281 '-',
282 N_("Prelude generic options"),
283 HAS_ARG_NO,
284 NULL },
285 { N_("profile"),
286 '-',
287 N_("Profile to use for this analyzer"),
288 HAS_ARG_YES,
289 NULL },
290 { N_("heartbeat-interval"),
291 '-',
292 N_("Number of seconds between two heartbeats"),
293 HAS_ARG_YES,
294 NULL },
295 { N_("server-addr"),
296 '-',
297 N_("Address where this sensor should report to"),
298 HAS_ARG_YES,
299 NULL },
300 { N_("analyzer-name"),
301 '-',
302 N_("Name for this analyzer"),
303 HAS_ARG_YES,
304 NULL },
305#endif
[1]306 /* last entry -- required !! -- */
307 { NULL,
308 '\0',
309 NULL,
310 HAS_ARG_NO,
311 NULL }
312};
313
[76]314
[170]315static void sh_getopt_print_log_facilities (void)
[76]316{
[171]317 int num = 0;
[76]318
[171]319 fputs (_("Compiled-in log facilities:\n"), stdout);
320
[76]321#ifndef DEFAULT_CONSOLE
[171]322 if (num > 0) fputc ('\n', stdout);
[210]323 printf ("%s", _(" console (/dev/console)")); ++num;
[76]324#else
[171]325 if (num > 0) fputc ('\n', stdout);
[76]326 if (0 == strcmp (DEFAULT_CONSOLE, _("NULL")))
[210]327 { printf ("%s", _("console (/dev/console)")); ++num; }
[76]328 else
[171]329 { printf (_("console (%s)"), DEFAULT_CONSOLE); ++num; }
[76]330#endif
[171]331 if (num > 0) fputc ('\n', stdout);
332 fputs (_(" syslog"), stdout); ++num;
333 if (num > 0) fputc ('\n', stdout);
334 printf (_(" logfile (%s)"), DEFAULT_ERRFILE); ++num;
[76]335
336#if defined(WITH_EXTERNAL)
[171]337 if (num > 0) fputc ('\n', stdout);
338 fputs (_(" external program"), stdout); ++num;
[76]339#endif
340
341#if defined(WITH_MESSAGE_QUEUE)
[171]342 if (num > 0) fputc ('\n', stdout);
343 fputs (_(" message queue"), stdout); ++num;
[76]344#endif
345
346#if defined(WITH_DATABASE)
[171]347 if (num > 0) fputc ('\n', stdout);
348 fputs (_(" database"), stdout); ++num;
[76]349#ifdef WITH_ODBC
350 fputs (_(" (odbc)"), stdout);
351#endif
352#ifdef WITH_ORACLE
353 fputs (_(" (Oracle)"), stdout);
354#endif
355#ifdef WITH_POSTGRES
356 fputs (_(" (PostgreSQL)"), stdout);
357#endif
358#ifdef WITH_MYSQL
359 fputs (_(" (MySQL)"), stdout);
360#endif
361#endif
362
363#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
[171]364 if (num > 0) fputc ('\n', stdout);
365 fputs (_(" server"), stdout); ++num;
[76]366#endif
367
368#if defined(SH_WITH_MAIL)
[171]369 if (num > 0) fputc ('\n', stdout);
370 fputs (_(" email"), stdout); ++num;
[76]371#endif
372
373#ifdef HAVE_LIBPRELUDE
[171]374 if (num > 0) fputc ('\n', stdout); ++num;
[181]375 fputs (_(" prelude (0.9.6+)"), stdout);
[76]376#endif
377
[171]378 if (num == 0)
379 fputs (_(" none"), stdout);
[76]380 fputc ('\n', stdout);
381 return;
382}
383
[170]384static void sh_getopt_print_options (void)
[76]385{
386 int num = 0;
387
388
389#if defined(SH_STANDALONE)
390 if (num > 0) fputc ('\n', stdout);
391 fputs (_("Standalone executable"), stdout); ++num;
392#endif
393#if defined(SH_WITH_CLIENT)
394 if (num > 0) fputc ('\n', stdout);
395 printf (_("Client executable (port %d)"), SH_DEFAULT_PORT); ++num;
396#endif
397#if defined(SH_WITH_CLIENT)
398 if (num > 0) fputc ('\n', stdout);
399 printf (_("Server executable (port %d, user %s)"),
400 SH_DEFAULT_PORT, DEFAULT_IDENT);
401 ++num;
402#endif
[295]403#if defined(USE_IPVX)
404 fputs (_(", IPv6 supported"), stdout);
405#endif
[76]406
407 fputs (_(", compiled-in options:"), stdout);
408
[182]409#if defined(USE_SYSTEM_MALLOC)
[171]410 if (num > 0) fputc ('\n', stdout);
[210]411 fputs (_(" using system malloc"), stdout); ++num;
[171]412#else
413 if (num > 0) fputc ('\n', stdout);
[210]414 fputs (_(" using dnmalloc"), stdout); ++num;
[171]415#endif
416
[76]417#if defined(HAVE_EGD_RANDOM)
418 if (num > 0) fputc ('\n', stdout);
[171]419 printf (_(" using entropy gathering daemon (%s)"), EGD_SOCKET_NAME); ++num;
[76]420#endif
421#if defined(HAVE_UNIX_RANDOM)
422 if (num > 0) fputc ('\n', stdout);
[171]423 fputs (_(" using unix entropy gatherer"), stdout); ++num;
[76]424#endif
425#if defined(HAVE_URANDOM)
426 if (num > 0) fputc ('\n', stdout);
[171]427 printf (_(" using entropy device (%s)"), NAME_OF_DEV_RANDOM); ++num;
[76]428#endif
429
430#ifdef WITH_GPG
431 if (num > 0) fputc ('\n', stdout);
432 printf (_(" GnuPG signatures (%s)"), DEFAULT_GPG_PATH); ++num;
433#ifdef HAVE_GPG_CHECKSUM
434 if (num > 0) fputc ('\n', stdout);
435 printf (_(" -- GnuPG checksum: %s"), GPG_HASH); ++num;
436#endif
437#ifdef USE_FINGERPRINT
438 if (num > 0) fputc ('\n', stdout);
439 printf (_(" -- Key fingerprint: %s"), SH_GPG_FP); ++num;
440#endif
441#endif
442
443#if defined(SL_DEBUG)
444 if (num > 0) fputc ('\n', stdout);
[171]445 fputs (_(" debug build (do not use for production)"), stdout); ++num;
[76]446#endif
447#if defined(SCREW_IT_UP)
448 if (num > 0) fputc ('\n', stdout);
449 fputs (_(" anti-debugger"), stdout); ++num;
450#endif
451#if defined(SH_USE_XML)
452 if (num > 0) fputc ('\n', stdout);
453 fputs (_(" xml log format"), stdout); ++num;
454#endif
455#if defined(HAVE_NTIME)
456 if (num > 0) fputc ('\n', stdout);
[171]457 fputs (_(" using time server"), stdout); ++num;
[76]458#endif
[272]459#if defined(HAVE_REGEX_H)
460 if (num > 0) fputc ('\n', stdout);
461 fputs (_(" posix regex support"), stdout); ++num;
462#endif
[76]463
[272]464
[76]465#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
[169]466#if defined(HAVE_LIBZ)
467 if (num > 0) fputc ('\n', stdout);
468 fputs (_(" optionally store full text for files"), stdout); ++num;
469#endif
[294]470#if !defined(SH_COMPILE_STATIC) && defined(__linux__) && defined(HAVE_AUPARSE_H) && defined(HAVE_AUPARSE_LIB)
471 if (num > 0) fputc ('\n', stdout);
472 fputs (_(" optionally report auditd record of changed file"), stdout); ++num;
473#endif
[76]474#if defined(USE_XATTR)
475 if (num > 0) fputc ('\n', stdout);
476 fputs (_(" check SELinux attributes"), stdout); ++num;
477#endif
478#if defined(USE_ACL)
479 if (num > 0) fputc ('\n', stdout);
480 fputs (_(" check Posix ACLs"), stdout); ++num;
481#endif
482#if defined(RELOAD_DATABASE)
483 if (num > 0) fputc ('\n', stdout);
484 fputs (_(" fetch database on reload"), stdout); ++num;
485#endif
486#endif
487
488#if defined(SH_WITH_SERVER)
489
490#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(HAVE_STRUCT_CMSGCRED) && !defined(HAVE_STRUCT_FCRED) && !(defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
491 if (num > 0) fputc ('\n', stdout);
492 fputs (_(" command socket authentication: use SetSocketPassword"), stdout);
493 ++num;
494#else
495 if (num > 0) fputc ('\n', stdout);
496 fputs (_(" command socket authentication: use SetSocketAllowUID"), stdout);
497 ++num;
498#endif
499
500#if defined(SH_USE_LIBWRAP)
501 if (num > 0) fputc ('\n', stdout);
502 fputs (_(" support tcp wrapper"), stdout); ++num;
503#endif
504#if defined(INET_SYSLOG)
505 if (num > 0) fputc ('\n', stdout);
506 fputs (_(" support listening on 514/udp (syslog)"), stdout); ++num;
507#endif
508#endif
509
510 if (num == 0)
511 fputs (_(" none"), stdout);
512 fputc ('\n', stdout);
513 return;
514}
515
[170]516static void sh_getopt_print_modules (void)
[76]517{
518#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
519 int num = 0;
520
[171]521 fputs (_("Compiled-in modules:\n"), stdout);
[76]522#ifdef SH_USE_UTMP
523 if (num > 0) fputc (',', stdout);
524 fputs (_(" login/logout"), stdout); ++num;
525#endif
526#ifdef SH_USE_MOUNTS
527 if (num > 0) fputc (',', stdout);
528 fputs (_(" mount options"), stdout); ++num;
529#endif
530#ifdef SH_USE_USERFILES
531 if (num > 0) fputc (',', stdout);
532 fputs (_(" userfiles"), stdout); ++num;
533#endif
534#ifdef SH_USE_KERN
535 if (num > 0) fputc (',', stdout);
536 fputs (_(" kernel"), stdout); ++num;
537#endif
538#ifdef SH_USE_SUIDCHK
539 if (num > 0) fputc (',', stdout);
540 fputs (_(" suid"), stdout); ++num;
541#endif
542#ifdef SH_USE_PROCESSCHECK
543 if (num > 0) fputc (',', stdout);
544 fputs (_(" processes"), stdout); ++num;
545#endif
546#ifdef SH_USE_PORTCHECK
547 if (num > 0) fputc (',', stdout);
548 fputs (_(" ports"), stdout); ++num;
549#endif
[183]550#ifdef USE_LOGFILE_MONITOR
551 if (num > 0) fputc (',', stdout);
552 fputs (_(" logfile monitor"), stdout); ++num;
553#endif
[76]554 if (num == 0)
555 fputs (_(" none"), stdout);
556 fputc ('\n', stdout);
557#endif
558 return;
559}
560
561static int sh_getopt_version (const char * dummy)
562{
563 (void) dummy;
564 fprintf (stdout,
565 _("This is samhain (%s), "\
[161]566 "(c) 1999-2008 Rainer Wichmann (http://la-samhna.de).\n"),
[76]567 VERSION);
[210]568 fprintf (stdout, "%s",_("This software comes with ABSOLUTELY NO WARRANTY. "));
569 fprintf (stdout, "%s",_("Use at own risk.\n\n"));
[76]570
571 sh_getopt_print_log_facilities ();
572 sh_getopt_print_modules ();
573 sh_getopt_print_options ();
574
575 _exit (EXIT_SUCCESS);
576 /*@notreached@*/
577 return 0; /* make compilers happy */
578}
[20]579static int sh_getopt_copyright (const char * dummy)
[1]580{
[210]581 fprintf (stdout, "%s",
[161]582 _("Copyright (C) 1999-2008 Rainer Wichmann"\
[1]583 " (http://la-samhna.de).\n\n"));
584
[210]585 fprintf (stdout, "%s",
[1]586 _("This program is free software; "\
587 "you can redistribute it and/or modify\n"));
[210]588 fprintf (stdout, "%s",_("it under the terms of the GNU General "\
[1]589 "Public License as published by\n"));
[210]590 fprintf (stdout, "%s",_("the Free Software Foundation; either version 2 "\
[1]591 "of the License, or\n"));
[210]592 fprintf (stdout, "%s",_("(at your option) any later version.\n\n"));
[1]593
[210]594 fprintf (stdout, "%s",_("This program is distributed in the hope "\
[1]595 "that it will be useful,\n"));
[210]596 fprintf (stdout, "%s",_("but WITHOUT ANY WARRANTY; "\
[1]597 "without even the implied warranty of\n"));
[210]598 fprintf (stdout, "%s",_("MERCHANTABILITY or FITNESS FOR A PARTICULAR "\
599 "PURPOSE. See the\n"));
600 fprintf (stdout, "%s",_("GNU General Public License for more details.\n\n"));
[1]601
[210]602 fprintf (stdout, "%s",_("You should have received a copy of the "\
[1]603 "GNU General Public License\n"));
[210]604 fprintf (stdout, "%s",_("along with this program; "\
[1]605 "if not, write to the Free Software\n"));
[210]606 fprintf (stdout, "%s",_("Foundation, Inc., 59 Temple Place - Suite 330, "\
[1]607 "Boston, MA 02111-1307, USA.\n\n"));
608
[210]609 fprintf (stdout, "%s",_("This product makes use of the reference "\
610 "implementation of the TIGER message\n"));
611 fprintf (stdout, "%s",_("digest algorithm. This code is copyright Eli Biham "\
[1]612 "(biham@cs.technion.ac.il)\n"));
[210]613 fprintf (stdout, "%s",_("and Ross Anderson (rja14@cl.cam.ac.uk). It can be used "\
[1]614 "freely without any\n"));
[210]615 fprintf (stdout, "%s",_("restrictions.\n"));
[1]616#if defined(USE_SRP_PROTOCOL) && !defined(SH_STANDALONE)
617#if (!defined(HAVE_LIBGMP) || !defined(HAVE_GMP_H))
[210]618 fprintf (stdout, "%s",_("This product makes use of the 'bignum' library by "\
[1]619 "Henrik Johansson\n"));
[210]620 fprintf (stdout, "%s",_("(Henrik.Johansson@Nexus.Comm.SE). If you are "\
621 "including this library in a\n"));
622 fprintf (stdout, "%s",_("commercial product, be sure to distribute ALL of"\
[1]623 " it with the product.\n"));
624#endif
[210]625 fprintf (stdout, "%s",_("This product uses the 'Secure Remote Password' "\
[1]626 "cryptographic\n"));
[210]627 fprintf (stdout, "%s",_("authentication system developed by Tom Wu "\
[1]628 "(tjw@CS.Stanford.EDU).\n"));
629#endif
[210]630 fprintf (stdout, "%s",_("\nPlease refer to the file COPYING in the source "\
[1]631 "distribution for a"));
[210]632 fprintf (stdout, "%s",_("\nfull list of incorporated code and associated "\
[1]633 "licenses.\n"));
634
635 if (dummy)
636 _exit (EXIT_SUCCESS);
637 else
638 _exit (EXIT_SUCCESS);
639 /*@notreached@*/
640 return 0; /* make compilers happy */
641}
642
643/*@noreturn@*/
[20]644static int sh_getopt_usage (const char * dummy)
[1]645{
646 int i;
647 char fmt[64];
648
649 char opts[64];
650
651 for (i = 0; i < 64; ++i) /* splint does not grok char opts[64] = { '\0' }; */
652 opts[i] = '\0';
653
654 fprintf (stdout,
655 _("This is samhain (%s), "\
[76]656 "(c) 1999-2006 Rainer Wichmann (http://la-samhna.de).\n"),
[1]657 VERSION);
[210]658 fprintf (stdout, "%s",_("This software comes with ABSOLUTELY NO WARRANTY. "));
659 fprintf (stdout, "%s",_("Use at own risk.\n"));
[1]660
[210]661 fprintf (stdout, "%s",_("Usage:\n\n"));
[1]662
663 for (i = 0; op_table[i].longopt != NULL; ++i) {
664
665 if (i == 63)
666 break;
667
668 if (op_table[i].shortopt != '-' &&
669 strchr(opts, op_table[i].shortopt) != NULL)
[210]670 fprintf (stdout, "%s",_("Short option char collision !\n"));
[1]671 opts[i] = op_table[i].shortopt;
672
673
674 if (op_table[i].hasArg == HAS_ARG_NO) {
675 if (sl_strlen(op_table[i].longopt) < 10)
[22]676 sl_strlcpy(fmt,_("%c%c%c --%-s,\t\t\t %s\n"), sizeof(fmt));
[1]677 else if (sl_strlen(op_table[i].longopt) < 17)
[22]678 sl_strlcpy(fmt, _("%c%c%c --%-s,\t\t %s\n"), sizeof(fmt));
[1]679 else
[22]680 sl_strlcpy(fmt, _("%c%c%c --%-s,\t %s\n"), sizeof(fmt));
681 /* flawfinder: ignore */
682 fprintf (stdout, fmt,
[1]683 (op_table[i].shortopt == '-') ? ' ' : '-',
684 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
685 (op_table[i].shortopt == '-') ? ' ' : ',',
686 _(op_table[i].longopt),
687 _(op_table[i].usage));
688 } else {
689 if (sl_strlen(op_table[i].longopt) < 12)
[22]690 sl_strlcpy(fmt, _("%c%c %s --%-s=<arg>,\t\t %s\n"), sizeof(fmt));
[1]691 else
[22]692 sl_strlcpy(fmt, _("%c%c %s --%-s=<arg>,\t %s\n"), sizeof(fmt));
693 /* flawfinder: ignore */
694 fprintf (stdout, fmt,
[1]695 (op_table[i].shortopt == '-') ? ' ' : '-',
696 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
697 (op_table[i].shortopt == '-') ? _(" ") : _("<arg>,"),
698 _(op_table[i].longopt),
699 _(op_table[i].usage));
700 }
701 }
702
[210]703 fprintf (stdout, "%s",
[1]704 _("\nPlease report bugs to support@la-samhna.de.\n"));
705
706 (void) fflush(stdout);
707
708 if ( dummy != NULL)
709 {
710 if (sl_strcmp( dummy, _("fail")) == 0 )
711 _exit (EXIT_FAILURE);
712 }
713
714 _exit (EXIT_SUCCESS);
715 /*@notreached@*/
716 return 0; /* make compilers happy */
717}
718
719#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
[20]720static int sh_getopt_forever (const char * dummy)
[1]721{
[170]722 (void) dummy;
[1]723 SL_ENTER(_("sh_getopt_forever"));
724 sh.flag.loop = S_TRUE;
725 SL_RETURN(0, _("sh_getopt_forever"));
726}
727#endif
728
729int sh_getopt_get (int argc, char * argv[])
730{
731 int count = 0;
732 size_t len = 0;
733 int foundit = 0;
734 int i;
735 size_t k;
736 char * theequal;
737
738 SL_ENTER(_("sh_getopt_get"));
739
740 /* -- Return if no args. --
741 */
742 if (argc < 2)
743 SL_RETURN(0, _("sh_getopt_get"));
744
745 while (argc > 1 && argv[1][0] == '-')
746 {
747
748 /* Initialize
749 */
750 foundit = 0;
751 len = sl_strlen (argv[1]);
752
753 /* a '-' with no argument: error
754 */
755 if (len == 1)
756 (void) sh_getopt_usage(_("fail"));
757
758 /* a '--' with no argument: stop argument processing
759 */
760 if (len == 2 && argv[1][1] == '-')
761 SL_RETURN( count, _("sh_getopt_get"));
762
763 /* a short option: process it
764 */
765 if (len >= 2 && argv[1][1] != '-')
766 {
767 for (k = 1; k < len; ++k)
768 {
769 for (i = 0; op_table[i].shortopt != '\0'; ++i)
770 {
771
772 if ( op_table[i].shortopt == argv[1][k] )
773 {
774 foundit = 1;
775 if ( op_table[i].hasArg == HAS_ARG_YES )
776 {
777 if (k != (len - 1))
778 {
779 /* not last option
780 */
[210]781 fprintf (stderr, "%s",
[1]782 _("Error: short option with argument is not last in option string\n"));
783 (void) sh_getopt_usage(_("fail"));
784 }
785 if (argc < 3)
786 {
787 /* argument required, but no avail
788 */
[210]789 fprintf (stderr, "%s",
790 _("Error: missing argument\n"));
[1]791 (void) sh_getopt_usage(_("fail"));
792 }
793 else
794 {
795 /* call function with argument */
796 --argc; ++argv;
[20]797 if (NULL != op_table[i].func &&
798 0 != (* op_table[i].func )(argv[1]))
[1]799 fprintf (stderr,
[42]800 _("Error processing option -%c\n"),
[1]801 op_table[i].shortopt);
802 break;
803 }
804 }
805 else
806 {
[20]807 if (NULL != op_table[i].func &&
808 0 != (* op_table[i].func )(NULL))
[1]809 fprintf (stderr,
[42]810 _("Error processing option -%c\n"),
[1]811 op_table[i].shortopt);
812 break;
813 }
814 }
815 }
816 }
817
818 /* 'break' should get here
819 */
820 if (foundit == 1)
821 {
822 --argc; ++argv;
823 continue;
824 }
825 else
826 {
827 /* unrecognized short option */
[210]828 fprintf (stderr, "%s",_("Error: unrecognized short option\n"));
[1]829 (void) sh_getopt_usage(_("fail"));
830 }
831 }
832
833 /* a long option: process it
834 */
835 if (len > 2)
836 {
837
838 for (i = 0; op_table[i].longopt != NULL; ++i)
839 {
[27]840
[1]841 if (sl_strncmp(_(op_table[i].longopt),
842 &argv[1][2],
843 sl_strlen(op_table[i].longopt)) == 0 )
844 {
845 foundit = 1;
846 if ( op_table[i].hasArg == HAS_ARG_YES )
847 {
[27]848 theequal = strchr(argv[1], '=');
849 if (theequal == NULL)
[1]850 {
[20]851 if (argc < 3)
852 {
853 /* argument required, but no avail
854 */
[210]855 fprintf (stderr, "%s",
856 _("Error: missing argument\n"));
[20]857 (void) sh_getopt_usage(_("fail"));
858 }
859 else
860 {
861 /* call function with argument */
862 --argc; ++argv;
863 if (NULL != op_table[i].func &&
864 0 != (* op_table[i].func )(argv[1]))
865 fprintf (stderr,
[42]866 _("Error processing option -%s\n"),
[20]867 op_table[i].longopt);
868 break;
869 }
[1]870 }
871 else
872 {
873 if (sl_strlen (theequal) > 1)
874 {
875 ++theequal;
876 /* call function with argument */
[20]877 if (NULL != op_table[i].func &&
878 0 != (* op_table[i].func )(theequal))
[1]879 fprintf (stderr,
[42]880 _("Error processing option -%s\n"),
[1]881 op_table[i].longopt);
882 break;
883 }
884 else
885 {
[210]886 fprintf (stderr, "%s",
887 _("Error: invalid argument\n"));
[1]888 /* argument required, but no avail */
889 (void) sh_getopt_usage(_("fail"));
890 }
891 }
892 }
893 else
894 {
[20]895 if (NULL != op_table[i].func &&
896 0 != (* op_table[i].func )(NULL))
[1]897 fprintf (stderr,
[42]898 _("Error processing option -%s\n"),
[1]899 op_table[i].longopt);
900 break;
901 }
902 }
903 }
904
905 /* 'break' should get here */
906 if (foundit == 1)
907 {
908 ++count;
909 --argc;
910 ++argv;
911 continue;
912 }
913 else
914 {
915 /* unrecognized long option */
[210]916 fprintf (stderr, "%s",_("Error: unrecognized long option\n"));
[1]917 (void) sh_getopt_usage(_("fail"));
918 }
919 }
920 }
921
922 SL_RETURN( count, _("sh_getopt_get"));
923}
Note: See TracBrowser for help on using the repository browser.