source: trunk/src/sh_getopt.c@ 451

Last change on this file since 451 was 422, checked in by katerina, 12 years ago

Fix for tickets #326, #327.

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