File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / compat / getopt_long.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:33 2013 UTC (10 years, 8 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, v1_8_10p3_0, v1_8_10p3, HEAD
v 1.8.8

    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>