Annotation of embedaddon/sudo/compat/getopt_long.c, revision 1.1.1.1

1.1       misho       1: /*     $OpenBSD: getopt_long.c,v 1.26 2013/06/08 22:47:56 millert Exp $        */
                      2: /*     $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $      */
                      3: /*     $FreeBSD: head/lib/libc/stdlib/getopt_long.c 236936 2012-06-11 22:25:20Z delphij $      */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
                      7:  *
                      8:  * Permission to use, copy, modify, and distribute this software for any
                      9:  * purpose with or without fee is hereby granted, provided that the above
                     10:  * copyright notice and this permission notice appear in all copies.
                     11:  *
                     12:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     13:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     14:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     15:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     16:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     17:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     18:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     19:  *
                     20:  * Sponsored in part by the Defense Advanced Research Projects
                     21:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
                     22:  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
                     23:  */
                     24: /*-
                     25:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
                     26:  * All rights reserved.
                     27:  *
                     28:  * This code is derived from software contributed to The NetBSD Foundation
                     29:  * by Dieter Baron and Thomas Klausner.
                     30:  *
                     31:  * Redistribution and use in source and binary forms, with or without
                     32:  * modification, are permitted provided that the following conditions
                     33:  * are met:
                     34:  * 1. Redistributions of source code must retain the above copyright
                     35:  *    notice, this list of conditions and the following disclaimer.
                     36:  * 2. Redistributions in binary form must reproduce the above copyright
                     37:  *    notice, this list of conditions and the following disclaimer in the
                     38:  *    documentation and/or other materials provided with the distribution.
                     39:  *
                     40:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     41:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     42:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     43:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     44:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     45:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     46:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     47:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     48:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     49:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     50:  * POSSIBILITY OF SUCH DAMAGE.
                     51:  */
                     52: 
                     53: #include <config.h>
                     54: 
                     55: #include <stdio.h>
                     56: #ifdef STDC_HEADERS
                     57: # include <stdlib.h>
                     58: # include <stddef.h>
                     59: #else
                     60: # ifdef HAVE_STDLIB_H
                     61: #  include <stdlib.h>
                     62: # endif
                     63: #endif /* STDC_HEADERS */
                     64: #ifdef HAVE_STRING_H
                     65: # include <string.h>
                     66: #endif /* HAVE_STRING_H */
                     67: #ifdef HAVE_STRINGS_H
                     68: # include <strings.h>
                     69: #endif /* HAVE_STRINGS_H */
                     70: 
                     71: #define SUDO_ERROR_WRAP 0
                     72: 
                     73: #include "missing.h"
                     74: #include "fatal.h"
                     75: #include "compat/getopt.h"
                     76: 
                     77: #define GNU_COMPATIBLE         /* Be more compatible with GNU getopt. */
                     78: 
                     79: #ifdef REPLACE_GETOPT
                     80: int    opterr = 1;             /* if error message should be printed */
                     81: int    optind = 1;             /* index into parent argv vector */
                     82: int    optopt = '?';           /* character checked for validity */
                     83: char    *optarg;               /* argument associated with option */
                     84: #else
                     85: extern int     opterr;         /* if error message should be printed */
                     86: extern int     optind;         /* index into parent argv vector */
                     87: extern int     optopt;         /* character checked for validity */
                     88: extern char    *optarg;                /* argument associated with option */
                     89: #endif
                     90: #if !defined(REPLACE_GETOPT) && !defined(HAVE_OPTRESET)
                     91: int    optreset;               /* reset getopt */
                     92: #endif
                     93: 
                     94: #define PRINT_ERROR    ((opterr) && (*options != ':'))
                     95: 
                     96: #define FLAG_PERMUTE   0x01    /* permute non-options to the end of argv */
                     97: #define FLAG_ALLARGS   0x02    /* treat non-options as args to option "-1" */
                     98: #define FLAG_LONGONLY  0x04    /* operate as getopt_long_only */
                     99: 
                    100: /* return values */
                    101: #define        BADCH           (int)'?'
                    102: #define        BADARG          ((*options == ':') ? (int)':' : (int)'?')
                    103: #define        INORDER         (int)1
                    104: 
                    105: #define        EMSG            ""
                    106: 
                    107: #ifdef GNU_COMPATIBLE
                    108: #define NO_PREFIX      (-1)
                    109: #define D_PREFIX       0
                    110: #define DD_PREFIX      1
                    111: #define W_PREFIX       2
                    112: #endif
                    113: 
                    114: static int getopt_internal(int, char * const *, const char *,
                    115:                           const struct option *, int *, int);
                    116: static int parse_long_options(char * const *, const char *,
                    117:                              const struct option *, int *, int, int);
                    118: static int gcd(int, int);
                    119: static void permute_args(int, int, int, char * const *);
                    120: 
                    121: static char *place = EMSG; /* option letter processing */
                    122: 
                    123: /* XXX: set optreset to 1 rather than these two */
                    124: static int nonopt_start = -1; /* first non option argument (for permute) */
                    125: static int nonopt_end = -1;   /* first option after non options (for permute) */
                    126: 
                    127: /* Error messages */
                    128: static const char recargchar[] = "option requires an argument -- %c";
                    129: static const char illoptchar[] = "illegal option -- %c"; /* From P1003.2 */
                    130: #ifdef GNU_COMPATIBLE
                    131: static int dash_prefix = NO_PREFIX;
                    132: static const char gnuoptchar[] = "invalid option -- %c";
                    133: 
                    134: static const char recargstring[] = "option `%s%s' requires an argument";
                    135: static const char ambig[] = "option `%s%.*s' is ambiguous";
                    136: static const char noarg[] = "option `%s%.*s' doesn't allow an argument";
                    137: static const char illoptstring[] = "unrecognized option `%s%s'";
                    138: #else
                    139: static const char recargstring[] = "option requires an argument -- %s";
                    140: static const char ambig[] = "ambiguous option -- %.*s";
                    141: static const char noarg[] = "option doesn't take an argument -- %.*s";
                    142: static const char illoptstring[] = "unknown option -- %s";
                    143: #endif
                    144: 
                    145: /*
                    146:  * Compute the greatest common divisor of a and b.
                    147:  */
                    148: static int
                    149: gcd(int a, int b)
                    150: {
                    151:        int c;
                    152: 
                    153:        c = a % b;
                    154:        while (c != 0) {
                    155:                a = b;
                    156:                b = c;
                    157:                c = a % b;
                    158:        }
                    159: 
                    160:        return (b);
                    161: }
                    162: 
                    163: /*
                    164:  * Exchange the block from nonopt_start to nonopt_end with the block
                    165:  * from nonopt_end to opt_end (keeping the same order of arguments
                    166:  * in each block).
                    167:  */
                    168: static void
                    169: permute_args(int panonopt_start, int panonopt_end, int opt_end,
                    170:        char * const *nargv)
                    171: {
                    172:        int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
                    173:        char *swap;
                    174: 
                    175:        /*
                    176:         * compute lengths of blocks and number and size of cycles
                    177:         */
                    178:        nnonopts = panonopt_end - panonopt_start;
                    179:        nopts = opt_end - panonopt_end;
                    180:        ncycle = gcd(nnonopts, nopts);
                    181:        cyclelen = (opt_end - panonopt_start) / ncycle;
                    182: 
                    183:        for (i = 0; i < ncycle; i++) {
                    184:                cstart = panonopt_end+i;
                    185:                pos = cstart;
                    186:                for (j = 0; j < cyclelen; j++) {
                    187:                        if (pos >= panonopt_end)
                    188:                                pos -= nnonopts;
                    189:                        else
                    190:                                pos += nopts;
                    191:                        swap = nargv[pos];
                    192:                        /* LINTED const cast */
                    193:                        ((char **) nargv)[pos] = nargv[cstart];
                    194:                        /* LINTED const cast */
                    195:                        ((char **)nargv)[cstart] = swap;
                    196:                }
                    197:        }
                    198: }
                    199: 
                    200: /*
                    201:  * parse_long_options --
                    202:  *     Parse long options in argc/argv argument vector.
                    203:  * Returns -1 if short_too is set and the option does not match long_options.
                    204:  */
                    205: static int
                    206: parse_long_options(char * const *nargv, const char *options,
                    207:        const struct option *long_options, int *idx, int short_too, int flags)
                    208: {
                    209:        char *current_argv, *has_equal;
                    210: #ifdef GNU_COMPATIBLE
                    211:        char *current_dash;
                    212: #endif
                    213:        size_t current_argv_len;
                    214:        int i, match, exact_match, second_partial_match;
                    215: 
                    216:        current_argv = place;
                    217: #ifdef GNU_COMPATIBLE
                    218:        switch (dash_prefix) {
                    219:                case D_PREFIX:
                    220:                        current_dash = "-";
                    221:                        break;
                    222:                case DD_PREFIX:
                    223:                        current_dash = "--";
                    224:                        break;
                    225:                case W_PREFIX:
                    226:                        current_dash = "-W ";
                    227:                        break;
                    228:                default:
                    229:                        current_dash = "";
                    230:                        break;
                    231:        }
                    232: #endif
                    233:        match = -1;
                    234:        exact_match = 0;
                    235:        second_partial_match = 0;
                    236: 
                    237:        optind++;
                    238: 
                    239:        if ((has_equal = strchr(current_argv, '=')) != NULL) {
                    240:                /* argument found (--option=arg) */
                    241:                current_argv_len = has_equal - current_argv;
                    242:                has_equal++;
                    243:        } else
                    244:                current_argv_len = strlen(current_argv);
                    245: 
                    246:        for (i = 0; long_options[i].name; i++) {
                    247:                /* find matching long option */
                    248:                if (strncmp(current_argv, long_options[i].name,
                    249:                    current_argv_len))
                    250:                        continue;
                    251: 
                    252:                if (strlen(long_options[i].name) == current_argv_len) {
                    253:                        /* exact match */
                    254:                        match = i;
                    255:                        exact_match = 1;
                    256:                        break;
                    257:                }
                    258:                /*
                    259:                 * If this is a known short option, don't allow
                    260:                 * a partial match of a single character.
                    261:                 */
                    262:                if (short_too && current_argv_len == 1)
                    263:                        continue;
                    264: 
                    265:                if (match == -1)        /* first partial match */
                    266:                        match = i;
                    267:                else if ((flags & FLAG_LONGONLY) ||
                    268:                         long_options[i].has_arg !=
                    269:                             long_options[match].has_arg ||
                    270:                         long_options[i].flag != long_options[match].flag ||
                    271:                         long_options[i].val != long_options[match].val)
                    272:                        second_partial_match = 1;
                    273:        }
                    274:        if (!exact_match && second_partial_match) {
                    275:                /* ambiguous abbreviation */
                    276:                if (PRINT_ERROR)
                    277:                        warningx(ambig,
                    278: #ifdef GNU_COMPATIBLE
                    279:                             current_dash,
                    280: #endif
                    281:                             (int)current_argv_len,
                    282:                             current_argv);
                    283:                optopt = 0;
                    284:                return (BADCH);
                    285:        }
                    286:        if (match != -1) {              /* option found */
                    287:                if (long_options[match].has_arg == no_argument
                    288:                    && has_equal) {
                    289:                        if (PRINT_ERROR)
                    290:                                warningx(noarg,
                    291: #ifdef GNU_COMPATIBLE
                    292:                                     current_dash,
                    293: #endif
                    294:                                     (int)current_argv_len,
                    295:                                     current_argv);
                    296:                        /*
                    297:                         * XXX: GNU sets optopt to val regardless of flag
                    298:                         */
                    299:                        if (long_options[match].flag == NULL)
                    300:                                optopt = long_options[match].val;
                    301:                        else
                    302:                                optopt = 0;
                    303: #ifdef GNU_COMPATIBLE
                    304:                        return (BADCH);
                    305: #else
                    306:                        return (BADARG);
                    307: #endif
                    308:                }
                    309:                if (long_options[match].has_arg == required_argument ||
                    310:                    long_options[match].has_arg == optional_argument) {
                    311:                        if (has_equal)
                    312:                                optarg = has_equal;
                    313:                        else if (long_options[match].has_arg ==
                    314:                            required_argument) {
                    315:                                /*
                    316:                                 * optional argument doesn't use next nargv
                    317:                                 */
                    318:                                optarg = nargv[optind++];
                    319:                        }
                    320:                }
                    321:                if ((long_options[match].has_arg == required_argument)
                    322:                    && (optarg == NULL)) {
                    323:                        /*
                    324:                         * Missing argument; leading ':' indicates no error
                    325:                         * should be generated.
                    326:                         */
                    327:                        if (PRINT_ERROR)
                    328:                                warningx(recargstring,
                    329: #ifdef GNU_COMPATIBLE
                    330:                                    current_dash,
                    331: #endif
                    332:                                    current_argv);
                    333:                        /*
                    334:                         * XXX: GNU sets optopt to val regardless of flag
                    335:                         */
                    336:                        if (long_options[match].flag == NULL)
                    337:                                optopt = long_options[match].val;
                    338:                        else
                    339:                                optopt = 0;
                    340:                        --optind;
                    341:                        return (BADARG);
                    342:                }
                    343:        } else {                        /* unknown option */
                    344:                if (short_too) {
                    345:                        --optind;
                    346:                        return (-1);
                    347:                }
                    348:                if (PRINT_ERROR)
                    349:                        warningx(illoptstring,
                    350: #ifdef GNU_COMPATIBLE
                    351:                              current_dash,
                    352: #endif
                    353:                              current_argv);
                    354:                optopt = 0;
                    355:                return (BADCH);
                    356:        }
                    357:        if (idx)
                    358:                *idx = match;
                    359:        if (long_options[match].flag) {
                    360:                *long_options[match].flag = long_options[match].val;
                    361:                return (0);
                    362:        } else
                    363:                return (long_options[match].val);
                    364: }
                    365: 
                    366: /*
                    367:  * getopt_internal --
                    368:  *     Parse argc/argv argument vector.  Called by user level routines.
                    369:  */
                    370: static int
                    371: getopt_internal(int nargc, char * const *nargv, const char *options,
                    372:        const struct option *long_options, int *idx, int flags)
                    373: {
                    374:        char *oli;                              /* option letter list index */
                    375:        int optchar, short_too;
                    376:        int posixly_correct;    /* no static, can be changed on the fly */
                    377: 
                    378:        if (options == NULL)
                    379:                return (-1);
                    380: 
                    381:        /*
                    382:         * Disable GNU extensions if POSIXLY_CORRECT is set or options
                    383:         * string begins with a '+'.
                    384:         */
                    385:        posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
                    386: #ifdef GNU_COMPATIBLE
                    387:        if (*options == '-')
                    388:                flags |= FLAG_ALLARGS;
                    389:        else if (posixly_correct || *options == '+')
                    390:                flags &= ~FLAG_PERMUTE;
                    391: #else
                    392:        if (posixly_correct || *options == '+')
                    393:                flags &= ~FLAG_PERMUTE;
                    394:        else if (*options == '-')
                    395:                flags |= FLAG_ALLARGS;
                    396: #endif
                    397:        if (*options == '+' || *options == '-')
                    398:                options++;
                    399: 
                    400:        /*
                    401:         * XXX Some GNU programs (like cvs) set optind to 0 instead of
                    402:         * XXX using optreset.  Work around this braindamage.
                    403:         */
                    404:        if (optind == 0)
                    405:                optind = optreset = 1;
                    406: 
                    407:        optarg = NULL;
                    408:        if (optreset)
                    409:                nonopt_start = nonopt_end = -1;
                    410: start:
                    411:        if (optreset || !*place) {              /* update scanning pointer */
                    412:                optreset = 0;
                    413:                if (optind >= nargc) {          /* end of argument vector */
                    414:                        place = EMSG;
                    415:                        if (nonopt_end != -1) {
                    416:                                /* do permutation, if we have to */
                    417:                                permute_args(nonopt_start, nonopt_end,
                    418:                                    optind, nargv);
                    419:                                optind -= nonopt_end - nonopt_start;
                    420:                        }
                    421:                        else if (nonopt_start != -1) {
                    422:                                /*
                    423:                                 * If we skipped non-options, set optind
                    424:                                 * to the first of them.
                    425:                                 */
                    426:                                optind = nonopt_start;
                    427:                        }
                    428:                        nonopt_start = nonopt_end = -1;
                    429:                        return (-1);
                    430:                }
                    431:                if (*(place = nargv[optind]) != '-' ||
                    432: #ifdef GNU_COMPATIBLE
                    433:                    place[1] == '\0') {
                    434: #else
                    435:                    (place[1] == '\0' && strchr(options, '-') == NULL)) {
                    436: #endif
                    437:                        place = EMSG;           /* found non-option */
                    438:                        if (flags & FLAG_ALLARGS) {
                    439:                                /*
                    440:                                 * GNU extension:
                    441:                                 * return non-option as argument to option 1
                    442:                                 */
                    443:                                optarg = nargv[optind++];
                    444:                                return (INORDER);
                    445:                        }
                    446:                        if (!(flags & FLAG_PERMUTE)) {
                    447:                                /*
                    448:                                 * If no permutation wanted, stop parsing
                    449:                                 * at first non-option.
                    450:                                 */
                    451:                                return (-1);
                    452:                        }
                    453:                        /* do permutation */
                    454:                        if (nonopt_start == -1)
                    455:                                nonopt_start = optind;
                    456:                        else if (nonopt_end != -1) {
                    457:                                permute_args(nonopt_start, nonopt_end,
                    458:                                    optind, nargv);
                    459:                                nonopt_start = optind -
                    460:                                    (nonopt_end - nonopt_start);
                    461:                                nonopt_end = -1;
                    462:                        }
                    463:                        optind++;
                    464:                        /* process next argument */
                    465:                        goto start;
                    466:                }
                    467:                if (nonopt_start != -1 && nonopt_end == -1)
                    468:                        nonopt_end = optind;
                    469: 
                    470:                /*
                    471:                 * If we have "-" do nothing, if "--" we are done.
                    472:                 */
                    473:                if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
                    474:                        optind++;
                    475:                        place = EMSG;
                    476:                        /*
                    477:                         * We found an option (--), so if we skipped
                    478:                         * non-options, we have to permute.
                    479:                         */
                    480:                        if (nonopt_end != -1) {
                    481:                                permute_args(nonopt_start, nonopt_end,
                    482:                                    optind, nargv);
                    483:                                optind -= nonopt_end - nonopt_start;
                    484:                        }
                    485:                        nonopt_start = nonopt_end = -1;
                    486:                        return (-1);
                    487:                }
                    488:        }
                    489: 
                    490:        /*
                    491:         * Check long options if:
                    492:         *  1) we were passed some
                    493:         *  2) the arg is not just "-"
                    494:         *  3) either the arg starts with -- we are getopt_long_only()
                    495:         */
                    496:        if (long_options != NULL && place != nargv[optind] &&
                    497:            (*place == '-' || (flags & FLAG_LONGONLY))) {
                    498:                short_too = 0;
                    499: #ifdef GNU_COMPATIBLE
                    500:                dash_prefix = D_PREFIX;
                    501: #endif
                    502:                if (*place == '-') {
                    503:                        place++;                /* --foo long option */
                    504: #ifdef GNU_COMPATIBLE
                    505:                        dash_prefix = DD_PREFIX;
                    506: #endif
                    507:                } else if (*place != ':' && strchr(options, *place) != NULL)
                    508:                        short_too = 1;          /* could be short option too */
                    509: 
                    510:                optchar = parse_long_options(nargv, options, long_options,
                    511:                    idx, short_too, flags);
                    512:                if (optchar != -1) {
                    513:                        place = EMSG;
                    514:                        return (optchar);
                    515:                }
                    516:        }
                    517: 
                    518:        if ((optchar = (int)*place++) == (int)':' ||
                    519:            (optchar == (int)'-' && *place != '\0') ||
                    520:            (oli = strchr(options, optchar)) == NULL) {
                    521:                /*
                    522:                 * If the user specified "-" and  '-' isn't listed in
                    523:                 * options, return -1 (non-option) as per POSIX.
                    524:                 * Otherwise, it is an unknown option character (or ':').
                    525:                 */
                    526:                if (optchar == (int)'-' && *place == '\0')
                    527:                        return (-1);
                    528:                if (!*place)
                    529:                        ++optind;
                    530: #ifdef GNU_COMPATIBLE
                    531:                if (PRINT_ERROR)
                    532:                        warningx(posixly_correct ? illoptchar : gnuoptchar,
                    533:                              optchar);
                    534: #else
                    535:                if (PRINT_ERROR)
                    536:                        warningx(illoptchar, optchar);
                    537: #endif
                    538:                optopt = optchar;
                    539:                return (BADCH);
                    540:        }
                    541:        if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
                    542:                /* -W long-option */
                    543:                if (*place)                     /* no space */
                    544:                        /* NOTHING */;
                    545:                else if (++optind >= nargc) {   /* no arg */
                    546:                        place = EMSG;
                    547:                        if (PRINT_ERROR)
                    548:                                warningx(recargchar, optchar);
                    549:                        optopt = optchar;
                    550:                        return (BADARG);
                    551:                } else                          /* white space */
                    552:                        place = nargv[optind];
                    553: #ifdef GNU_COMPATIBLE
                    554:                dash_prefix = W_PREFIX;
                    555: #endif
                    556:                optchar = parse_long_options(nargv, options, long_options,
                    557:                    idx, 0, flags);
                    558:                place = EMSG;
                    559:                return (optchar);
                    560:        }
                    561:        if (*++oli != ':') {                    /* doesn't take argument */
                    562:                if (!*place)
                    563:                        ++optind;
                    564:        } else {                                /* takes (optional) argument */
                    565:                optarg = NULL;
                    566:                if (*place)                     /* no white space */
                    567:                        optarg = place;
                    568:                else if (oli[1] != ':') {       /* arg not optional */
                    569:                        if (++optind >= nargc) {        /* no arg */
                    570:                                place = EMSG;
                    571:                                if (PRINT_ERROR)
                    572:                                        warningx(recargchar, optchar);
                    573:                                optopt = optchar;
                    574:                                return (BADARG);
                    575:                        } else
                    576:                                optarg = nargv[optind];
                    577:                }
                    578:                place = EMSG;
                    579:                ++optind;
                    580:        }
                    581:        /* dump back option letter */
                    582:        return (optchar);
                    583: }
                    584: 
                    585: #ifdef REPLACE_GETOPT
                    586: /*
                    587:  * getopt --
                    588:  *     Parse argc/argv argument vector.
                    589:  */
                    590: int
                    591: getopt(int nargc, char * const *nargv, const char *options)
                    592: {
                    593: 
                    594:        /*
                    595:         * We don't pass FLAG_PERMUTE to getopt_internal() since
                    596:         * the BSD getopt(3) (unlike GNU) has never done this.
                    597:         *
                    598:         * Furthermore, since many privileged programs call getopt()
                    599:         * before dropping privileges it makes sense to keep things
                    600:         * as simple (and bug-free) as possible.
                    601:         */
                    602:        return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
                    603: }
                    604: #endif /* REPLACE_GETOPT */
                    605: 
                    606: /*
                    607:  * getopt_long --
                    608:  *     Parse argc/argv argument vector.
                    609:  */
                    610: int
                    611: getopt_long(int nargc, char * const *nargv, const char *options,
                    612:        const struct option *long_options, int *idx)
                    613: {
                    614: 
                    615:        return (getopt_internal(nargc, nargv, options, long_options, idx,
                    616:            FLAG_PERMUTE));
                    617: }
                    618: 
                    619: /*
                    620:  * getopt_long_only --
                    621:  *     Parse argc/argv argument vector.
                    622:  */
                    623: int
                    624: getopt_long_only(int nargc, char * const *nargv, const char *options,
                    625:        const struct option *long_options, int *idx)
                    626: {
                    627: 
                    628:        return (getopt_internal(nargc, nargv, options, long_options, idx,
                    629:            FLAG_PERMUTE|FLAG_LONGONLY));
                    630: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>