-code deduplication in rsa sign/verify code
[oweals/gnunet.git] / src / util / getopt.c
1 /* Getopt for GNU.
2    NOTE: getopt is now part of the C library, so if you don't know what
3    "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
4    before changing it!
5
6    Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
7      Free Software Foundation, Inc.
8
9 NOTE: The canonical source of this file is maintained with the GNU C Library.
10 Bugs can be reported to bug-glibc@prep.ai.mit.edu.
11
12 This program is free software; you can redistribute it and/or modify it
13 under the terms of the GNU General Public License as published by the
14 Free Software Foundation; either version 2, or (at your option) any
15 later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
25 USA.
26
27
28 This code was heavily modified for GNUnet.
29 Copyright (C) 2006 Christian Grothoff
30 */
31
32 /**
33  * @file util/getopt.c
34  * @brief GNU style option parsing
35  *
36  * TODO: get rid of statics (make reentrant) and
37  * replace main GNU getopt parser with one that
38  * actually fits our API.
39  */
40
41 #include "platform.h"
42 #include "gnunet_common.h"
43 #include "gnunet_getopt_lib.h"
44
45 #ifdef VMS
46 #include <unixlib.h>
47 #if HAVE_STRING_H - 0
48 #include <string.h>
49 #endif
50 #endif
51
52 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
53
54 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util", syscall)
55
56 #if defined (WIN32) && !defined (__CYGWIN32__)
57 /* It's not Unix, really.  See?  Capital letters.  */
58 #include <windows.h>
59 #define getpid() GetCurrentProcessId()
60 #endif
61
62 #ifndef _
63 /* This is for other GNU distributions with internationalized messages.
64    When compiling libc, the _ macro is predefined.  */
65 #ifdef HAVE_LIBINTL_H
66 #include <libintl.h>
67 #define _(msgid)  gettext (msgid)
68 #else
69 #define _(msgid)  (msgid)
70 #endif
71 #endif
72
73 /* Describe the long-named options requested by the application.
74    The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
75    of `struct GNoption' terminated by an element containing a name which is
76    zero.
77
78    The field `has_arg' is:
79    no_argument          (or 0) if the option does not take an argument,
80    required_argument  (or 1) if the option requires an argument,
81    optional_argument   (or 2) if the option takes an optional argument.
82
83    If the field `flag' is not NULL, it points to a variable that is set
84    to the value given in the field `val' when the option is found, but
85    left unchanged if the option is not found.
86
87    To have a long-named option do something other than set an `int' to
88    a compiled-in constant, such as set a value from `GNoptarg', set the
89    option's `flag' field to zero and its `val' field to a nonzero
90    value (the equivalent single-letter option character, if there is
91    one).  For long options that have a zero `flag' field, `getopt'
92    returns the contents of the `val' field.  */
93
94 struct GNoption
95 {
96   const char *name;
97   /* has_arg can't be an enum because some compilers complain about
98    * type mismatches in all the code that assumes it is an int.  */
99   int has_arg;
100   int *flag;
101   int val;
102 };
103
104
105 /* This version of `getopt' appears to the caller like standard Unix `getopt'
106    but it behaves differently for the user, since it allows the user
107    to intersperse the options with the other arguments.
108
109    As `getopt' works, it permutes the elements of ARGV so that,
110    when it is done, all the options precede everything else.  Thus
111    all application programs are extended to handle flexible argument order.
112
113    Setting the environment variable POSIXLY_CORRECT disables permutation.
114    Then the behavior is completely standard.
115
116    GNU application programs can use a third alternative mode in which
117    they can distinguish the relative order of options and other arguments.  */
118
119 /* For communication from `getopt' to the caller.
120    When `getopt' finds an option that takes an argument,
121    the argument value is returned here.
122    Also, when `ordering' is RETURN_IN_ORDER,
123    each non-option ARGV-element is returned here.  */
124
125 static char *GNoptarg = NULL;
126
127 /* Index in ARGV of the next element to be scanned.
128    This is used for communication to and from the caller
129    and for communication between successive calls to `getopt'.
130
131    On entry to `getopt', zero means this is the first call; initialize.
132
133    When `getopt' returns -1, this is the index of the first of the
134    non-option elements that the caller should itself scan.
135
136    Otherwise, `GNoptind' communicates from one call to the next
137    how much of ARGV has been scanned so far.  */
138
139 /* 1003.2 says this must be 1 before any call.  */
140 static int GNoptind = 1;
141
142 /* The next char to be scanned in the option-element
143    in which the last option character we returned was found.
144    This allows us to pick up the scan where we left off.
145
146    If this is zero, or a null string, it means resume the scan
147    by advancing to the next ARGV-element.  */
148
149 static char *nextchar;
150
151
152 /* Describe how to deal with options that follow non-option ARGV-elements.
153
154    If the caller did not specify anything,
155    the default is REQUIRE_ORDER if the environment variable
156    POSIXLY_CORRECT is defined, PERMUTE otherwise.
157
158    REQUIRE_ORDER means don't recognize them as options;
159    stop option processing when the first non-option is seen.
160    This is what Unix does.
161    This mode of operation is selected by either setting the environment
162    variable POSIXLY_CORRECT, or using `+' as the first character
163    of the list of option characters.
164
165    PERMUTE is the default.  We GNUNET_CRYPTO_random_permute the contents of ARGV as we scan,
166    so that eventually all the non-options are at the end.  This allows options
167    to be given in any order, even with programs that were not written to
168    expect this.
169
170    RETURN_IN_ORDER is an option available to programs that were written
171    to expect GNoptions and other ARGV-elements in any order and that care about
172    the ordering of the two.  We describe each non-option ARGV-element
173    as if it were the argument of an option with character code 1.
174    Using `-' as the first character of the list of option characters
175    selects this mode of operation.
176
177    The special argument `--' forces an end of option-scanning regardless
178    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
179    `--' can cause `getopt' to return -1 with `GNoptind' != ARGC.  */
180
181 static enum
182 {
183   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
184 } ordering;
185
186 /* Value of POSIXLY_CORRECT environment variable.  */
187 static char *posixly_correct;
188
189 #ifdef  __GNU_LIBRARY__
190 /* We want to avoid inclusion of string.h with non-GNU libraries
191    because there are many ways it can cause trouble.
192    On some systems, it contains special magic macros that don't work
193    in GCC.  */
194 #include <string.h>
195 #define  my_index       strchr
196 #else
197
198 /* Avoid depending on library functions or files
199    whose names are inconsistent.  */
200
201 char *
202 getenv ();
203
204 static char *
205 my_index (const char *str,
206           int chr)
207 {
208   while (*str)
209   {
210     if (*str == chr)
211       return (char *) str;
212     str++;
213   }
214   return 0;
215 }
216
217 /* If using GCC, we can safely declare strlen this way.
218    If not using GCC, it is ok not to declare it.  */
219 #ifdef __GNUC__
220 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
221    That was relevant to code that was here before.  */
222 #if !defined (__STDC__) || !__STDC__
223 /* gcc with -traditional declares the built-in strlen to return int,
224    and has done so at least since version 2.4.5. -- rms.  */
225 extern int
226 strlen (const char *);
227 #endif /* not __STDC__ */
228 #endif /* __GNUC__ */
229
230 #endif /* not __GNU_LIBRARY__ */
231
232 /* Handle permutation of arguments.  */
233
234 /* Describe the part of ARGV that contains non-options that have
235    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
236    `last_nonopt' is the index after the last of them.  */
237
238 static int first_nonopt;
239 static int last_nonopt;
240
241 #define SWAP_FLAGS(ch1, ch2)
242
243 /* Exchange two adjacent subsequences of ARGV.
244    One subsequence is elements [first_nonopt,last_nonopt)
245    which contains all the non-options that have been skipped so far.
246    The other is elements [last_nonopt,GNoptind), which contains all
247    the options processed since those non-options were skipped.
248
249    `first_nonopt' and `last_nonopt' are relocated so that they describe
250    the new indices of the non-options in ARGV after they are moved.  */
251
252 #if defined (__STDC__) && __STDC__
253 static void
254 exchange (char **);
255 #endif
256
257 static void
258 exchange (char **argv)
259 {
260   int bottom = first_nonopt;
261   int middle = last_nonopt;
262   int top = GNoptind;
263   char *tem;
264
265   /* Exchange the shorter segment with the far end of the longer segment.
266    * That puts the shorter segment into the right place.
267    * It leaves the longer segment in the right place overall,
268    * but it consists of two parts that need to be swapped next.  */
269
270   while (top > middle && middle > bottom)
271   {
272     if (top - middle > middle - bottom)
273     {
274       /* Bottom segment is the short one.  */
275       int len = middle - bottom;
276       register int i;
277
278       /* Swap it with the top part of the top segment.  */
279       for (i = 0; i < len; i++)
280       {
281         tem = argv[bottom + i];
282         argv[bottom + i] = argv[top - (middle - bottom) + i];
283         argv[top - (middle - bottom) + i] = tem;
284         SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
285       }
286       /* Exclude the moved bottom segment from further swapping.  */
287       top -= len;
288     }
289     else
290     {
291       /* Top segment is the short one.  */
292       int len = top - middle;
293       register int i;
294
295       /* Swap it with the bottom part of the bottom segment.  */
296       for (i = 0; i < len; i++)
297       {
298         tem = argv[bottom + i];
299         argv[bottom + i] = argv[middle + i];
300         argv[middle + i] = tem;
301         SWAP_FLAGS (bottom + i, middle + i);
302       }
303       /* Exclude the moved top segment from further swapping.  */
304       bottom += len;
305     }
306   }
307
308   /* Update records for the slots the non-options now occupy.  */
309
310   first_nonopt += (GNoptind - last_nonopt);
311   last_nonopt = GNoptind;
312 }
313
314 /* Initialize the internal data when the first call is made.  */
315
316 #if defined (__STDC__) && __STDC__
317 static const char *
318 _getopt_initialize (int, char *const *, const char *);
319 #endif
320 static const char *
321 _getopt_initialize (int argc,
322                     char *const *argv,
323                     const char *optstring)
324 {
325   /* Start processing options with ARGV-element 1 (since ARGV-element 0
326    * is the program name); the sequence of previously skipped
327    * non-option ARGV-elements is empty.  */
328
329   first_nonopt = last_nonopt = GNoptind;
330
331   nextchar = NULL;
332
333   posixly_correct = getenv ("POSIXLY_CORRECT");
334
335   /* Determine how to handle the ordering of options and nonoptions.  */
336
337   if (optstring[0] == '-')
338   {
339     ordering = RETURN_IN_ORDER;
340     ++optstring;
341   }
342   else if (optstring[0] == '+')
343   {
344     ordering = REQUIRE_ORDER;
345     ++optstring;
346   }
347   else if (posixly_correct != NULL)
348     ordering = REQUIRE_ORDER;
349   else
350     ordering = PERMUTE;
351
352   return optstring;
353 }
354
355 /* Scan elements of ARGV (whose length is ARGC) for option characters
356    given in OPTSTRING.
357
358    If an element of ARGV starts with '-', and is not exactly "-" or "--",
359    then it is an option element.  The characters of this element
360    (aside from the initial '-') are option characters.  If `getopt'
361    is called repeatedly, it returns successively each of the option characters
362    from each of the option elements.
363
364    If `getopt' finds another option character, it returns that character,
365    updating `GNoptind' and `nextchar' so that the next call to `getopt' can
366    resume the scan with the following option character or ARGV-element.
367
368    If there are no more option characters, `getopt' returns -1.
369    Then `GNoptind' is the index in ARGV of the first ARGV-element
370    that is not an option.  (The ARGV-elements have been permuted
371    so that those that are not options now come last.)
372
373    OPTSTRING is a string containing the legitimate option characters.
374    If an option character is seen that is not listed in OPTSTRING,
375    return '?' after printing an error message.  If you set `GNopterr' to
376    zero, the error message is suppressed but we still return '?'.
377
378    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
379    so the following text in the same ARGV-element, or the text of the following
380    ARGV-element, is returned in `GNoptarg'.  Two colons mean an option that
381    wants an optional arg; if there is text in the current ARGV-element,
382    it is returned in `GNoptarg', otherwise `GNoptarg' is set to zero.
383
384    If OPTSTRING starts with `-' or `+', it requests different methods of
385    handling the non-option ARGV-elements.
386    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
387
388    Long-named options begin with `--' instead of `-'.
389    Their names may be abbreviated as long as the abbreviation is unique
390    or is an exact match for some defined option.  If they have an
391    argument, it follows the option name in the same ARGV-element, separated
392    from the option name by a `=', or else the in next ARGV-element.
393    When `getopt' finds a long-named option, it returns 0 if that option's
394    `flag' field is nonzero, the value of the option's `val' field
395    if the `flag' field is zero.
396
397    The elements of ARGV aren't really const, because we GNUNET_CRYPTO_random_permute them.
398    But we pretend they're const in the prototype to be compatible
399    with other systems.
400
401    LONGOPTS is a vector of `struct GNoption' terminated by an
402    element containing a name which is zero.
403
404    LONGIND returns the index in LONGOPT of the long-named option found.
405    It is only valid when a long-named option has been found by the most
406    recent call.
407
408    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
409    long-named options.  */
410
411 static int
412 GN_getopt_internal (int argc, char *const *argv, const char *optstring,
413                     const struct GNoption *longopts, int *longind,
414                     int long_only)
415 {
416   static int __getopt_initialized = 0;
417   static int GNopterr = 1;
418
419   GNoptarg = NULL;
420
421   if (GNoptind == 0 || !__getopt_initialized)
422   {
423     if (GNoptind == 0)
424       GNoptind = 1;             /* Don't scan ARGV[0], the program name.  */
425     optstring = _getopt_initialize (argc, argv, optstring);
426     __getopt_initialized = 1;
427   }
428
429   /* Test whether ARGV[GNoptind] points to a non-option argument.
430    * Either it does not have option syntax, or there is an environment flag
431    * from the shell indicating it is not an option.  The later information
432    * is only used when the used in the GNU libc.  */
433 #define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0')
434
435   if (nextchar == NULL || *nextchar == '\0')
436   {
437     /* Advance to the next ARGV-element.  */
438
439     /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
440      * moved back by the user (who may also have changed the arguments).  */
441     if (last_nonopt > GNoptind)
442       last_nonopt = GNoptind;
443     if (first_nonopt > GNoptind)
444       first_nonopt = GNoptind;
445
446     if (ordering == PERMUTE)
447     {
448       /* If we have just processed some options following some non-options,
449        * exchange them so that the options come first.  */
450
451       if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
452         exchange ((char **) argv);
453       else if (last_nonopt != GNoptind)
454         first_nonopt = GNoptind;
455
456       /* Skip any additional non-options
457        * and extend the range of non-options previously skipped.  */
458
459       while (GNoptind < argc && NONOPTION_P)
460         GNoptind++;
461       last_nonopt = GNoptind;
462     }
463
464     /* The special ARGV-element `--' means premature end of options.
465      * Skip it like a null option,
466      * then exchange with previous non-options as if it were an option,
467      * then skip everything else like a non-option.  */
468     if (GNoptind != argc && !strcmp (argv[GNoptind], "--"))
469     {
470       GNoptind++;
471
472       if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
473         exchange ((char **) argv);
474       else if (first_nonopt == last_nonopt)
475         first_nonopt = GNoptind;
476       last_nonopt = argc;
477
478       GNoptind = argc;
479     }
480
481     /* If we have done all the ARGV-elements, stop the scan
482      * and back over any non-options that we skipped and permuted.  */
483
484     if (GNoptind == argc)
485     {
486       /* Set the next-arg-index to point at the non-options
487        * that we previously skipped, so the caller will digest them.  */
488       if (first_nonopt != last_nonopt)
489         GNoptind = first_nonopt;
490       return -1;
491     }
492
493     /* If we have come to a non-option and did not permute it,
494      * either stop the scan or describe it to the caller and pass it by.  */
495
496     if (NONOPTION_P)
497     {
498       if (ordering == REQUIRE_ORDER)
499         return -1;
500       GNoptarg = argv[GNoptind++];
501       return 1;
502     }
503
504     /* We have found another option-ARGV-element.
505      * Skip the initial punctuation.  */
506
507     nextchar =
508         (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
509   }
510
511   /* Decode the current option-ARGV-element.  */
512
513   /* Check whether the ARGV-element is a long option.
514    *
515    * If long_only and the ARGV-element has the form "-f", where f is
516    * a valid short option, don't consider it an abbreviated form of
517    * a long option that starts with f.  Otherwise there would be no
518    * way to give the -f short option.
519    *
520    * On the other hand, if there's a long option "fubar" and
521    * the ARGV-element is "-fu", do consider that an abbreviation of
522    * the long option, just like "--fu", and not "-f" with arg "u".
523    *
524    * This distinction seems to be the most useful approach.  */
525
526   if (longopts != NULL &&
527       (argv[GNoptind][1] == '-' ||
528        (long_only &&
529         (argv[GNoptind][2] || !my_index (optstring, argv[GNoptind][1])))))
530   {
531     char *nameend;
532     const struct GNoption *p;
533     const struct GNoption *pfound = NULL;
534     int exact = 0;
535     int ambig = 0;
536     int indfound = -1;
537     int option_index;
538
539     for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
540       /* Do nothing.  */ ;
541
542     /* Test all long options for either exact match
543      * or abbreviated matches.  */
544     for (p = longopts, option_index = 0; p->name; p++, option_index++)
545       if (!strncmp (p->name, nextchar, nameend - nextchar))
546       {
547         if ((unsigned int) (nameend - nextchar) ==
548             (unsigned int) strlen (p->name))
549         {
550           /* Exact match found.  */
551           pfound = p;
552           indfound = option_index;
553           exact = 1;
554           break;
555         }
556         else if (pfound == NULL)
557         {
558           /* First nonexact match found.  */
559           pfound = p;
560           indfound = option_index;
561         }
562         else
563           /* Second or later nonexact match found.  */
564           ambig = 1;
565       }
566
567     if (ambig && !exact)
568     {
569       if (GNopterr)
570         FPRINTF (stderr, _("%s: option `%s' is ambiguous\n"), argv[0],
571                  argv[GNoptind]);
572       nextchar += strlen (nextchar);
573       GNoptind++;
574       return '?';
575     }
576
577     if (pfound != NULL)
578     {
579       option_index = indfound;
580       GNoptind++;
581       if (*nameend)
582       {
583         /* Don't test has_arg with >, because some C compilers don't
584          * allow it to be used on enums.  */
585         if (pfound->has_arg)
586           GNoptarg = nameend + 1;
587         else
588         {
589           if (GNopterr)
590           {
591             if (argv[GNoptind - 1][1] == '-')
592               /* --option */
593               FPRINTF (stderr,
594                        _("%s: option `--%s' does not allow an argument\n"),
595                        argv[0], pfound->name);
596             else
597               /* +option or -option */
598               FPRINTF (stderr,
599                        _("%s: option `%c%s' does not allow an argument\n"),
600                        argv[0], argv[GNoptind - 1][0], pfound->name);
601           }
602           nextchar += strlen (nextchar);
603           return '?';
604         }
605       }
606       else if (pfound->has_arg == 1)
607       {
608         if (GNoptind < argc)
609         {
610           GNoptarg = argv[GNoptind++];
611         }
612         else
613         {
614           if (GNopterr)
615           {
616             FPRINTF (stderr, _("%s: option `%s' requires an argument\n"),
617                      argv[0], argv[GNoptind - 1]);
618           }
619           nextchar += strlen (nextchar);
620           return (optstring[0] == ':') ? ':' : '?';
621         }
622       }
623       nextchar += strlen (nextchar);
624       if (longind != NULL)
625         *longind = option_index;
626       if (pfound->flag)
627       {
628         *(pfound->flag) = pfound->val;
629         return 0;
630       }
631       return pfound->val;
632     }
633
634     /* Can't find it as a long option.  If this is not getopt_long_only,
635      * or the option starts with '--' or is not a valid short
636      * option, then it's an error.
637      * Otherwise interpret it as a short option.  */
638     if (!long_only || argv[GNoptind][1] == '-' ||
639         my_index (optstring, *nextchar) == NULL)
640     {
641       if (GNopterr)
642       {
643         if (argv[GNoptind][1] == '-')
644           /* --option */
645           FPRINTF (stderr, _("%s: unrecognized option `--%s'\n"), argv[0],
646                    nextchar);
647         else
648           /* +option or -option */
649           FPRINTF (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0],
650                    argv[GNoptind][0], nextchar);
651       }
652       nextchar = (char *) "";
653       GNoptind++;
654       return '?';
655     }
656   }
657
658   /* Look at and handle the next short option-character.  */
659
660   {
661     char c = *nextchar++;
662     char *temp = my_index (optstring, c);
663
664     /* Increment `GNoptind' when we start to process its last character.  */
665     if (*nextchar == '\0')
666       ++GNoptind;
667
668     if (temp == NULL || c == ':')
669     {
670       if (GNopterr)
671       {
672         if (posixly_correct)
673           /* 1003.2 specifies the format of this message.  */
674           FPRINTF (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
675         else
676           FPRINTF (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
677       }
678       return '?';
679     }
680     /* Convenience. Treat POSIX -W foo same as long option --foo */
681     if (temp[0] == 'W' && temp[1] == ';')
682     {
683       char *nameend;
684       const struct GNoption *p;
685       const struct GNoption *pfound = NULL;
686       int exact = 0;
687       int ambig = 0;
688       int indfound = 0;
689       int option_index;
690
691       /* This is an option that requires an argument.  */
692       if (*nextchar != '\0')
693       {
694         GNoptarg = nextchar;
695         /* If we end this ARGV-element by taking the rest as an arg,
696          * we must advance to the next element now.  */
697         GNoptind++;
698       }
699       else if (GNoptind == argc)
700       {
701         if (GNopterr)
702         {
703           /* 1003.2 specifies the format of this message.  */
704           FPRINTF (stderr, _("%s: option requires an argument -- %c\n"),
705                    argv[0], c);
706         }
707         if (optstring[0] == ':')
708           c = ':';
709         else
710           c = '?';
711         return c;
712       }
713       else
714         /* We already incremented `GNoptind' once;
715          * increment it again when taking next ARGV-elt as argument.  */
716         GNoptarg = argv[GNoptind++];
717
718       /* GNoptarg is now the argument, see if it's in the
719        * table of longopts.  */
720
721       for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
722            nameend++)
723         /* Do nothing.  */ ;
724
725       /* Test all long options for either exact match
726        * or abbreviated matches.  */
727       if (longopts != NULL)
728         for (p = longopts, option_index = 0; p->name; p++, option_index++)
729           if (!strncmp (p->name, nextchar, nameend - nextchar))
730           {
731             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
732             {
733               /* Exact match found.  */
734               pfound = p;
735               indfound = option_index;
736               exact = 1;
737               break;
738             }
739             else if (pfound == NULL)
740             {
741               /* First nonexact match found.  */
742               pfound = p;
743               indfound = option_index;
744             }
745             else
746               /* Second or later nonexact match found.  */
747               ambig = 1;
748           }
749       if (ambig && !exact)
750       {
751         if (GNopterr)
752           FPRINTF (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0],
753                    argv[GNoptind]);
754         nextchar += strlen (nextchar);
755         GNoptind++;
756         return '?';
757       }
758       if (pfound != NULL)
759       {
760         option_index = indfound;
761         if (*nameend)
762         {
763           /* Don't test has_arg with >, because some C compilers don't
764            * allow it to be used on enums.  */
765           if (pfound->has_arg)
766             GNoptarg = nameend + 1;
767           else
768           {
769             if (GNopterr)
770               FPRINTF (stderr, _("%s: option `-W %s' does not allow an argument\n"), argv[0], pfound->name);
771
772             nextchar += strlen (nextchar);
773             return '?';
774           }
775         }
776         else if (pfound->has_arg == 1)
777         {
778           if (GNoptind < argc)
779             GNoptarg = argv[GNoptind++];
780           else
781           {
782             if (GNopterr)
783               FPRINTF (stderr, _("%s: option `%s' requires an argument\n"),
784                        argv[0], argv[GNoptind - 1]);
785             nextchar += strlen (nextchar);
786             return optstring[0] == ':' ? ':' : '?';
787           }
788         }
789         nextchar += strlen (nextchar);
790         if (longind != NULL)
791           *longind = option_index;
792         if (pfound->flag)
793         {
794           *(pfound->flag) = pfound->val;
795           return 0;
796         }
797         return pfound->val;
798       }
799       nextchar = NULL;
800       return 'W';               /* Let the application handle it.   */
801     }
802     if (temp[1] == ':')
803     {
804       if (temp[2] == ':')
805       {
806         /* This is an option that accepts an argument optionally.  */
807         if (*nextchar != '\0')
808         {
809           GNoptarg = nextchar;
810           GNoptind++;
811         }
812         else
813           GNoptarg = NULL;
814         nextchar = NULL;
815       }
816       else
817       {
818         /* This is an option that requires an argument.  */
819         if (*nextchar != '\0')
820         {
821           GNoptarg = nextchar;
822           /* If we end this ARGV-element by taking the rest as an arg,
823            * we must advance to the next element now.  */
824           GNoptind++;
825         }
826         else if (GNoptind == argc)
827         {
828           if (GNopterr)
829           {
830             /* 1003.2 specifies the format of this message.  */
831             FPRINTF (stderr, _("%s: option requires an argument -- %c\n"),
832                      argv[0], c);
833           }
834           if (optstring[0] == ':')
835             c = ':';
836           else
837             c = '?';
838         }
839         else
840           /* We already incremented `GNoptind' once;
841            * increment it again when taking next ARGV-elt as argument.  */
842           GNoptarg = argv[GNoptind++];
843         nextchar = NULL;
844       }
845     }
846     return c;
847   }
848 }
849
850 static int
851 GNgetopt_long (int argc, char *const *argv, const char *options,
852                const struct GNoption *long_options, int *opt_index)
853 {
854   return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
855 }
856
857 /* ******************** now the GNUnet specific modifications... ********************* */
858
859 /**
860  * Parse the command line.
861  *
862  * @param binaryOptions Name of application with option summary
863  * @param allOptions defined options and handlers
864  * @param argc number of arguments
865  * @param argv actual arguments
866  * @return index into argv with first non-option
867  *   argument, or -1 on error
868  */
869 int
870 GNUNET_GETOPT_run (const char *binaryOptions,
871                    const struct GNUNET_GETOPT_CommandLineOption *allOptions,
872                    unsigned int argc, char *const *argv)
873 {
874   struct GNoption *long_options;
875   struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
876   int count;
877   int i;
878   char *shorts;
879   int spos;
880   int cont;
881   int c;
882
883   GNUNET_assert (argc > 0);
884   GNoptind = 0;
885   clpc.binaryName = argv[0];
886   clpc.binaryOptions = binaryOptions;
887   clpc.allOptions = allOptions;
888   clpc.argv = argv;
889   clpc.argc = argc;
890   count = 0;
891   while (allOptions[count].name != NULL)
892     count++;
893   long_options = GNUNET_malloc (sizeof (struct GNoption) * (count + 1));
894   shorts = GNUNET_malloc (count * 2 + 1);
895   spos = 0;
896   for (i = 0; i < count; i++)
897   {
898     long_options[i].name = allOptions[i].name;
899     long_options[i].has_arg = allOptions[i].require_argument;
900     long_options[i].flag = NULL;
901     long_options[i].val = allOptions[i].shortName;
902     shorts[spos++] = allOptions[i].shortName;
903     if (allOptions[i].require_argument != 0)
904       shorts[spos++] = ':';
905   }
906   long_options[count].name = NULL;
907   long_options[count].has_arg = 0;
908   long_options[count].flag = NULL;
909   long_options[count].val = '\0';
910   shorts[spos] = '\0';
911   cont = GNUNET_OK;
912   /* main getopt loop */
913   while (cont == GNUNET_OK)
914   {
915     int option_index = 0;
916
917     c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
918
919     if (c == GNUNET_SYSERR)
920       break;                    /* No more flags to process */
921
922     for (i = 0; i < count; i++)
923     {
924       clpc.currentArgument = GNoptind - 1;
925       if ((char) c == allOptions[i].shortName)
926       {
927         cont =
928             allOptions[i].processor (&clpc, allOptions[i].scls,
929                                      allOptions[i].name, GNoptarg);
930         break;
931       }
932     }
933     if (i == count)
934     {
935       FPRINTF (stderr, _("Use %s to get a list of options.\n"), "--help");
936       cont = GNUNET_SYSERR;
937     }
938   }
939
940   GNUNET_free (shorts);
941   GNUNET_free (long_options);
942   if (cont != GNUNET_OK)
943   {
944     return cont;
945   }
946   return GNoptind;
947 }
948
949 /* end of getopt.c */