source: trunk/src/sh_getopt.c@ 376

Last change on this file since 376 was 367, checked in by katerina, 13 years ago

Modifications for ticket #265 (inotify support). Needs testing.

File size: 24.8 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_CLIENT)
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 (num == 0)
566 fputs (_(" none"), stdout);
567 fputc ('\n', stdout);
568#endif
569 return;
570}
571
572static int sh_getopt_version (const char * dummy)
573{
574 (void) dummy;
575 fprintf (stdout,
576 _("This is samhain (%s), "\
577 "(c) 1999-2008 Rainer Wichmann (http://la-samhna.de).\n"),
578 VERSION);
579 fprintf (stdout, "%s",_("This software comes with ABSOLUTELY NO WARRANTY. "));
580 fprintf (stdout, "%s",_("Use at own risk.\n\n"));
581
582 sh_getopt_print_log_facilities ();
583 sh_getopt_print_modules ();
584 sh_getopt_print_options ();
585
586 _exit (EXIT_SUCCESS);
587 /*@notreached@*/
588 return 0; /* make compilers happy */
589}
590static int sh_getopt_copyright (const char * dummy)
591{
592 fprintf (stdout, "%s",
593 _("Copyright (C) 1999-2008 Rainer Wichmann"\
594 " (http://la-samhna.de).\n\n"));
595
596 fprintf (stdout, "%s",
597 _("This program is free software; "\
598 "you can redistribute it and/or modify\n"));
599 fprintf (stdout, "%s",_("it under the terms of the GNU General "\
600 "Public License as published by\n"));
601 fprintf (stdout, "%s",_("the Free Software Foundation; either version 2 "\
602 "of the License, or\n"));
603 fprintf (stdout, "%s",_("(at your option) any later version.\n\n"));
604
605 fprintf (stdout, "%s",_("This program is distributed in the hope "\
606 "that it will be useful,\n"));
607 fprintf (stdout, "%s",_("but WITHOUT ANY WARRANTY; "\
608 "without even the implied warranty of\n"));
609 fprintf (stdout, "%s",_("MERCHANTABILITY or FITNESS FOR A PARTICULAR "\
610 "PURPOSE. See the\n"));
611 fprintf (stdout, "%s",_("GNU General Public License for more details.\n\n"));
612
613 fprintf (stdout, "%s",_("You should have received a copy of the "\
614 "GNU General Public License\n"));
615 fprintf (stdout, "%s",_("along with this program; "\
616 "if not, write to the Free Software\n"));
617 fprintf (stdout, "%s",_("Foundation, Inc., 59 Temple Place - Suite 330, "\
618 "Boston, MA 02111-1307, USA.\n\n"));
619
620 fprintf (stdout, "%s",_("This product makes use of the reference "\
621 "implementation of the TIGER message\n"));
622 fprintf (stdout, "%s",_("digest algorithm. This code is copyright Eli Biham "\
623 "(biham@cs.technion.ac.il)\n"));
624 fprintf (stdout, "%s",_("and Ross Anderson (rja14@cl.cam.ac.uk). It can be used "\
625 "freely without any\n"));
626 fprintf (stdout, "%s",_("restrictions.\n"));
627#if defined(USE_SRP_PROTOCOL) && !defined(SH_STANDALONE)
628#if (!defined(HAVE_LIBGMP) || !defined(HAVE_GMP_H))
629 fprintf (stdout, "%s",_("This product makes use of the 'bignum' library by "\
630 "Henrik Johansson\n"));
631 fprintf (stdout, "%s",_("(Henrik.Johansson@Nexus.Comm.SE). If you are "\
632 "including this library in a\n"));
633 fprintf (stdout, "%s",_("commercial product, be sure to distribute ALL of"\
634 " it with the product.\n"));
635#endif
636 fprintf (stdout, "%s",_("This product uses the 'Secure Remote Password' "\
637 "cryptographic\n"));
638 fprintf (stdout, "%s",_("authentication system developed by Tom Wu "\
639 "(tjw@CS.Stanford.EDU).\n"));
640#endif
641 fprintf (stdout, "%s",_("\nPlease refer to the file COPYING in the source "\
642 "distribution for a"));
643 fprintf (stdout, "%s",_("\nfull list of incorporated code and associated "\
644 "licenses.\n"));
645
646 if (dummy)
647 _exit (EXIT_SUCCESS);
648 else
649 _exit (EXIT_SUCCESS);
650 /*@notreached@*/
651 return 0; /* make compilers happy */
652}
653
654/*@noreturn@*/
655static int sh_getopt_usage (const char * dummy)
656{
657 int i;
658 char fmt[64];
659
660 char opts[64];
661
662 for (i = 0; i < 64; ++i) /* splint does not grok char opts[64] = { '\0' }; */
663 opts[i] = '\0';
664
665 fprintf (stdout,
666 _("This is samhain (%s), "\
667 "(c) 1999-2006 Rainer Wichmann (http://la-samhna.de).\n"),
668 VERSION);
669 fprintf (stdout, "%s",_("This software comes with ABSOLUTELY NO WARRANTY. "));
670 fprintf (stdout, "%s",_("Use at own risk.\n"));
671
672 fprintf (stdout, "%s",_("Usage:\n\n"));
673
674 for (i = 0; op_table[i].longopt != NULL; ++i) {
675
676 if (i == 63)
677 break;
678
679 if (op_table[i].shortopt != '-' &&
680 strchr(opts, op_table[i].shortopt) != NULL)
681 fprintf (stdout, "%s",_("Short option char collision !\n"));
682 opts[i] = op_table[i].shortopt;
683
684
685 if (op_table[i].hasArg == HAS_ARG_NO) {
686 if (sl_strlen(op_table[i].longopt) < 10)
687 sl_strlcpy(fmt,_("%c%c%c --%-s,\t\t\t %s\n"), sizeof(fmt));
688 else if (sl_strlen(op_table[i].longopt) < 17)
689 sl_strlcpy(fmt, _("%c%c%c --%-s,\t\t %s\n"), sizeof(fmt));
690 else
691 sl_strlcpy(fmt, _("%c%c%c --%-s,\t %s\n"), sizeof(fmt));
692 /* flawfinder: ignore */
693 fprintf (stdout, fmt,
694 (op_table[i].shortopt == '-') ? ' ' : '-',
695 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
696 (op_table[i].shortopt == '-') ? ' ' : ',',
697 _(op_table[i].longopt),
698 _(op_table[i].usage));
699 } else {
700 if (sl_strlen(op_table[i].longopt) < 12)
701 sl_strlcpy(fmt, _("%c%c %s --%-s=<arg>,\t\t %s\n"), sizeof(fmt));
702 else
703 sl_strlcpy(fmt, _("%c%c %s --%-s=<arg>,\t %s\n"), sizeof(fmt));
704 /* flawfinder: ignore */
705 fprintf (stdout, fmt,
706 (op_table[i].shortopt == '-') ? ' ' : '-',
707 (op_table[i].shortopt == '-') ? ' ' : op_table[i].shortopt,
708 (op_table[i].shortopt == '-') ? _(" ") : _("<arg>,"),
709 _(op_table[i].longopt),
710 _(op_table[i].usage));
711 }
712 }
713
714 fprintf (stdout, "%s",
715 _("\nPlease report bugs to support@la-samhna.de.\n"));
716
717 (void) fflush(stdout);
718
719 if ( dummy != NULL)
720 {
721 if (sl_strcmp( dummy, _("fail")) == 0 )
722 _exit (EXIT_FAILURE);
723 }
724
725 _exit (EXIT_SUCCESS);
726 /*@notreached@*/
727 return 0; /* make compilers happy */
728}
729
730#if defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)
731static int sh_getopt_forever (const char * dummy)
732{
733 (void) dummy;
734 SL_ENTER(_("sh_getopt_forever"));
735 sh.flag.loop = S_TRUE;
736 SL_RETURN(0, _("sh_getopt_forever"));
737}
738#endif
739
740int sh_getopt_get (int argc, char * argv[])
741{
742 int count = 0;
743 size_t len = 0;
744 int foundit = 0;
745 int i;
746 size_t k;
747 char * theequal;
748
749 SL_ENTER(_("sh_getopt_get"));
750
751 /* -- Return if no args. --
752 */
753 if (argc < 2)
754 SL_RETURN(0, _("sh_getopt_get"));
755
756 while (argc > 1 && argv[1][0] == '-')
757 {
758
759 /* Initialize
760 */
761 foundit = 0;
762 len = sl_strlen (argv[1]);
763
764 /* a '-' with no argument: error
765 */
766 if (len == 1)
767 (void) sh_getopt_usage(_("fail"));
768
769 /* a '--' with no argument: stop argument processing
770 */
771 if (len == 2 && argv[1][1] == '-')
772 SL_RETURN( count, _("sh_getopt_get"));
773
774 /* a short option: process it
775 */
776 if (len >= 2 && argv[1][1] != '-')
777 {
778 for (k = 1; k < len; ++k)
779 {
780 for (i = 0; op_table[i].shortopt != '\0'; ++i)
781 {
782
783 if ( op_table[i].shortopt == argv[1][k] )
784 {
785 foundit = 1;
786 if ( op_table[i].hasArg == HAS_ARG_YES )
787 {
788 if (k != (len - 1))
789 {
790 /* not last option
791 */
792 fprintf (stderr, "%s",
793 _("Error: short option with argument is not last in option string\n"));
794 (void) sh_getopt_usage(_("fail"));
795 }
796 if (argc < 3)
797 {
798 /* argument required, but no avail
799 */
800 fprintf (stderr, "%s",
801 _("Error: missing argument\n"));
802 (void) sh_getopt_usage(_("fail"));
803 }
804 else
805 {
806 /* call function with argument */
807 --argc; ++argv;
808 if (NULL != op_table[i].func &&
809 0 != (* op_table[i].func )(argv[1]))
810 fprintf (stderr,
811 _("Error processing option -%c\n"),
812 op_table[i].shortopt);
813 break;
814 }
815 }
816 else
817 {
818 if (NULL != op_table[i].func &&
819 0 != (* op_table[i].func )(NULL))
820 fprintf (stderr,
821 _("Error processing option -%c\n"),
822 op_table[i].shortopt);
823 break;
824 }
825 }
826 }
827 }
828
829 /* 'break' should get here
830 */
831 if (foundit == 1)
832 {
833 --argc; ++argv;
834 continue;
835 }
836 else
837 {
838 /* unrecognized short option */
839 fprintf (stderr, "%s",_("Error: unrecognized short option\n"));
840 (void) sh_getopt_usage(_("fail"));
841 }
842 }
843
844 /* a long option: process it
845 */
846 if (len > 2)
847 {
848
849 for (i = 0; op_table[i].longopt != NULL; ++i)
850 {
851
852 if (sl_strncmp(_(op_table[i].longopt),
853 &argv[1][2],
854 sl_strlen(op_table[i].longopt)) == 0 )
855 {
856 foundit = 1;
857 if ( op_table[i].hasArg == HAS_ARG_YES )
858 {
859 theequal = strchr(argv[1], '=');
860 if (theequal == NULL)
861 {
862 if (argc < 3)
863 {
864 /* argument required, but no avail
865 */
866 fprintf (stderr, "%s",
867 _("Error: missing argument\n"));
868 (void) sh_getopt_usage(_("fail"));
869 }
870 else
871 {
872 /* call function with argument */
873 --argc; ++argv;
874 if (NULL != op_table[i].func &&
875 0 != (* op_table[i].func )(argv[1]))
876 fprintf (stderr,
877 _("Error processing option -%s\n"),
878 op_table[i].longopt);
879 break;
880 }
881 }
882 else
883 {
884 if (sl_strlen (theequal) > 1)
885 {
886 ++theequal;
887 /* call function with argument */
888 if (NULL != op_table[i].func &&
889 0 != (* op_table[i].func )(theequal))
890 fprintf (stderr,
891 _("Error processing option -%s\n"),
892 op_table[i].longopt);
893 break;
894 }
895 else
896 {
897 fprintf (stderr, "%s",
898 _("Error: invalid argument\n"));
899 /* argument required, but no avail */
900 (void) sh_getopt_usage(_("fail"));
901 }
902 }
903 }
904 else
905 {
906 if (NULL != op_table[i].func &&
907 0 != (* op_table[i].func )(NULL))
908 fprintf (stderr,
909 _("Error processing option -%s\n"),
910 op_table[i].longopt);
911 break;
912 }
913 }
914 }
915
916 /* 'break' should get here */
917 if (foundit == 1)
918 {
919 ++count;
920 --argc;
921 ++argv;
922 continue;
923 }
924 else
925 {
926 /* unrecognized long option */
927 fprintf (stderr, "%s",_("Error: unrecognized long option\n"));
928 (void) sh_getopt_usage(_("fail"));
929 }
930 }
931 }
932
933 SL_RETURN( count, _("sh_getopt_get"));
934}
Note: See TracBrowser for help on using the repository browser.