source: trunk/src/sh_getopt.c@ 568

Last change on this file since 568 was 550, checked in by katerina, 5 years ago

Fix for ticket #442 (support for OpenBSD signify).

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