source: trunk/src/sh_getopt.c@ 479

Last change on this file since 479 was 467, checked in by katerina, 10 years ago

Fix for ticket #365 (cl option to choose log server).

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