source: trunk/src/sh_getopt.c @ 481

Last change on this file since 481 was 481, checked in by katerina, 6 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

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_SHELL_EVAL)
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.