source: trunk/src/sh_getopt.c@ 362

Last change on this file since 362 was 355, checked in by katerina, 13 years ago

Patch for ticket #260 (update from file list).

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