23#define ALIGNOF(x) alignof(x)
25#define ALIGNOF(x) __alignof__(x)
27#define ALIGNOF(x) sizeof(x)
37#if !defined(HAVE_STRERROR)
41 extern char * sys_errlist[];
43 if ((0 <= errno) && (errno < sys_nerr))
44 return sys_errlist[errno];
46 return POPT_(
"unknown errno");
53 if (msg) fprintf(stderr,
"%s", msg);
54 fprintf(stderr,
"\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n",
57 (con->os->nextArg ? con->os->nextArg :
""),
59 (con->os->argv && con->os->argv[con->os->next]
60 ? con->os->argv[con->os->next] :
""));
66 if (con == NULL)
return;
75 if (con == NULL || opt == NULL)
return;
95 if (con == NULL || opt == NULL)
return;
116 const void * myData,
int shorty)
121 if (con == NULL || opt == NULL)
return;
127 if (opt->
arg != NULL)
137 if (cbopt == NULL || cbarg.
cb == NULL)
143 {
const void *cbData = (cbopt->
descrip ? cbopt->
descrip : myData);
156 const struct poptOption * options,
unsigned int flags)
160 if (argc < 1)
return NULL;
162 con = malloc(
sizeof(*con));
163 if (con == NULL)
return NULL;
164 memset(con, 0,
sizeof(*con));
188 if (getenv(
"POSIXLY_CORRECT") || getenv(
"POSIX_ME_HARDER"))
210 if (con == NULL)
return;
246 for (i = con->
numExecs - 1; i >= 0; i--) {
247 item = con->
execs + i;
261 if (con->
doExec == NULL) {
302 const char *
longName,
size_t longNameLen)
304 const char * optLongName = opt->
longName;
307 if (optLongName == NULL ||
longName == NULL)
311 if (optLongName[0] ==
'n' && optLongName[1] ==
'o') {
312 optLongName +=
sizeof(
"no") - 1;
313 if (optLongName[0] ==
'-')
318 longNameLen -=
sizeof(
"no") - 1;
325 rc = (int)(strlen(optLongName) == longNameLen);
327 rc = (int)(strncmp(optLongName,
longName, longNameLen) == 0);
333 const char *
longName,
size_t longNameLen,
335 const char * nextArg)
369 if (
longName == NULL && nextArg != NULL && *nextArg !=
'\0')
381 if (
longName && nextArg != NULL && *nextArg !=
'\0') {
382 av = malloc((ac + 1 + 1) *
sizeof(*av));
384 for (i = 0; i < ac; i++) {
399 return (rc ? rc : 1);
410 char *path = NULL, *s = NULL, *se;
413 if (argv0 == NULL)
return NULL;
417 if (strchr(argv0,
'/'))
420 if ((path = getenv(
"PATH")) == NULL || (path =
xstrdup(path)) == NULL)
424 if ((t = malloc(strlen(path) + strlen(argv0) +
sizeof(
"/"))) != NULL)
425 for (s = path; s && *s; s = se) {
428 if ((se = strchr(s,
':')))
435 if (!access(t, X_OK))
440 if (!(s && *s) && t != NULL)
458 if (item->
argv == NULL || item->
argc < 1 ||
462 argv = malloc(
sizeof(*argv) *
466 if (!strchr(item->
argv[0],
'/') && con->
execPath != NULL) {
467 char *s = malloc(strlen(con->
execPath) + strlen(item->
argv[0]) +
sizeof(
"/"));
474 if (argv[argc++] == NULL) {
479 if (item->
argc > 1) {
480 memcpy(argv + argc, item->
argv + 1,
sizeof(*argv) * (item->
argc - 1));
481 argc += (item->
argc - 1);
497#if defined(hpux) || defined(__hpux)
498 rc = setresgid(getgid(), getgid(),-1);
500 rc = setresuid(getuid(), getuid(),-1);
508#if defined(HAVE_SETUID)
509 rc = setgid(getgid());
511 rc = setuid(getuid());
513#elif defined (HAVE_SETREUID)
514 rc = setregid(getgid(), getgid());
516 rc = setreuid(getuid(), getuid());
520 if (getuid() != geteuid() || getgid() != getegid()) {
530 fprintf(stderr,
"==> execvp(%s) argv[%d]:", argv[0], argc);
531 for (avp = argv; *avp; avp++)
532 fprintf(stderr,
" '%s'", *avp);
533 fprintf(stderr,
"\n");
537 rc = execvp(argv[0], (
char *
const *)argv);
545 free((
void *)argv[0]);
553 const char *
longName,
size_t longNameLen,
556 const void ** callbackData,
574 if (
arg.ptr == NULL)
continue;
577 if (opt2 == NULL)
continue;
579 if (callback && *callback
580 && callbackData && *callbackData == NULL)
607 *callback = (cb ? cbarg.
cb : NULL);
615 unsigned argx,
int delete_arg)
620 if (os == NULL || con->
optionStack == NULL)
return NULL;
627 if (os->
argv != NULL)
628 for (i = os->
next; i < os->
argc; i++) {
631 if (*os->
argv[i] ==
'-')
638 if (os->
argb != NULL)
644 }
while (arg == NULL);
651 const char * a = NULL;
653 size_t tn = strlen(s) + 1;
656 if (con == NULL)
return NULL;
659 if (t == NULL)
return NULL;
661 while ((c = *s++) !=
'\0') {
669 if (!(s[0] ==
'#' && s[1] ==
':' && s[2] ==
'+'))
676 s +=
sizeof(
"#:+") - 1;
679 {
size_t pos = (size_t) (te - t);
680 if ((t = realloc(t, tn)) == NULL)
694 if ((te = realloc(t, (
size_t)(te - t))) == NULL)
720 if (*bitsp == NULL) {
734 size_t ns = (s ? strlen(s) : 0);
738 if (bits == NULL || ns == 0)
744 uint32_t h = h0 + ns * h1;
753 size_t ns = (s ? strlen(s) : 0);
758 if (bits == NULL || ns == 0)
764 uint32_t h = h0 + ns * h1;
781 memset(bits, 0, nw * nbw);
787 size_t ns = (s ? strlen(s) : 0);
791 if (bits == NULL || ns == 0)
797 uint32_t h = h0 + ns * h1;
817 for (i = 0; i < nw; i++) {
818 abits[i] &= bbits[i];
837 for (i = 0; i < nw; i++) {
838 abits[i] |= bbits[i];
864 UNUSED(
unsigned int argInfo),
const char * s)
870 if (bitsp == NULL || s == NULL || *s ==
'\0' ||
_poptBitsNew(bitsp))
875 while ((t = te) != NULL && *t) {
876 while (*te !=
'\0' && *te !=
',')
898 UNUSED(
unsigned int argInfo),
const char * val)
902 if (argvp == NULL || val == NULL)
907 while ((*argvp)[
argc] != NULL)
910 if ((*argvp =
xrealloc(*argvp, (
argc + 1 + 1) *
sizeof(**argvp))) != NULL) {
912 (*argvp)[
argc ] = NULL;
922 if (arg == NULL || (((
unsigned long)arg) & (
ALIGNOF(*arg)-1)))
925 if (aLongLong != 0 &&
LF_ISSET(RANDOM)) {
926#if defined(HAVE_SRANDOM)
928 srandom((
unsigned)getpid());
929 srandom((
unsigned)random());
931 aLongLong = (
long long)(random() % (aLongLong > 0 ? aLongLong : -aLongLong));
939 aLongLong = ~aLongLong;
945 *(
unsigned long long *)arg |= (
unsigned long long)aLongLong;
948 *(
unsigned long long *)arg &= (
unsigned long long)aLongLong;
951 *(
unsigned long long *)arg ^= (
unsigned long long)aLongLong;
963 if (arg == NULL || (((
unsigned long)arg) & (
ALIGNOF(*arg)-1)))
966 if (aLong != 0 &&
LF_ISSET(RANDOM)) {
967#if defined(HAVE_SRANDOM)
969 srandom((
unsigned)getpid());
970 srandom((
unsigned)random());
972 aLong = random() % (aLong > 0 ? aLong : -aLong);
982 case 0: *arg = aLong;
break;
983 case POPT_ARGFLAG_OR: *(
unsigned long *)arg |= (
unsigned long)aLong;
break;
984 case POPT_ARGFLAG_AND: *(
unsigned long *)arg &= (
unsigned long)aLong;
break;
985 case POPT_ARGFLAG_XOR: *(
unsigned long *)arg ^= (
unsigned long)aLong;
break;
996 if (arg == NULL || (((
unsigned long)arg) & (
ALIGNOF(*arg)-1)))
999 if (aLong != 0 &&
LF_ISSET(RANDOM)) {
1000#if defined(HAVE_SRANDOM)
1002 srandom((
unsigned)getpid());
1003 srandom((
unsigned)random());
1005 aLong = random() % (aLong > 0 ? aLong : -aLong);
1015 case 0: *arg = (int) aLong;
break;
1016 case POPT_ARGFLAG_OR: *(
unsigned int *)arg |= (
unsigned int) aLong;
break;
1017 case POPT_ARGFLAG_AND: *(
unsigned int *)arg &= (
unsigned int) aLong;
break;
1018 case POPT_ARGFLAG_XOR: *(
unsigned int *)arg ^= (
unsigned int) aLong;
break;
1029 if (arg == NULL || (((
unsigned long)arg) & (
ALIGNOF(*arg)-1)))
1032 if (aLong != 0 &&
LF_ISSET(RANDOM)) {
1033#if defined(HAVE_SRANDOM)
1035 srandom((
unsigned)getpid());
1036 srandom((
unsigned)random());
1038 aLong = random() % (aLong > 0 ? aLong : -aLong);
1048 case 0: *arg = (short) aLong;
1050 case POPT_ARGFLAG_OR: *(
unsigned short *)arg |= (
unsigned short) aLong;
1070 unsigned int argInfo = opt->
argInfo;
1074 const char * longName = con->
os->
argv[con->
os->
next-1];
1075 while (*longName ==
'-') longName++;
1098 UNUSED(
unsigned int argInfo),
1103 *llp = strtoll(val, &end, 0);
1107 if (!(end && *end ==
'\0'))
1152#if !defined(LLONG_MAX)
1153# define LLONG_MAX 9223372036854775807LL
1154# define LLONG_MIN (-LLONG_MAX - 1LL)
1161 rc = !(aNUM < (long long)LONG_MIN || aNUM > (
long long)LONG_MAX)
1166 rc = !(aNUM < (long long)INT_MIN || aNUM > (
long long)INT_MAX)
1171 rc = !(aNUM < (long long)SHRT_MIN || aNUM > (
long long)SHRT_MAX)
1181 double aDouble = 0.0;
1184 int saveerrno = errno;
1186 aDouble = strtod(con->
os->
nextArg, &end);
1187 if (errno == ERANGE) {
1203#define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
1204 if ((FLT_MIN -
POPT_ABS(aDouble)) > DBL_EPSILON
1205 || (
POPT_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
1208 arg.
floatp[0] = (float) aDouble;
1216 fprintf(stdout,
POPT_(
"option type (%u) not implemented in popt\n"),
1233 const char * origOptString = NULL;
1235 const void * cbData = NULL;
1236 const char * longArg = NULL;
1258 const char * optString;
1259 size_t optStringLen;
1267 if (con->
os->
argv != NULL)
1270 if (origOptString == NULL)
1274 (*origOptString ==
'-' && origOptString[1] ==
'\0'))
1288 optString = origOptString;
1290 if (optString[0] ==
'\0')
1293 if (optString[1] ==
'-' && !optString[2]) {
1301 if (*optString ==
'-')
1307 for (oe = optString; *oe && *oe !=
'='; oe++)
1309 optStringLen = (size_t)(oe - optString);
1314 if (
handleAlias(con, optString, optStringLen,
'\0', longArg)) {
1347 if (
handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1))
1353 if (*nextCharArg !=
'\0')
1365 if (*nextCharArg !=
'\0')
1366 con->
os->
nextCharArg = nextCharArg + (int)(*nextCharArg ==
'=');
1408 &&
F_ISSET(opt, STRIP) && canstrip)
1413 if (con->
os->
argv != NULL) {
1446 {
char *s = malloc((opt->
longName ? strlen(opt->
longName) : 0) +
sizeof(
"--"));
1473 return (opt ? opt->
val : -1);
1488 const char * ret = NULL;
1496 const char * ret = NULL;
1517 if (items != NULL) {
1519 while (--nitems >= 0) {
1526 items =
_free(items);
1533 if (con == NULL)
return con;
1559 if (con == NULL)
return 1;
1561 memset(item, 0,
sizeof(*item));
1562 item->option.longName = alias.
longName;
1563 item->option.shortName = alias.
shortName;
1565 item->option.arg = 0;
1566 item->option.val = 0;
1567 item->option.descrip = NULL;
1568 item->option.argDescrip = NULL;
1569 item->argc = alias.
argc;
1570 item->argv = alias.
argv;
1579 if (con == NULL)
return 1;
1583 items = &con->
execs;
1595 *items = realloc((*items), ((*nitems) + 1) *
sizeof(**items));
1596 if ((*items) == NULL)
1599 item = (*items) + (*nitems);
1644 return POPT_(
"missing argument");
1646 return POPT_(
"unknown option");
1648 return POPT_(
"mutually exclusive logical operations requested");
1650 return POPT_(
"opt->arg should not be NULL");
1652 return POPT_(
"aliases nested too deeply");
1654 return POPT_(
"error in parameter quoting");
1656 return POPT_(
"invalid numeric value");
1658 return POPT_(
"number too large or too small");
1660 return POPT_(
"memory allocation failed");
1662 return POPT_(
"config file failed sanity test");
1666 return POPT_(
"no context");
1668 return POPT_(
"unknown error");
1700 return ((con && con->
os->
argv) ? con->
os->
argv[0] :
"");
1710 for (i = 1; i <
argc; i++) {
1715 for (i = 1; i <
argc; i++) {
1718 argv[j] = (j < numargs) ?
argv[i] : NULL;
static void invokeCallbacksPOST(poptContext con, const struct poptOption *opt)
char * poptGetOptArg(poptContext con)
Return next option argument (if any).
static int poptParseInteger(long long *llp, unsigned int argInfo, const char *val)
Parse an integer expression.
void poptSetExecPath(poptContext con, const char *path, int allowAbsolute)
Limit search for executables.
const char ** poptGetArgs(poptContext con)
Return remaining arguments.
const char * poptBadOption(poptContext con, unsigned int flags)
Return the option which caused the most recent error.
int poptSaveInt(int *arg, unsigned int argInfo, long aLong)
Save an integer, performing logical operation with value.
int poptStuffArgs(poptContext con, const char **argv)
Add arguments to context.
const char * poptStrerror(const int error)
Return formatted error string for popt failure.
static unsigned int poptArgInfo(poptContext con, const struct poptOption *opt)
Return argInfo field, handling POPT_ARGFLAG_TOGGLE overrides.
static int execCommand(poptContext con)
static int handleExec(poptContext con, const char *longName, char shortName)
int poptBitsUnion(poptBits *ap, const poptBits b)
unsigned int _poptGroupMask
int poptAddAlias(poptContext con, struct poptAlias alias, int flags)
Add alias to context.
int poptStrippedArgv(poptContext con, int argc, char **argv)
Shuffle argv pointers to remove stripped args, returns new argc.
const char * poptPeekArg(poptContext con)
Peek at current argument.
int poptAddItem(poptContext con, poptItem newItem, int flags)
Add alias/exec item to context.
static int handleAlias(poptContext con, const char *longName, size_t longNameLen, char shortName, const char *nextArg)
static void invokeCallbacksOPTION(poptContext con, const struct poptOption *opt, const struct poptOption *myOpt, const void *myData, int shorty)
void poptResetContext(poptContext con)
Reinitialize popt context.
int poptBitsClr(poptBits bits)
int poptBitsChk(poptBits bits, const char *s)
const char * poptGetArg(poptContext con)
Return next argument.
static const char * expandNextArg(poptContext con, const char *s)
int poptGetNextOpt(poptContext con)
Return value of next option found.
static int longOptionStrcmp(const struct poptOption *opt, const char *longName, size_t longNameLen)
Compare long option for equality, adjusting for POPT_ARGFLAG_TOGGLE.
int poptBitsIntersect(poptBits *ap, const poptBits b)
int poptBitsArgs(poptContext con, poptBits *ap)
static poptItem poptFreeItems(poptItem items, int nitems)
static char * strerror(int errno)
static void cleanOSE(struct optionStackEntry *os)
int poptSaveLongLong(long long *arg, unsigned int argInfo, long long aLongLong)
Save a long long, performing logical operation with value.
unsigned int _poptArgMask
const char * poptGetInvocationName(poptContext con)
Return argv[0] from context.
static void invokeCallbacksPRE(poptContext con, const struct poptOption *opt)
int poptSaveString(const char ***argvp, unsigned int argInfo, const char *val)
Add a string to an argv array.
static const char * findNextArg(poptContext con, unsigned argx, int delete_arg)
static int _poptBitsNew(poptBits *bitsp)
poptContext poptGetContext(const char *name, int argc, const char **argv, const struct poptOption *options, unsigned int flags)
Initialize popt context.
int poptBitsAdd(poptBits bits, const char *s)
static const struct poptOption * findOption(const struct poptOption *opt, const char *longName, size_t longNameLen, char shortName, poptCallbackType *callback, const void **callbackData, unsigned int argInfo)
poptContext poptFreeContext(poptContext con)
Destroy context.
int poptSaveLong(long *arg, unsigned int argInfo, long aLong)
Save a long, performing logical operation with value.
int poptSaveBits(poptBits *bitsp, unsigned int argInfo, const char *s)
Save a string into a bit set (experimental).
int poptBitsDel(poptBits bits, const char *s)
int poptSaveShort(short *arg, unsigned int argInfo, long aLong)
Save a short integer, performing logical operation with value.
static int poptSaveArg(poptContext con, const struct poptOption *opt)
Save the option argument through the (*opt->arg) pointer.
static void poptStripArg(poptContext con, int which)
static const char * findProgramPath(const char *argv0)
Return absolute path to executable by searching PATH.
#define POPT_ERROR_OVERFLOW
#define POPT_CONTEXT_KEEP_FIRST
#define POPT_ERROR_OPTSTOODEEP
void(* poptCallbackType)(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data)
Table callback prototype.
#define POPT_ERROR_BADOPT
#define POPT_ARGFLAG_DOC_HIDDEN
#define POPT_ERROR_BADQUOTE
#define POPT_ARG_MAINCALL
#define POPT_CONTEXT_ARG_OPTS
#define POPT_ARGFLAG_ONEDASH
int poptDupArgv(int argc, const char **argv, int *argcPtr, const char ***argvPtr)
Duplicate an argument array.
#define POPT_CONTEXT_NO_EXEC
#define POPT_BADOPTION_NOALIAS
#define POPT_ERROR_BADOPERATION
#define POPT_ERROR_MALLOC
#define POPT_ARG_INCLUDE_TABLE
#define POPT_OPTION_DEPTH
#define POPT_ARG_LONGLONG
#define POPT_ERROR_NULLARG
#define POPT_ERROR_NOCONTEXT
#define POPT_ARG_CALLBACK
#define POPT_CONTEXT_POSIXMEHARDER
#define POPT_ERROR_BADNUMBER
#define POPT_ERROR_BADCONFIG
@ POPT_CALLBACK_REASON_PRE
@ POPT_CALLBACK_REASON_OPTION
@ POPT_CALLBACK_REASON_POST
#define F_ISSET(_opt, _FLAG)
#define CBF_ISSET(_opt, _FLAG)
#define poptSubstituteHelpI18N(opt)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
#define poptArgType(_opt)
void poptJlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb)
A popt alias argument for poptAddAlias().
const struct poptOption * options
struct optionStackEntry * os
int(* maincall)(int argc, const char **argv)
struct optionStackEntry optionStack[POPT_OPTION_DEPTH]
A popt alias or exec argument for poptAddItem().
static char * stpcpy(char *dest, const char *src)
#define xrealloc(_ptr, _size)
A union to simplify opt->arg access without casting.