source: trunk/src/sh_getopt.c@ 499

Last change on this file since 499 was 485, checked in by katerina, 9 years ago

Fix for ticket #383 (shell expansion capability not reported).

File size: 26.1 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_("wait-on-check"),
294 'w',
295 N_("Timed wait for end of filecheck (0 for no timeout)"),
296 HAS_ARG_YES,
297 sh_sem_wait},
298#endif
299 { N_("trace-logfile"),
300 '-',
301 N_("Logfile for trace"),
302 HAS_ARG_YES,
303 sl_trace_file },
304 { N_("trace-enable"),
305 '-',
306 N_("Enable tracing"),
307 HAS_ARG_NO,
308 sl_trace_use },
309 { N_("copyright"),
310 'c',
311 N_("Print copyright information"),
312 HAS_ARG_NO,
313 sh_getopt_copyright },
314 { N_("help"),
315 'h',
316 N_("Print usage information"),
317 HAS_ARG_NO,
318 sh_getopt_usage },
319 { N_("version"),
320 'v',
321 N_("Show version and compiled-in options"),
322 HAS_ARG_NO,
323 sh_getopt_version },
324#if defined(HAVE_LIBPRELUDE)
325 /* need to skip over these */
326 { N_("prelude"),
327 '-',
328 N_("Prelude generic options"),
329 HAS_ARG_NO,
330 NULL },
331 { N_("profile"),
332 '-',
333 N_("Profile to use for this analyzer"),
334 HAS_ARG_YES,
335 NULL },
336 { N_("heartbeat-interval"),
337 '-',
338 N_("Number of seconds between two heartbeats"),
339 HAS_ARG_YES,
340 NULL },
341 { N_("server-addr"),
342 '-',
343 N_("Address where this sensor should report to"),
344 HAS_ARG_YES,
345 NULL },
346 { N_("analyzer-name"),
347 '-',
348 N_("Name for this analyzer"),
349 HAS_ARG_YES,
350 NULL },
351#endif
352 /* last entry -- required !! -- */
353 { NULL,
354 '\0',
355 NULL,
356 HAS_ARG_NO,
357 NULL }
358};
359
360
361static void sh_getopt_print_log_facilities (void)
362{
363 int num = 0;
364
365 fputs (_("Compiled-in log facilities:\n"), stdout);
366
367#ifndef DEFAULT_CONSOLE
368 if (num > 0) fputc ('\n', stdout);
369 printf ("%s", _(" console (/dev/console)")); ++num;
370#else
371 if (num > 0) fputc ('\n', stdout);
372 if (0 == strcmp (DEFAULT_CONSOLE, _("NULL")))
373 { printf ("%s", _("console (/dev/console)")); ++num; }
374 else
375 { printf (_("console (%s)"), DEFAULT_CONSOLE); ++num; }
376#endif
377 if (num > 0) fputc ('\n', stdout);
378 fputs (_(" syslog"), stdout); ++num;
379 if (num > 0) fputc ('\n', stdout);
380 printf (_(" logfile (%s)"), DEFAULT_ERRFILE); ++num;
381
382#if defined(WITH_EXTERNAL)
383 if (num > 0) fputc ('\n', stdout);
384 fputs (_(" external program"), stdout); ++num;
385#endif
386
387#if defined(WITH_MESSAGE_QUEUE)
388 if (num > 0) fputc ('\n', stdout);
389 fputs (_(" message queue"), stdout); ++num;
390#endif
391
392#if defined(WITH_DATABASE)
393 if (num > 0) fputc ('\n', stdout);
394 fputs (_(" database"), stdout); ++num;
395#ifdef WITH_ODBC
396 fputs (_(" (odbc)"), stdout);
397#endif
398#ifdef WITH_ORACLE
399 fputs (_(" (Oracle)"), stdout);
400#endif
401#ifdef WITH_POSTGRES
402 fputs (_(" (PostgreSQL)"), stdout);
403#endif
404#ifdef WITH_MYSQL
405 fputs (_(" (MySQL)"), stdout);
406#endif
407#endif
408
409#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
410 if (num > 0) fputc ('\n', stdout);
411 fputs (_(" server"), stdout); ++num;
412#endif
413
414#if defined(SH_WITH_MAIL)
415 if (num > 0) fputc ('\n', stdout);
416 fputs (_(" email"), stdout); ++num;
417#endif
418
419#ifdef HAVE_LIBPRELUDE
420 if (num > 0) fputc ('\n', stdout); ++num;
421 fputs (_(" prelude (0.9.6+)"), stdout);
422#endif
423
424 if (num == 0)
425 fputs (_(" none"), stdout);
426 fputc ('\n', stdout);
427 return;
428}
429
430static void sh_getopt_print_options (void)
431{
432 int num = 0;
433
434
435#if defined(SH_STANDALONE)
436 if (num > 0) fputc ('\n', stdout);
437 fputs (_("Standalone executable"), stdout); ++num;
438#endif
439#if defined(SH_WITH_CLIENT)
440 if (num > 0) fputc ('\n', stdout);
441 printf (_("Client executable (port %d)"), SH_DEFAULT_PORT); ++num;
442#endif
443#if defined(SH_WITH_SERVER)
444 if (num > 0) fputc ('\n', stdout);
445 printf (_("Server executable (port %d, user %s)"),
446 SH_DEFAULT_PORT, DEFAULT_IDENT);
447 ++num;
448#endif
449#if defined(USE_IPVX)
450 fputs (_(", IPv6 supported"), stdout);
451#endif
452
453 fputs (_(", compiled-in options:"), stdout);
454
455#if defined(USE_SYSTEM_MALLOC)
456 if (num > 0) fputc ('\n', stdout);
457 fputs (_(" using system malloc"), stdout); ++num;
458#else
459 if (num > 0) fputc ('\n', stdout);
460 fputs (_(" using dnmalloc"), stdout); ++num;
461#endif
462
463#if defined(HAVE_EGD_RANDOM)
464 if (num > 0) fputc ('\n', stdout);
465 printf (_(" using entropy gathering daemon (%s)"), EGD_SOCKET_NAME); ++num;
466#endif
467#if defined(HAVE_UNIX_RANDOM)
468 if (num > 0) fputc ('\n', stdout);
469 fputs (_(" using unix entropy gatherer"), stdout); ++num;
470#endif
471#if defined(HAVE_URANDOM)
472 if (num > 0) fputc ('\n', stdout);
473 printf (_(" using entropy device (%s)"), NAME_OF_DEV_RANDOM); ++num;
474#endif
475
476#ifdef WITH_GPG
477 if (num > 0) fputc ('\n', stdout);
478 printf (_(" GnuPG signatures (%s)"), DEFAULT_GPG_PATH); ++num;
479#ifdef HAVE_GPG_CHECKSUM
480 if (num > 0) fputc ('\n', stdout);
481 printf (_(" -- GnuPG checksum: %s"), GPG_HASH); ++num;
482#endif
483#ifdef USE_FINGERPRINT
484 if (num > 0) fputc ('\n', stdout);
485 printf (_(" -- Key fingerprint: %s"), SH_GPG_FP); ++num;
486#endif
487#endif
488
489#if defined(SH_EVAL_SHELL)
490 if (num > 0) fputc ('\n', stdout);
491 fputs (_(" shell expansion in configuration file supported"), stdout); ++num;
492#endif
493
494#if defined(SL_DEBUG)
495 if (num > 0) fputc ('\n', stdout);
496 fputs (_(" debug build (do not use for production)"), stdout); ++num;
497#endif
498#if defined(SCREW_IT_UP)
499 if (num > 0) fputc ('\n', stdout);
500 fputs (_(" anti-debugger"), stdout); ++num;
501#endif
502#if defined(SH_USE_XML)
503 if (num > 0) fputc ('\n', stdout);
504 fputs (_(" xml log format"), stdout); ++num;
505#endif
506#if defined(HAVE_NTIME)
507 if (num > 0) fputc ('\n', stdout);
508 fputs (_(" using time server"), stdout); ++num;
509#endif
510#if defined(HAVE_REGEX_H)
511 if (num > 0) fputc ('\n', stdout);
512 fputs (_(" posix regex support"), stdout); ++num;
513#endif
514
515
516#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
517#if defined(HAVE_LIBZ)
518 if (num > 0) fputc ('\n', stdout);
519 fputs (_(" optionally store full text for files"), stdout); ++num;
520#endif
521#if !defined(SH_COMPILE_STATIC) && defined(__linux__) && defined(HAVE_AUPARSE_H) && defined(HAVE_AUPARSE_LIB)
522 if (num > 0) fputc ('\n', stdout);
523 fputs (_(" optionally report auditd record of changed file"), stdout); ++num;
524#endif
525#if defined(USE_XATTR)
526 if (num > 0) fputc ('\n', stdout);
527 fputs (_(" check SELinux attributes"), stdout); ++num;
528#endif
529#if defined(USE_ACL)
530 if (num > 0) fputc ('\n', stdout);
531 fputs (_(" check Posix ACLs"), stdout); ++num;
532#endif
533#if defined(RELOAD_DATABASE)
534 if (num > 0) fputc ('\n', stdout);
535 fputs (_(" fetch database on reload"), stdout); ++num;
536#endif
537#endif
538
539#if defined(SH_WITH_SERVER)
540
541#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(HAVE_STRUCT_CMSGCRED) && !defined(HAVE_STRUCT_FCRED) && !(defined(HAVE_STRUCT_SOCKCRED) && defined(LOCAL_CREDS))
542 if (num > 0) fputc ('\n', stdout);
543 fputs (_(" command socket authentication: use SetSocketPassword"), stdout);
544 ++num;
545#else
546 if (num > 0) fputc ('\n', stdout);
547 fputs (_(" command socket authentication: use SetSocketAllowUID"), stdout);
548 ++num;
549#endif
550
551#if defined(SH_USE_LIBWRAP)
552 if (num > 0) fputc ('\n', stdout);
553 fputs (_(" support tcp wrapper"), stdout); ++num;
554#endif
555#if defined(INET_SYSLOG)
556 if (num > 0) fputc ('\n', stdout);
557 fputs (_(" support listening on 514/udp (syslog)"), stdout); ++num;
558#endif
559#endif
560
561 if (num == 0)
562 fputs (_(" none"), stdout);
563 fputc ('\n', stdout);
564 return;
565}
566
567static void sh_getopt_print_modules (void)
568{
569#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
570 int num = 0;
571
572 fputs (_("Compiled-in modules:\n"), stdout);
573#ifdef SH_USE_UTMP
574 if (num > 0) fputc (',', stdout);
575 fputs (_(" login/logout"), stdout); ++num;
576#endif
577#ifdef SH_USE_MOUNTS
578 if (num > 0) fputc (',', stdout);
579 fputs (_(" mount options"), stdout); ++num;
580#endif
581#ifdef SH_USE_USERFILES
582 if (num > 0) fputc (',', stdout);
583 fputs (_(" userfiles"), stdout); ++num;
584#endif
585#ifdef SH_USE_KERN
586 if (num > 0) fputc (',', stdout);
587 fputs (_(" kernel"), stdout); ++num;
588#endif
589#ifdef SH_USE_SUIDCHK
590 if (num > 0) fputc (',', stdout);
591 fputs (_(" suid"), stdout); ++num;
592#endif
593#ifdef SH_USE_PROCESSCHECK
594 if (num > 0) fputc (',', stdout);
595 fputs (_(" processes"), stdout); ++num;
596#endif
597#ifdef SH_USE_PORTCHECK
598 if (num > 0) fputc (',', stdout);
599 fputs (_(" ports"), stdout); ++num;
600#endif
601#ifdef USE_LOGFILE_MONITOR
602 if (num > 0) fputc (',', stdout);
603 fputs (_(" logfile monitor"), stdout); ++num;
604#endif
605#if defined(USE_REGISTRY_CHECK)
606 if (num > 0) fputc ('\n', stdout);
607 fputs (_(" Windows registry"), stdout); ++num;
608#endif
609 if (num == 0)
610 fputs (_(" none"), stdout);
611 fputc ('\n', stdout);
612#endif
613 return;
614}
615
616static int sh_getopt_version (const char * dummy)
617{
618 (void) dummy;
619 fprintf (stdout,
620 _("This is samhain (%s), "\
621 "(c) 1999-2008 Rainer Wichmann (http://la-samhna.de).\n"),
622 VERSION);
623 fprintf (stdout, "%s",_("This software comes with ABSOLUTELY NO WARRANTY. "));
624 fprintf (stdout, "%s",_("Use at own risk.\n\n"));
625
626 sh_getopt_print_log_facilities ();
627 sh_getopt_print_modules ();
628 sh_getopt_print_options ();
629
630 _exit (EXIT_SUCCESS);
631 /*@notreached@*/
632 return 0; /* make compilers happy */
633}
634static int sh_getopt_copyright (const char * dummy)
635{
636 fprintf (stdout, "%s",
637 _("Copyright (C) 1999-2008 Rainer Wichmann"\
638 " (http://la-samhna.de).\n\n"));
639
640 fprintf (stdout, "%s",
641 _("This program is free software; "\
642 "you can redistribute it and/or modify\n"));
643 fprintf (stdout, "%s",_("it under the terms of the GNU General "\
644 "Public License as published by\n"));
645 fprintf (stdout, "%s",_("the Free Software Foundation; either version 2 "\
646 "of the License, or\n"));
647 fprintf (stdout, "%s",_("(at your option) any later version.\n\n"));
648
649 fprintf (stdout, "%s",_("This program is distributed in the hope "\
650 "that it will be useful,\n"));
651 fprintf (stdout, "%s",_("but WITHOUT ANY WARRANTY; "\
652 "without even the implied warranty of\n"));
653 fprintf (stdout, "%s",_("MERCHANTABILITY or FITNESS FOR A PARTICULAR "\
654 "PURPOSE. See the\n"));
655 fprintf (stdout, "%s",_("GNU General Public License for more details.\n\n"));
656
657 fprintf (stdout, "%s",_("You should have received a copy of the "\
658 "GNU General Public License\n"));
659 fprintf (stdout, "%s",_("along with this program; "\
660 "if not, write to the Free Software\n"));
661 fprintf (stdout, "%s",_("Foundation, Inc., 59 Temple Place - Suite 330, "\
662 "Boston, MA 02111-1307, USA.\n\n"));
663
664 fprintf (stdout, "%s",_("This product makes use of the reference "\
665 "implementation of the TIGER message\n"));
666 fprintf (stdout, "%s",_("digest algorithm. This code is copyright Eli Biham "\
667 "(biham@cs.technion.ac.il)\n"));
668 fprintf (stdout, "%s",_("and Ross Anderson (rja14@cl.cam.ac.uk). It can be used "\
669 "freely without any\n"));
670 fprintf (stdout, "%s",_("restrictions.\n"));
671#if defined(USE_SRP_PROTOCOL) && !defined(SH_STANDALONE)
672#if (!defined(HAVE_LIBGMP) || !defined(HAVE_GMP_H))
673 fprintf (stdout, "%s",_("This product makes use of the 'bignum' library by "\
674 "Henrik Johansson\n"));
675 fprintf (stdout, "%s",_("(Henrik.Johansson@Nexus.Comm.SE). If you are "\
676 "including this library in a\n"));
677 fprintf (stdout, "%s",_("commercial product, be sure to distribute ALL of"\
678 " it with the product.\n"));
679#endif
680 fprintf (stdout, "%s",_("This product uses the 'Secure Remote Password' "\
681 "cryptographic\n"));
682 fprintf (stdout, "%s",_("authentication system developed by Tom Wu "\
683 "(tjw@CS.Stanford.EDU).\n"));
684#endif
685 fprintf (stdout, "%s",_("\nPlease refer to the file COPYING in the source "\
686 "distribution for a"));
687 fprintf (stdout, "%s",_("\nfull list of incorporated code and associated "\
688 "licenses.\n"));
689
690 if (dummy)
691 _exit (EXIT_SUCCESS);
692 else
693 _exit (EXIT_SUCCESS);
694 /*@notreached@*/
695 return 0; /* make compilers happy */
696}
697
698/*@noreturn@*/
699static int sh_getopt_usage (const char * dummy)
700{
701 int i;
702 char fmt[64];
703
704 char opts[64];
705
706 for (i = 0; i < 64; ++i) /* splint does not grok char opts[64] = { '\0' }; */
707 opts[i] = '\0';
708
709 fprintf (stdout,
710 _("This is samhain (%s), "\
711 "(c) 1999-2006 Rainer Wichmann (http://la-samhna.de).\n"),
712 VERSION);
713 fprintf (stdout, "%s",_("This software comes with ABSOLUTELY NO WARRANTY. "));
714 fprintf (stdout, "%s",_("Use at own risk.\n"));
715
716 fprintf (stdout, "%s",_("Usage:\n\n"));
717
718 for (i = 0; op_table[i].longopt != NULL; ++i) {
719
720 if (i == 63)
721 break;
722
723 if (op_table[i].shortopt != '-' &&
724 strchr(opts, op_table[i].shortopt) != NULL)
725 fprintf (stdout, "%s",_("Short option char collision !\n"));
726 opts[i] = op_table[i].shortopt;
727
728
729 if (op_table[i].hasArg == HAS_ARG_NO) {
730 if (sl_strlen(op_table[i].longopt) < 10)
731 sl_strlcpy(fmt,_("%c%c%c --%-s,\t\t\t %s\n"), sizeof(fmt));
732 else if (sl_strlen(op_table[i].longopt) < 17)
733 sl_strlcpy(fmt, _("%c%c%c --%-s,\t\t %s\n"), sizeof(fmt));
734 else
735 sl_strlcpy(fmt, _("%c%c%c --%-s,\t %s\n"), sizeof(fmt));
736 /* flawfinder: ignore */
737 fprintf (stdout, fmt,
738 (op_table[i].shortopt == '-') ? ' ' : '-',
739 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
740 (op_table[i].shortopt == '-') ? ' ' : ',',
741 _(op_table[i].longopt),
742 _(op_table[i].usage));
743 } else {
744 if (sl_strlen(op_table[i].longopt) < 12)
745 sl_strlcpy(fmt, _("%c%c %s --%-s=<arg>,\t\t %s\n"), sizeof(fmt));
746 else
747 sl_strlcpy(fmt, _("%c%c %s --%-s=<arg>,\t %s\n"), sizeof(fmt));
748 /* flawfinder: ignore */
749 fprintf (stdout, fmt,
750 (op_table[i].shortopt == '-') ? ' ' : '-',
751 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
752 (op_table[i].shortopt == '-') ? _(" ") : _("<arg>,"),
753 _(op_table[i].longopt),
754 _(op_table[i].usage));
755 }
756 }
757
758 fprintf (stdout, "%s",
759 _("\nPlease report bugs to support@la-samhna.de.\n"));
760
761 (void) fflush(stdout);
762
763 if ( dummy != NULL)
764 {
765 if (sl_strcmp( dummy, _("fail")) == 0 )
766 _exit (EXIT_FAILURE);
767 }
768
769 _exit (EXIT_SUCCESS);
770 /*@notreached@*/
771 return 0; /* make compilers happy */
772}
773
774#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
775static int sh_getopt_forever (const char * dummy)
776{
777 (void) dummy;
778 SL_ENTER(_("sh_getopt_forever"));
779 sh.flag.loop = S_TRUE;
780 SL_RETURN(0, _("sh_getopt_forever"));
781}
782
783static int sh_getopt_outpath (const char * str)
784{
785 if (str)
786 {
787 if (sh.outpath)
788 SH_FREE(sh.outpath);
789 sh.outpath = sh_util_strdup(str);
790 return 0;
791 }
792 return -1;
793}
794#endif
795
796int sh_getopt_get (int argc, char * argv[])
797{
798 int count = 0;
799 size_t len = 0;
800 int foundit = 0;
801 int i;
802 size_t k;
803 char * theequal;
804
805 SL_ENTER(_("sh_getopt_get"));
806
807 /* -- Return if no args. --
808 */
809 if (argc < 2)
810 SL_RETURN(0, _("sh_getopt_get"));
811
812 while (argc > 1 && argv[1][0] == '-')
813 {
814
815 /* Initialize
816 */
817 foundit = 0;
818 len = sl_strlen (argv[1]);
819
820 /* a '-' with no argument: error
821 */
822 if (len == 1)
823 (void) sh_getopt_usage(_("fail"));
824
825 /* a '--' with no argument: stop argument processing
826 */
827 if (len == 2 && argv[1][1] == '-')
828 SL_RETURN( count, _("sh_getopt_get"));
829
830 /* a short option: process it
831 */
832 if (len >= 2 && argv[1][1] != '-')
833 {
834 for (k = 1; k < len; ++k)
835 {
836 for (i = 0; op_table[i].shortopt != '\0'; ++i)
837 {
838
839 if ( op_table[i].shortopt == argv[1][k] )
840 {
841 foundit = 1;
842 if ( op_table[i].hasArg == HAS_ARG_YES )
843 {
844 if (k != (len - 1))
845 {
846 /* not last option
847 */
848 fprintf (stderr, "%s",
849 _("Error: short option with argument is not last in option string\n"));
850 (void) sh_getopt_usage(_("fail"));
851 }
852 if (argc < 3)
853 {
854 /* argument required, but no avail
855 */
856 fprintf (stderr, "%s",
857 _("Error: missing argument\n"));
858 (void) sh_getopt_usage(_("fail"));
859 }
860 else
861 {
862 /* call function with argument */
863 --argc; ++argv;
864 if (NULL != op_table[i].func &&
865 0 != (* op_table[i].func )(argv[1]))
866 fprintf (stderr,
867 _("Error processing option -%c\n"),
868 op_table[i].shortopt);
869 break;
870 }
871 }
872 else
873 {
874 if (NULL != op_table[i].func &&
875 0 != (* op_table[i].func )(NULL))
876 fprintf (stderr,
877 _("Error processing option -%c\n"),
878 op_table[i].shortopt);
879 break;
880 }
881 }
882 }
883 }
884
885 /* 'break' should get here
886 */
887 if (foundit == 1)
888 {
889 --argc; ++argv;
890 continue;
891 }
892 else
893 {
894 /* unrecognized short option */
895 fprintf (stderr, "%s",_("Error: unrecognized short option\n"));
896 (void) sh_getopt_usage(_("fail"));
897 }
898 }
899
900 /* a long option: process it
901 */
902 if (len > 2)
903 {
904
905 for (i = 0; op_table[i].longopt != NULL; ++i)
906 {
907
908 if (sl_strncmp(_(op_table[i].longopt),
909 &argv[1][2],
910 sl_strlen(op_table[i].longopt)) == 0 )
911 {
912 foundit = 1;
913 if ( op_table[i].hasArg == HAS_ARG_YES )
914 {
915 theequal = strchr(argv[1], '=');
916 if (theequal == NULL)
917 {
918 if (argc < 3)
919 {
920 /* argument required, but no avail
921 */
922 fprintf (stderr, "%s",
923 _("Error: missing argument\n"));
924 (void) sh_getopt_usage(_("fail"));
925 }
926 else
927 {
928 /* call function with argument */
929 --argc; ++argv;
930 if (NULL != op_table[i].func &&
931 0 != (* op_table[i].func )(argv[1]))
932 fprintf (stderr,
933 _("Error processing option -%s\n"),
934 op_table[i].longopt);
935 break;
936 }
937 }
938 else
939 {
940 if (sl_strlen (theequal) > 1)
941 {
942 ++theequal;
943 /* call function with argument */
944 if (NULL != op_table[i].func &&
945 0 != (* op_table[i].func )(theequal))
946 fprintf (stderr,
947 _("Error processing option -%s\n"),
948 op_table[i].longopt);
949 break;
950 }
951 else
952 {
953 fprintf (stderr, "%s",
954 _("Error: invalid argument\n"));
955 /* argument required, but no avail */
956 (void) sh_getopt_usage(_("fail"));
957 }
958 }
959 }
960 else
961 {
962 if (NULL != op_table[i].func &&
963 0 != (* op_table[i].func )(NULL))
964 fprintf (stderr,
965 _("Error processing option -%s\n"),
966 op_table[i].longopt);
967 break;
968 }
969 }
970 }
971
972 /* 'break' should get here */
973 if (foundit == 1)
974 {
975 ++count;
976 --argc;
977 ++argv;
978 continue;
979 }
980 else
981 {
982 /* unrecognized long option */
983 fprintf (stderr, "%s",_("Error: unrecognized long option\n"));
984 (void) sh_getopt_usage(_("fail"));
985 }
986 }
987 }
988
989 SL_RETURN( count, _("sh_getopt_get"));
990}
Note: See TracBrowser for help on using the repository browser.