~ubuntu-dev/ubuntu/lucid/zabbix/lucid-201002110857

« back to all changes in this revision

Viewing changes to src/libs/zbxcommon/zbxgetopt.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Ablassmeier
  • Date: 2007-07-02 09:06:51 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070702090651-8l6fl3fjw9rh6l2u
Tags: 1:1.4.1-2
Add patch from SVN in order to fix Incorrect processing of character '%'
in user parameters and remote commands.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, 1993
 
7
        Free Software Foundation, Inc.
 
8
 
 
9
   This program is free software; you can redistribute it and/or modify it
 
10
   under the terms of the GNU General Public License as published by the
 
11
   Free Software Foundation; either version 2, or (at your zbx_option) any
 
12
   later version.
 
13
 
 
14
   This program is distributed in the hope that it will be useful,
 
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
   GNU General Public License for more details.
 
18
 
 
19
   You should have received a copy of the GNU General Public License
 
20
   along with this program; if not, write to the Free Software
 
21
   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
22
 
 
23
 
 
24
#include "common.h"
 
25
 
 
26
 
 
27
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
 
28
   long-named zbx_option.  Because this is not POSIX.2 compliant, it is
 
29
   being phased out.  */
 
30
/* #define GETOPT_COMPAT */
 
31
#undef GETOPT_COMPAT
 
32
 
 
33
/* This version of `getopt' appears to the caller like standard Unix `getopt'
 
34
   but it behaves differently for the user, since it allows the user
 
35
   to intersperse the options with the other arguments.
 
36
 
 
37
   As `getopt' works, it permutes the elements of ARGV so that,
 
38
   when it is done, all the options precede everything else.  Thus
 
39
   all application programs are extended to handle flexible argument order.
 
40
 
 
41
   Setting the environment variable POSIXLY_CORRECT disables permutation.
 
42
   Then the behavior is completely standard.
 
43
 
 
44
   GNU application programs can use a third alternative mode in which
 
45
   they can distinguish the relative order of options and other arguments.  */
 
46
 
 
47
#include "zbxgetopt.h"
 
48
 
 
49
#undef BAD_OPTION
 
50
 
 
51
/* For communication from `getopt' to the caller.
 
52
   When `getopt' finds an zbx_option that takes an argument,
 
53
   the argument value is returned here.
 
54
   Also, when `ordering' is RETURN_IN_ORDER,
 
55
   each non-zbx_option ARGV-element is returned here.  */
 
56
 
 
57
char *zbx_optarg = NULL;
 
58
 
 
59
/* Index in ARGV of the next element to be scanned.
 
60
   This is used for communication to and from the caller
 
61
   and for communication between successive calls to `getopt'.
 
62
 
 
63
   On entry to `getopt', zero means this is the first call; initialize.
 
64
 
 
65
   When `getopt' returns EOF, this is the index of the first of the
 
66
   non-zbx_option elements that the caller should itself scan.
 
67
 
 
68
   Otherwise, `zbx_optind' communicates from one call to the next
 
69
   how much of ARGV has been scanned so far.  */
 
70
 
 
71
/* XXX 1003.2 says this must be 1 before any call.  */
 
72
int zbx_optind = 0;
 
73
 
 
74
/* The next char to be scanned in the zbx_option-element
 
75
   in which the last zbx_option character we returned was found.
 
76
   This allows us to pick up the scan where we left off.
 
77
 
 
78
   If this is zero, or a null string, it means resume the scan
 
79
   by advancing to the next ARGV-element.  */
 
80
 
 
81
static char *nextchar;
 
82
 
 
83
/* Callers store zero here to inhibit the error message
 
84
   for unrecognized options.  */
 
85
 
 
86
int zbx_opterr = 1;
 
87
 
 
88
/* Set to an zbx_option character which was unrecognized.
 
89
   This must be initialized on some systems to avoid linking in the
 
90
   system's own getopt implementation.  */
 
91
 
 
92
#define BAD_OPTION '\0'
 
93
int zbx_optopt = BAD_OPTION;
 
94
 
 
95
/* Describe how to deal with options that follow non-zbx_option ARGV-elements.
 
96
 
 
97
   If the caller did not specify anything,
 
98
   the default is REQUIRE_ORDER if the environment variable
 
99
   POSIXLY_CORRECT is defined, PERMUTE otherwise.
 
100
 
 
101
   REQUIRE_ORDER means don't recognize them as options;
 
102
   stop zbx_option processing when the first non-zbx_option is seen.
 
103
   This is what Unix does.
 
104
   This mode of operation is selected by either setting the environment
 
105
   variable POSIXLY_CORRECT, or using `+' as the first character
 
106
   of the list of zbx_option characters.
 
107
 
 
108
   PERMUTE is the default.  We permute the contents of ARGV as we scan,
 
109
   so that eventually all the non-options are at the end.  This allows options
 
110
   to be given in any order, even with programs that were not written to
 
111
   expect this.
 
112
 
 
113
   RETURN_IN_ORDER is an zbx_option available to programs that were written
 
114
   to expect options and other ARGV-elements in any order and that care about
 
115
   the ordering of the two.  We describe each non-zbx_option ARGV-element
 
116
   as if it were the argument of an zbx_option with character code 1.
 
117
   Using `-' as the first character of the list of zbx_option characters
 
118
   selects this mode of operation.
 
119
 
 
120
   The special argument `--' forces an end of zbx_option-scanning regardless
 
121
   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
 
122
   `--' can cause `getopt' to return EOF with `zbx_optind' != ARGC.  */
 
123
 
 
124
static enum
 
125
{
 
126
  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
 
127
} ordering;
 
128
 
 
129
/* Handle permutation of arguments.  */
 
130
 
 
131
/* Describe the part of ARGV that contains non-options that have
 
132
   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
 
133
   `last_nonopt' is the index after the last of them.  */
 
134
 
 
135
static int first_nonopt;
 
136
static int last_nonopt;
 
137
 
 
138
/* Exchange two adjacent subsequences of ARGV.
 
139
   One subsequence is elements [first_nonopt,last_nonopt)
 
140
   which contains all the non-options that have been skipped so far.
 
141
   The other is elements [last_nonopt,zbx_optind), which contains all
 
142
   the options processed since those non-options were skipped.
 
143
 
 
144
   `first_nonopt' and `last_nonopt' are relocated so that they describe
 
145
   the new indices of the non-options in ARGV after they are moved.
 
146
 
 
147
   To perform the swap, we first reverse the order of all elements. So
 
148
   all options now come before all non options, but they are in the
 
149
   wrong order. So we put back the options and non options in original
 
150
   order by reversing them again. For example:
 
151
       original input:      a b c -x -y
 
152
       reverse all:         -y -x c b a
 
153
       reverse options:     -x -y c b a
 
154
       reverse non options: -x -y a b c
 
155
*/
 
156
 
 
157
 
 
158
static void exchange (char **argv)
 
159
{
 
160
  char *temp; char **first, **last;
 
161
 
 
162
  /* Reverse all the elements [first_nonopt, zbx_optind) */
 
163
  first = &argv[first_nonopt];
 
164
  last  = &argv[zbx_optind-1];
 
165
  while (first < last) {
 
166
    temp = *first; *first = *last; *last = temp; first++; last--;
 
167
  }
 
168
  /* Put back the options in order */
 
169
  first = &argv[first_nonopt];
 
170
  first_nonopt += (zbx_optind - last_nonopt);
 
171
  last  = &argv[first_nonopt - 1];
 
172
  while (first < last) {
 
173
    temp = *first; *first = *last; *last = temp; first++; last--;
 
174
  }
 
175
 
 
176
  /* Put back the non options in order */
 
177
  first = &argv[first_nonopt];
 
178
  last_nonopt = zbx_optind;
 
179
  last  = &argv[last_nonopt-1];
 
180
  while (first < last) {
 
181
    temp = *first; *first = *last; *last = temp; first++; last--;
 
182
  }
 
183
}
 
184
 
 
185
/* Scan elements of ARGV (whose length is ARGC) for zbx_option characters
 
186
   given in OPTSTRING.
 
187
 
 
188
   If an element of ARGV starts with '-', and is not exactly "-" or "--",
 
189
   then it is an zbx_option element.  The characters of this element
 
190
   (aside from the initial '-') are zbx_option characters.  If `getopt'
 
191
   is called repeatedly, it returns successively each of the zbx_option characters
 
192
   from each of the zbx_option elements.
 
193
 
 
194
   If `getopt' finds another zbx_option character, it returns that character,
 
195
   updating `zbx_optind' and `nextchar' so that the next call to `getopt' can
 
196
   resume the scan with the following zbx_option character or ARGV-element.
 
197
 
 
198
   If there are no more zbx_option characters, `getopt' returns `EOF'.
 
199
   Then `zbx_optind' is the index in ARGV of the first ARGV-element
 
200
   that is not an zbx_option.  (The ARGV-elements have been permuted
 
201
   so that those that are not options now come last.)
 
202
 
 
203
   OPTSTRING is a string containing the legitimate zbx_option characters.
 
204
   If an zbx_option character is seen that is not listed in OPTSTRING,
 
205
   return BAD_OPTION after printing an error message.  If you set `zbx_opterr' to
 
206
   zero, the error message is suppressed but we still return BAD_OPTION.
 
207
 
 
208
   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
 
209
   so the following text in the same ARGV-element, or the text of the following
 
210
   ARGV-element, is returned in `zbx_optarg'.  Two colons mean an zbx_option that
 
211
   wants an optional arg; if there is text in the current ARGV-element,
 
212
   it is returned in `zbx_optarg', otherwise `zbx_optarg' is set to zero.
 
213
 
 
214
   If OPTSTRING starts with `-' or `+', it requests different methods of
 
215
   handling the non-zbx_option ARGV-elements.
 
216
   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
 
217
 
 
218
   Long-named options begin with `--' instead of `-'.
 
219
   Their names may be abbreviated as long as the abbreviation is unique
 
220
   or is an exact match for some defined zbx_option.  If they have an
 
221
   argument, it follows the zbx_option name in the same ARGV-element, separated
 
222
   from the zbx_option name by a `=', or else the in next ARGV-element.
 
223
   When `getopt' finds a long-named zbx_option, it returns 0 if that zbx_option's
 
224
   `flag' field is nonzero, the value of the zbx_option's `val' field
 
225
   if the `flag' field is zero.
 
226
 
 
227
   LONGOPTS is a vector of `struct zbx_option' terminated by an
 
228
   element containing a name which is zero.
 
229
 
 
230
   LONGIND returns the index in LONGOPT of the long-named zbx_option found.
 
231
   It is only valid when a long-named zbx_option has been found by the most
 
232
   recent call.
 
233
 
 
234
   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
 
235
   long-named options.  */
 
236
 
 
237
static int zbx_getopt_internal (int argc, char **argv, const char *optstring,
 
238
                 const struct zbx_option *longopts, int *longind,
 
239
                 int long_only)
 
240
{
 
241
  static char empty_string[1];
 
242
  int option_index;
 
243
 
 
244
  if (longind != NULL)
 
245
    *longind = -1;
 
246
 
 
247
  zbx_optarg = 0;
 
248
 
 
249
  /* Initialize the internal data when the first call is made.
 
250
     Start processing options with ARGV-element 1 (since ARGV-element 0
 
251
     is the program name); the sequence of previously skipped
 
252
     non-zbx_option ARGV-elements is empty.  */
 
253
 
 
254
  if (zbx_optind == 0)
 
255
    {
 
256
      first_nonopt = last_nonopt = zbx_optind = 1;
 
257
 
 
258
      nextchar = NULL;
 
259
 
 
260
      /* Determine how to handle the ordering of options and nonoptions.  */
 
261
 
 
262
      if (optstring[0] == '-')
 
263
        {
 
264
          ordering = RETURN_IN_ORDER;
 
265
          ++optstring;
 
266
        }
 
267
      else if (optstring[0] == '+')
 
268
        {
 
269
          ordering = REQUIRE_ORDER;
 
270
          ++optstring;
 
271
        }
 
272
#if OFF
 
273
      else if (getenv ("POSIXLY_CORRECT") != NULL)
 
274
        ordering = REQUIRE_ORDER;
 
275
#endif
 
276
      else
 
277
        ordering = PERMUTE;
 
278
    }
 
279
 
 
280
  if (nextchar == NULL || *nextchar == '\0')
 
281
    {
 
282
      if (ordering == PERMUTE)
 
283
        {
 
284
          /* If we have just processed some options following some non-options,
 
285
             exchange them so that the options come first.  */
 
286
 
 
287
          if (first_nonopt != last_nonopt && last_nonopt != zbx_optind)
 
288
            exchange (argv);
 
289
          else if (last_nonopt != zbx_optind)
 
290
            first_nonopt = zbx_optind;
 
291
 
 
292
          /* Now skip any additional non-options
 
293
             and extend the range of non-options previously skipped.  */
 
294
 
 
295
          while (zbx_optind < argc
 
296
                 && (argv[zbx_optind][0] != '-' || argv[zbx_optind][1] == '\0')
 
297
#ifdef GETOPT_COMPAT
 
298
                 && (longopts == NULL
 
299
                     || argv[zbx_optind][0] != '+' || argv[zbx_optind][1] == '\0')
 
300
#endif                          /* GETOPT_COMPAT */
 
301
                 )
 
302
            zbx_optind++;
 
303
          last_nonopt = zbx_optind;
 
304
        }
 
305
 
 
306
      /* Special ARGV-element `--' means premature end of options.
 
307
         Skip it like a null zbx_option,
 
308
         then exchange with previous non-options as if it were an zbx_option,
 
309
         then skip everything else like a non-zbx_option.  */
 
310
 
 
311
      if (zbx_optind != argc && !strcmp (argv[zbx_optind], "--"))
 
312
        {
 
313
          zbx_optind++;
 
314
 
 
315
          if (first_nonopt != last_nonopt && last_nonopt != zbx_optind)
 
316
            exchange (argv);
 
317
          else if (first_nonopt == last_nonopt)
 
318
            first_nonopt = zbx_optind;
 
319
          last_nonopt = argc;
 
320
 
 
321
          zbx_optind = argc;
 
322
        }
 
323
 
 
324
      /* If we have done all the ARGV-elements, stop the scan
 
325
         and back over any non-options that we skipped and permuted.  */
 
326
 
 
327
      if (zbx_optind == argc)
 
328
        {
 
329
          /* Set the next-arg-index to point at the non-options
 
330
             that we previously skipped, so the caller will digest them.  */
 
331
          if (first_nonopt != last_nonopt)
 
332
            zbx_optind = first_nonopt;
 
333
          return EOF;
 
334
        }
 
335
 
 
336
      /* If we have come to a non-zbx_option and did not permute it,
 
337
         either stop the scan or describe it to the caller and pass it by.  */
 
338
 
 
339
      if ((argv[zbx_optind][0] != '-' || argv[zbx_optind][1] == '\0')
 
340
#ifdef GETOPT_COMPAT
 
341
          && (longopts == NULL
 
342
              || argv[zbx_optind][0] != '+' || argv[zbx_optind][1] == '\0')
 
343
#endif                          /* GETOPT_COMPAT */
 
344
          )
 
345
        {
 
346
          if (ordering == REQUIRE_ORDER)
 
347
            return EOF;
 
348
          zbx_optarg = argv[zbx_optind++];
 
349
          return 1;
 
350
        }
 
351
 
 
352
      /* We have found another zbx_option-ARGV-element.
 
353
         Start decoding its characters.  */
 
354
 
 
355
      nextchar = (argv[zbx_optind] + 1
 
356
                  + (longopts != NULL && argv[zbx_optind][1] == '-'));
 
357
    }
 
358
 
 
359
  if (longopts != NULL
 
360
      && ((argv[zbx_optind][0] == '-'
 
361
           && (argv[zbx_optind][1] == '-' || long_only))
 
362
#ifdef GETOPT_COMPAT
 
363
          || argv[zbx_optind][0] == '+'
 
364
#endif                          /* GETOPT_COMPAT */
 
365
          ))
 
366
    {
 
367
      const struct zbx_option *p;
 
368
      char *s = nextchar;
 
369
      int exact = 0;
 
370
      int ambig = 0;
 
371
      const struct zbx_option *pfound = NULL;
 
372
      int indfound = 0;
 
373
      int needexact = 0;
 
374
 
 
375
#if ON
 
376
      /* allow `--zbx_option#value' because you cannout assign a '='
 
377
         to an environment variable under DOS command.com */
 
378
      while (*s && *s != '=' && * s != '#')
 
379
        s++;
 
380
#else
 
381
      while (*s && *s != '=')
 
382
        s++;
 
383
#endif
 
384
 
 
385
      /* Test all options for either exact match or abbreviated matches.  */
 
386
      for (p = longopts, option_index = 0; p->name;
 
387
           p++, option_index++)
 
388
        if (!strncmp (p->name, nextchar, (unsigned) (s - nextchar)))
 
389
          {
 
390
            if (p->has_arg & 0x10)
 
391
              needexact = 1;
 
392
            if ((unsigned) (s - nextchar) == strlen (p->name))
 
393
              {
 
394
                /* Exact match found.  */
 
395
                pfound = p;
 
396
                indfound = option_index;
 
397
                exact = 1;
 
398
                break;
 
399
              }
 
400
            else if (pfound == NULL)
 
401
              {
 
402
                /* First nonexact match found.  */
 
403
                pfound = p;
 
404
                indfound = option_index;
 
405
              }
 
406
            else
 
407
              /* Second nonexact match found.  */
 
408
              ambig = 1;
 
409
          }
 
410
 
 
411
      /* don't allow nonexact longoptions */
 
412
      if (needexact && !exact)
 
413
        {
 
414
          if (zbx_opterr)
 
415
                zbx_error("unrecognized zbx_option `%s'", argv[zbx_optind]);
 
416
 
 
417
          nextchar += strlen (nextchar);
 
418
          zbx_optind++;
 
419
          return BAD_OPTION;
 
420
        }
 
421
      if (ambig && !exact)
 
422
        {
 
423
          if (zbx_opterr)
 
424
                zbx_error("zbx_option `%s' is ambiguous", argv[zbx_optind]);
 
425
 
 
426
          nextchar += strlen (nextchar);
 
427
          zbx_optind++;
 
428
          return BAD_OPTION;
 
429
        }
 
430
 
 
431
      if (pfound != NULL)
 
432
        {
 
433
          int have_arg = (s[0] != '\0');
 
434
          if (have_arg && (pfound->has_arg & 0xf))
 
435
            have_arg = (s[1] != '\0');
 
436
          option_index = indfound;
 
437
          zbx_optind++;
 
438
          if (have_arg)
 
439
            {
 
440
              /* Don't test has_arg with >, because some C compilers don't
 
441
                 allow it to be used on enums.  */
 
442
              if (pfound->has_arg & 0xf)
 
443
                zbx_optarg = s + 1;
 
444
              else
 
445
                {
 
446
                  if (zbx_opterr)
 
447
                    {
 
448
                      if (argv[zbx_optind - 1][1] == '-')
 
449
                        /* --zbx_option */
 
450
                        zbx_error("zbx_option `--%s' doesn't allow an argument",pfound->name);
 
451
                      else
 
452
                        /* +zbx_option or -zbx_option */
 
453
                        zbx_error("zbx_option `%c%s' doesn't allow an argument", argv[zbx_optind - 1][0], pfound->name);
 
454
                    }
 
455
                  nextchar += strlen (nextchar);
 
456
                  return BAD_OPTION;
 
457
                }
 
458
            }
 
459
          else if ((pfound->has_arg & 0xf) == 1)
 
460
            {
 
461
#if OFF
 
462
              if (zbx_optind < argc)
 
463
#else
 
464
              if (zbx_optind < argc && (pfound->has_arg & 0x20) == 0)
 
465
#endif
 
466
                zbx_optarg = argv[zbx_optind++];
 
467
              else
 
468
                {
 
469
                  if (zbx_opterr)
 
470
                    zbx_error("zbx_option `--%s%s' requires an argument",
 
471
                             pfound->name, (pfound->has_arg & 0x20) ? "=" : "");
 
472
                  nextchar += strlen (nextchar);
 
473
                  return optstring[0] == ':' ? ':' : BAD_OPTION;
 
474
                }
 
475
            }
 
476
          nextchar += strlen (nextchar);
 
477
          if (longind != NULL)
 
478
            *longind = option_index;
 
479
          if (pfound->flag)
 
480
            {
 
481
              *(pfound->flag) = pfound->val;
 
482
              return 0;
 
483
            }
 
484
          return pfound->val;
 
485
        }
 
486
      /* Can't find it as a long zbx_option.  If this is not getopt_long_only,
 
487
         or the zbx_option starts with '--' or is not a valid short
 
488
         zbx_option, then it's an error.
 
489
         Otherwise interpret it as a short zbx_option.  */
 
490
      if (!long_only || argv[zbx_optind][1] == '-'
 
491
#ifdef GETOPT_COMPAT
 
492
          || argv[zbx_optind][0] == '+'
 
493
#endif                          /* GETOPT_COMPAT */
 
494
          || strchr (optstring, *nextchar) == NULL)
 
495
        {
 
496
          if (zbx_opterr)
 
497
            {
 
498
              if (argv[zbx_optind][1] == '-')
 
499
                /* --zbx_option */
 
500
                zbx_error("unrecognized zbx_option `--%s'", nextchar);
 
501
              else
 
502
                /* +zbx_option or -zbx_option */
 
503
                zbx_error("unrecognized zbx_option `%c%s'", argv[zbx_optind][0], nextchar);
 
504
            }
 
505
          nextchar = empty_string;
 
506
          zbx_optind++;
 
507
          return BAD_OPTION;
 
508
        }
 
509
        (void) &ambig;  /* UNUSED */
 
510
    }
 
511
 
 
512
  /* Look at and handle the next zbx_option-character.  */
 
513
 
 
514
  {
 
515
    char c = *nextchar++;
 
516
    const char *temp = strchr (optstring, c);
 
517
 
 
518
    /* Increment `zbx_optind' when we start to process its last character.  */
 
519
    if (*nextchar == '\0')
 
520
      ++zbx_optind;
 
521
 
 
522
    if (temp == NULL || c == ':')
 
523
      {
 
524
        if (zbx_opterr)
 
525
          {
 
526
#if OFF
 
527
            if (c < 040 || c >= 0177)
 
528
              zbx_error("unrecognized zbx_option, character code 0%o", c);
 
529
            else
 
530
              zbx_error("unrecognized zbx_option `-%c'", c);
 
531
#else
 
532
            /* 1003.2 specifies the format of this message.  */
 
533
            zbx_error("illegal zbx_option -- %c", c);
 
534
#endif
 
535
          }
 
536
        zbx_optopt = c;
 
537
        return BAD_OPTION;
 
538
      }
 
539
    if (temp[1] == ':')
 
540
      {
 
541
        if (temp[2] == ':')
 
542
          {
 
543
            /* This is an zbx_option that accepts an argument optionally.  */
 
544
            if (*nextchar != '\0')
 
545
              {
 
546
                zbx_optarg = nextchar;
 
547
                zbx_optind++;
 
548
              }
 
549
            else
 
550
              zbx_optarg = 0;
 
551
            nextchar = NULL;
 
552
          }
 
553
        else
 
554
          {
 
555
            /* This is an zbx_option that requires an argument.  */
 
556
            if (*nextchar != '\0')
 
557
              {
 
558
                zbx_optarg = nextchar;
 
559
                /* If we end this ARGV-element by taking the rest as an arg,
 
560
                   we must advance to the next element now.  */
 
561
                zbx_optind++;
 
562
              }
 
563
            else if (zbx_optind == argc)
 
564
              {
 
565
                if (zbx_opterr)
 
566
                  {
 
567
#if OFF
 
568
                    zbx_error("zbx_option `-%c' requires an argument", c);
 
569
#else
 
570
                    /* 1003.2 specifies the format of this message.  */
 
571
                    zbx_error("zbx_option requires an argument -- %c", c);
 
572
#endif
 
573
                  }
 
574
                zbx_optopt = c;
 
575
                if (optstring[0] == ':')
 
576
                  c = ':';
 
577
                else
 
578
                  c = BAD_OPTION;
 
579
              }
 
580
            else
 
581
              /* We already incremented `zbx_optind' once;
 
582
                 increment it again when taking next ARGV-elt as argument.  */
 
583
              zbx_optarg = argv[zbx_optind++];
 
584
            nextchar = NULL;
 
585
          }
 
586
      }
 
587
    return c;
 
588
  }
 
589
}
 
590
 
 
591
int zbx_getopt(int argc, char **argv, const char *optstring)
 
592
{
 
593
  return zbx_getopt_internal (argc, argv, optstring,
 
594
                           (const struct zbx_option *) 0,
 
595
                           (int *) 0,
 
596
                           0);
 
597
}
 
598
 
 
599
int zbx_getopt_long(int argc, char **argv, const char *options,
 
600
                    const struct zbx_option *long_options, int *opt_index)
 
601
{
 
602
  return zbx_getopt_internal (argc, argv, options, long_options, opt_index, 0);
 
603
}
 
604
 
 
605
 
 
606
#ifdef TEST2
 
607
 
 
608
/* Compile with -DTEST to make an executable for use in testing
 
609
   the above definition of `getopt'.  */
 
610
 
 
611
int
 
612
main (argc, argv)
 
613
     int argc;
 
614
     char **argv;
 
615
{
 
616
  int c;
 
617
  int digit_optind = 0;
 
618
 
 
619
  while (1)
 
620
    {
 
621
      int this_option_optind = zbx_optind ? zbx_optind : 1;
 
622
 
 
623
      c = getopt (argc, argv, "abc:d:0123456789");
 
624
      if (c == EOF)
 
625
        break;
 
626
 
 
627
      switch (c)
 
628
        {
 
629
        case '0':
 
630
        case '1':
 
631
        case '2':
 
632
        case '3':
 
633
        case '4':
 
634
        case '5':
 
635
        case '6':
 
636
        case '7':
 
637
        case '8':
 
638
        case '9':
 
639
          if (digit_optind != 0 && digit_optind != this_option_optind)
 
640
            printf ("digits occur in two different argv-elements.\n");
 
641
          digit_optind = this_option_optind;
 
642
          printf ("zbx_option %c\n", c);
 
643
          break;
 
644
 
 
645
        case 'a':
 
646
          printf ("zbx_option a\n");
 
647
          break;
 
648
 
 
649
        case 'b':
 
650
          printf ("zbx_option b\n");
 
651
          break;
 
652
 
 
653
        case 'c':
 
654
          printf ("zbx_option c with value `%s'\n", zbx_optarg);
 
655
          break;
 
656
 
 
657
        case BAD_OPTION:
 
658
          break;
 
659
 
 
660
        default:
 
661
          printf ("?? getopt returned character code 0%o ??\n", c);
 
662
        }
 
663
    }
 
664
 
 
665
  if (zbx_optind < argc)
 
666
    {
 
667
      printf ("non-zbx_option ARGV-elements: ");
 
668
      while (zbx_optind < argc)
 
669
        printf ("%s ", argv[zbx_optind++]);
 
670
      printf ("\n");
 
671
    }
 
672
 
 
673
  exit (0);
 
674
}
 
675
 
 
676
#endif /* TEST */