update popt

This commit is contained in:
Elliot Lee 1998-11-03 23:34:54 +00:00
parent 5602fc5a1e
commit 154be9f2ed
8 changed files with 1005 additions and 436 deletions

View File

@ -23,7 +23,7 @@ SRCS = dir.c util.c main.c screen.c dialog.c key.c keyxdef.c menu.c\
wtools.c cons.handler.c chown.c subshell.c terms.c boxes.c \
hotlist.c achown.c layout.c fsusage.c mountlist.c regex.c \
complete.c slint.c command.c cmd.c panelize.c learn.c \
listmode.c utilunix.c background.c rxvt.c popt.c \
listmode.c utilunix.c background.c rxvt.c \
text.c
HDRS = color.h file.h mouse.h user.h dialog.h find.h main.h \
@ -34,7 +34,7 @@ HDRS = color.h file.h mouse.h user.h dialog.h find.h main.h \
hotlist.h layout.h fsusage.h mountlist.h regex.h complete.h \
myslang.h command.h cmd.h tty.h fs.h panelize.h achown.h \
learn.h listmode.h features.inc background.h \
x.h popt.h textconf.h i18n.h
x.h textconf.h i18n.h
OBJS = dir.o util.o screen.o dialog.o key.o keyxdef.o menu.o\
file.o win.o color.o help.o find.o profile.o user.o view.o \
@ -44,7 +44,7 @@ OBJS = dir.o util.o screen.o dialog.o key.o keyxdef.o menu.o\
hotlist.o achown.o layout.o fsusage.o mountlist.o \
@XCURSES@ @REGEX_O@ complete.o slint.o command.o \
cmd.o main.o panelize.o learn.o listmode.o utilunix.o \
background.o rxvt.o popt.o text.o
background.o rxvt.o text.o
#
# Distribution variables

60
src/findme.c Normal file
View File

@ -0,0 +1,60 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef __NeXT
/* access macros are not declared in non posix mode in unistd.h -
don't try to use posix on NeXTstep 3.3 ! */
#include <libc.h>
#endif
#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "findme.h"
char * findProgramPath(char * argv0) {
char * path = getenv("PATH");
char * pathbuf;
char * start, * chptr;
char * buf;
/* If there is a / in the argv[0], it has to be an absolute
path */
if (strchr(argv0, '/'))
return strdup(argv0);
if (!path) return NULL;
start = pathbuf = alloca(strlen(path) + 1);
buf = malloc(strlen(path) + strlen(argv0) + 2);
strcpy(pathbuf, path);
chptr = NULL;
do {
if ((chptr = strchr(start, ':')))
*chptr = '\0';
sprintf(buf, "%s/%s", start, argv0);
if (!access(buf, X_OK))
return buf;
if (chptr)
start = chptr + 1;
else
start = NULL;
} while (start && *start);
free(buf);
return NULL;
}

View File

@ -2783,7 +2783,13 @@ static struct argp mc_argp_parser = {
argp_options, parse_an_arg, N_("[this dir] [other dir]"), NULL, NULL, NULL, NULL
};
#else
#else
#include <glib.h>
char *cmdline_geometry = NULL;
int nowindows = 0;
char **directory_list = NULL;
static struct poptOption argumentTable[] = {
#ifdef WITH_BACKGROUND
@ -2799,7 +2805,9 @@ static struct poptOption argumentTable[] = {
#endif
{ "edit", 'e', POPT_ARG_STRING, &edit_one_file, 0 },
#ifndef HAVE_GNOME
{ "help", 'h', POPT_ARG_NONE, NULL, 'h' },
#endif
{ "help-colors", 'H', POPT_ARG_NONE, NULL, 'H' },
#ifdef USE_NETCODE
{ "ftplog", 'l', POPT_ARG_STRING, NULL, 'l' },
@ -2827,6 +2835,10 @@ static struct poptOption argumentTable[] = {
{ "version", 'V', POPT_ARG_NONE, NULL, 'V'},
{ "view", 'v', POPT_ARG_STRING, &view_one_file, 0 },
{ "xterm", 'x', POPT_ARG_NONE, &force_xterm, 0},
#ifdef HAVE_GNOME
{ "geometry", '\0', POPT_ARG_STRING, &cmdline_geometry, 0, N_("Geometry for the window"), N_("GEOMETRY")},
{"nowindows", '\0', POPT_ARG_NONE, &nowindows, 0, N_("No windows opened at startup"), NULL},
#endif
{ NULL, 0, 0, NULL, 0 }
};
@ -2838,7 +2850,12 @@ handle_args (int argc, char *argv [])
int c;
poptContext optCon;
#ifdef HAVE_GNOME
gnome_init_with_popt_table ("gmc", VERSION, argc, argv, argumentTable, 0, &optCon);
/* poptResetContext(optCon); */
#else
optCon = poptGetContext ("mc", argc, argv, argumentTable, 0);
#endif
#ifdef USE_TERMCAP
SLtt_Try_Termcap = 1;
@ -2884,6 +2901,8 @@ handle_args (int argc, char *argv [])
other_dir = strdup (tmp);
}
}
poptFreeContext(optCon);
}
#endif
@ -2986,7 +3005,9 @@ int main (int argc, char *argv [])
view_one_file = "";
}
}
gnome_init ("gmc", &mc_argp_parser, argc, argv, 0, NULL);
handle_args(argc, argv);
session_management_setup (argv [0]);
probably_finish_program ();
#endif

View File

@ -1,9 +1,11 @@
/*
*
* Written by Erik Troan (ewt@redhat.com).
*
*/
#include <config.h>
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
@ -11,73 +13,81 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#ifdef HAVE_MMAP
# include <sys/mman.h>
#else
# include "util.h"
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef OS2_NT
# include <io.h>
#include <unistd.h>
#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "findme.h"
#include "popt.h"
#include "poptint.h"
struct optionStackEntry {
int argc;
char ** argv;
int next;
char * nextArg;
char * nextCharArg;
struct poptAlias * currAlias;
};
#ifndef HAVE_STRERROR
static char * strerror(int errno) {
extern int sys_nerr;
extern char * sys_errlist[];
struct poptContext_s {
struct optionStackEntry optionStack[POPT_OPTION_DEPTH], * os;
char ** leftovers;
int numLeftovers;
int nextLeftover;
struct poptOption * options;
int restLeftover;
char * appName;
struct poptAlias * aliases;
int numAliases;
int flags;
};
if ((0 <= errno) && (errno < sys_nerr))
return sys_errlist[errno];
else
return POPT_("unknown errno");
}
#endif
poptContext poptGetContext(char * name ,int argc, char ** argv,
struct poptOption * options, int flags) {
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) {
if (con->execPath) free(con->execPath);
con->execPath = strdup(path);
con->execAbsolute = allowAbsolute;
}
static void invokeCallbacks(poptContext con, const struct poptOption * table,
int post) {
const struct poptOption * opt = table;
poptCallbackType cb;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
invokeCallbacks(con, opt->arg, post);
} else if (((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) &&
((!post && (opt->argInfo & POPT_CBFLAG_PRE)) ||
( post && (opt->argInfo & POPT_CBFLAG_POST)))) {
cb = opt->arg;
cb(con, post ? POPT_CALLBACK_REASON_POST : POPT_CALLBACK_REASON_PRE,
NULL, NULL, opt->descrip);
}
opt++;
}
}
poptContext poptGetContext(char * name, int argc, char ** argv,
const struct poptOption * options, int flags) {
poptContext con = malloc(sizeof(*con));
memset(con, 0, sizeof(*con));
con->os = con->optionStack;
con->os->argc = argc;
con->os->argv = argv;
con->os->currAlias = NULL;
con->os->nextCharArg = NULL;
con->os->nextArg = NULL;
if (flags & POPT_KEEP_FIRST)
con->os->next = 0; /* include argv[0] */
else
if (!(flags & POPT_CONTEXT_KEEP_FIRST))
con->os->next = 1; /* skip argv[0] */
con->leftovers = malloc(sizeof(char *) * (argc + 1));
con->numLeftovers = 0;
con->nextLeftover = 0;
con->restLeftover = 0;
con->options = options;
con->aliases = NULL;
con->numAliases = 0;
con->flags = 0;
con->finalArgv = malloc(sizeof(*con->finalArgv) * (argc * 2));
con->finalArgvAlloced = argc * 2;
con->flags = flags;
con->execAbsolute = 1;
if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
con->flags |= POPT_CONTEXT_POSIXMEHARDER;
if (!name)
con->appName = NULL;
else
if (name)
con->appName = strcpy(malloc(strlen(name) + 1), name);
invokeCallbacks(con, con->options, 0);
return con;
}
@ -91,6 +101,174 @@ void poptResetContext(poptContext con) {
con->numLeftovers = 0;
con->nextLeftover = 0;
con->restLeftover = 0;
con->doExec = NULL;
con->finalArgvCount = 0;
}
/* Only one of longName, shortName may be set at a time */
static int handleExec(poptContext con, char * longName, char shortName) {
int i;
i = con->numExecs - 1;
if (longName) {
while (i >= 0 && (!con->execs[i].longName ||
strcmp(con->execs[i].longName, longName))) i--;
} else {
while (i >= 0 &&
con->execs[i].shortName != shortName) i--;
}
if (i < 0) return 0;
if (con->flags & POPT_CONTEXT_NO_EXEC)
return 1;
if (!con->doExec) {
con->doExec = con->execs + i;
return 1;
}
/* We already have an exec to do; remember this option for next
time 'round */
if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) {
con->finalArgvAlloced += 10;
con->finalArgv = realloc(con->finalArgv,
sizeof(*con->finalArgv) * con->finalArgvAlloced);
}
i = con->finalArgvCount++;
con->finalArgv[i] = malloc((longName ? strlen(longName) : 0) + 3);
if (longName)
sprintf(con->finalArgv[i], "--%s", longName);
else
sprintf(con->finalArgv[i], "-%c", shortName);
return 1;
}
/* Only one of longName, shortName may be set at a time */
static int handleAlias(poptContext con, char * longName, char shortName,
char * nextCharArg) {
int i;
if (con->os->currAlias && con->os->currAlias->longName && longName &&
!strcmp(con->os->currAlias->longName, longName))
return 0;
if (con->os->currAlias && shortName == con->os->currAlias->shortName)
return 0;
i = con->numAliases - 1;
if (longName) {
while (i >= 0 && (!con->aliases[i].longName ||
strcmp(con->aliases[i].longName, longName))) i--;
} else {
while (i >= 0 &&
con->aliases[i].shortName != shortName) i--;
}
if (i < 0) return 0;
if ((con->os - con->optionStack + 1)
== POPT_OPTION_DEPTH)
return POPT_ERROR_OPTSTOODEEP;
if (nextCharArg && *nextCharArg)
con->os->nextCharArg = nextCharArg;
con->os++;
con->os->next = 0;
con->os->stuffed = 0;
con->os->nextArg = con->os->nextCharArg = NULL;
con->os->currAlias = con->aliases + i;
con->os->argc = con->os->currAlias->argc;
con->os->argv = con->os->currAlias->argv;
return 1;
}
static void execCommand(poptContext con) {
char ** argv;
int pos = 0;
char * script = con->doExec->script;
argv = malloc(sizeof(*argv) *
(6 + con->numLeftovers + con->finalArgvCount));
if (!con->execAbsolute && strchr(script, '/')) return;
if (!strchr(script, '/') && con->execPath) {
argv[pos] = alloca(strlen(con->execPath) + strlen(script) + 2);
sprintf(argv[pos], "%s/%s", con->execPath, script);
} else {
argv[pos] = script;
}
pos++;
argv[pos] = findProgramPath(con->os->argv[0]);
if (argv[pos]) pos++;
argv[pos++] = ";";
memcpy(argv + pos, con->finalArgv, sizeof(*argv) * con->finalArgvCount);
pos += con->finalArgvCount;
if (con->numLeftovers) {
argv[pos++] = "--";
memcpy(argv + pos, con->leftovers, sizeof(*argv) * con->numLeftovers);
pos += con->numLeftovers;
}
argv[pos++] = NULL;
#ifdef __hpux
setresuid(getuid(), getuid(),-1);
#else
setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */
#endif
execvp(argv[0], argv);
}
static const struct poptOption * findOption(const struct poptOption * table,
const char * longName,
const char shortName,
poptCallbackType * callback,
void ** callbackData,
int singleDash) {
const struct poptOption * opt = table;
const struct poptOption * opt2;
const struct poptOption * cb = NULL;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
opt2 = findOption(opt->arg, longName, shortName, callback,
callbackData, singleDash);
if (opt2) {
if (*callback && !*callbackData)
*callbackData = opt->descrip;
return opt2;
}
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) {
cb = opt;
} else if (longName && opt->longName &&
(!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) &&
!strcmp(longName, opt->longName)) {
break;
} else if (shortName && shortName == opt->shortName) {
break;
}
opt++;
}
if (!opt->longName && !opt->shortName) return NULL;
*callbackData = NULL;
*callback = NULL;
if (cb) {
*callback = cb->arg;
if (!(cb->argInfo & POPT_CBFLAG_INC_DATA))
*callbackData = cb->descrip;
}
return opt;
}
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
@ -100,16 +278,22 @@ int poptGetNextOpt(poptContext con) {
char * origOptString;
long aLong;
char * end;
struct poptOption * opt = NULL;
const struct poptOption * opt = NULL;
int done = 0;
int i;
poptCallbackType cb;
void * cbData;
int singleDash;
while (!done) {
while (!con->os->nextCharArg && con->os->next == con->os->argc
&& con->os > con->optionStack)
con->os--;
if (!con->os->nextCharArg && con->os->next == con->os->argc)
if (!con->os->nextCharArg && con->os->next == con->os->argc) {
invokeCallbacks(con, con->options, 1);
if (con->doExec) execCommand(con);
return -1;
}
if (!con->os->nextCharArg) {
@ -117,46 +301,33 @@ int poptGetNextOpt(poptContext con) {
if (con->restLeftover || *origOptString != '-') {
con->leftovers[con->numLeftovers++] = origOptString;
if (con->flags & POPT_CONTEXT_POSIXMEHARDER)
con->restLeftover = 1;
continue;
}
if (!origOptString[0])
return POPT_ERROR_BADOPT;
/* Make a copy we can hack at */
localOptString = optString =
strcpy(malloc(strlen(origOptString) + 1),
strcpy(alloca(strlen(origOptString) + 1),
origOptString);
if (!optString[0])
return POPT_ERROR_BADOPT;
if (optString[1] == '-' && !optString[2]) {
con->restLeftover = 1;
free(localOptString);
continue;
} else if (optString[1] == '-') {
optString += 2;
} else {
optString++;
if (*optString == '-')
singleDash = 0, optString++;
else
singleDash = 1;
if (!con->os->currAlias || !con->os->currAlias->longName ||
strcmp(con->os->currAlias->longName, optString)) {
i = con->numAliases - 1;
while (i >= 0 && (!con->aliases[i].longName ||
strcmp(con->aliases[i].longName, optString))) i--;
if (i >= 0) {
free(localOptString);
if ((con->os - con->optionStack + 1)
== POPT_OPTION_DEPTH)
return POPT_ERROR_OPTSTOODEEP;
con->os++;
con->os->next = 0;
con->os->nextArg = con->os->nextCharArg = NULL;
con->os->currAlias = con->aliases + i;
con->os->argc = con->os->currAlias->argc;
con->os->argv = con->os->currAlias->argv;
continue;
}
}
if (handleAlias(con, optString, '\0', NULL))
continue;
if (handleExec(con, optString, '\0'))
continue;
chptr = optString;
while (*chptr && *chptr != '=') chptr++;
@ -165,66 +336,40 @@ int poptGetNextOpt(poptContext con) {
*chptr = '\0';
}
opt = con->options;
while (opt->longName || opt->shortName) {
if (opt->longName && !strcmp(optString, opt->longName))
break;
opt++;
}
opt = findOption(con->options, optString, '\0', &cb, &cbData,
singleDash);
if (!opt && !singleDash) return POPT_ERROR_BADOPT;
}
if (!opt->longName && !opt->shortName) {
free(localOptString);
return POPT_ERROR_BADOPT;
}
} else
if (!opt)
con->os->nextCharArg = origOptString + 1;
free(localOptString);
}
if (con->os->nextCharArg) {
origOptString = con->os->nextCharArg;
con->os->nextCharArg = NULL;
if (!con->os->currAlias || *origOptString !=
con->os->currAlias->shortName) {
i = con->numAliases - 1;
while (i >= 0 &&
con->aliases[i].shortName != *origOptString) i--;
if (i >= 0) {
if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH)
return POPT_ERROR_OPTSTOODEEP;
/* We'll need this on the way out */
origOptString++;
if (*origOptString)
con->os->nextCharArg = origOptString;
con->os++;
con->os->next = 0;
con->os->nextArg = con->os->nextCharArg = NULL;
con->os->currAlias = con->aliases + i;
con->os->argc = con->os->currAlias->argc;
con->os->argv = con->os->currAlias->argv;
continue;
}
if (handleAlias(con, NULL, *origOptString,
origOptString + 1)) {
origOptString++;
continue;
}
if (handleExec(con, NULL, *origOptString))
continue;
opt = con->options;
while ((opt->longName || opt->shortName) &&
*origOptString != opt->shortName) opt++;
if (!opt->longName && !opt->shortName) return POPT_ERROR_BADOPT;
opt = findOption(con->options, NULL, *origOptString, &cb,
&cbData, 0);
if (!opt) return POPT_ERROR_BADOPT;
origOptString++;
if (*origOptString)
con->os->nextCharArg = origOptString;
}
if (opt->arg && opt->argInfo == POPT_ARG_NONE)
if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE)
*((int *)opt->arg) = 1;
else if (opt->argInfo != POPT_ARG_NONE) {
else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) {
if (longArg) {
con->os->nextArg = longArg;
} else if (con->os->nextCharArg) {
@ -241,7 +386,7 @@ int poptGetNextOpt(poptContext con) {
}
if (opt->arg) {
switch (opt->argInfo) {
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_STRING:
*((char **) opt->arg) = con->os->nextArg;
break;
@ -254,7 +399,7 @@ int poptGetNextOpt(poptContext con) {
if (aLong == LONG_MIN || aLong == LONG_MAX)
return POPT_ERROR_OVERFLOW;
if (opt->argInfo == POPT_ARG_LONG) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
*((long *) opt->arg) = aLong;
} else {
if (aLong > INT_MAX || aLong < INT_MIN)
@ -264,13 +409,34 @@ int poptGetNextOpt(poptContext con) {
break;
default:
printf("option type not implemented in popt\n");
fprintf(stdout, POPT_("option type (%d) not implemented in popt\n"),
opt->argInfo & POPT_ARG_MASK);
exit(1);
}
}
}
if (opt->val) done = 1;
if (cb)
cb(con, POPT_CALLBACK_REASON_OPTION, opt, con->os->nextArg, cbData);
else if (opt->val)
done = 1;
if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) {
con->finalArgvAlloced += 10;
con->finalArgv = realloc(con->finalArgv,
sizeof(*con->finalArgv) * con->finalArgvAlloced);
}
i = con->finalArgvCount++;
con->finalArgv[i] =
malloc((opt->longName ? strlen(opt->longName) : 0) + 3);
if (opt->longName)
sprintf(con->finalArgv[i], "--%s", opt->longName);
else
sprintf(con->finalArgv[i], "-%c", opt->shortName);
if (opt->arg && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE)
con->finalArgv[con->finalArgvCount++] = strdup(con->os->nextArg);
}
return opt->val;
@ -305,13 +471,23 @@ void poptFreeContext(poptContext con) {
int i;
for (i = 0; i < con->numAliases; i++) {
free(con->aliases[i].longName);
if (con->aliases[i].longName) free(con->aliases[i].longName);
free(con->aliases[i].argv);
}
for (i = 0; i < con->numExecs; i++) {
if (con->execs[i].longName) free(con->execs[i].longName);
free(con->execs[i].script);
}
for (i = 0; i < con->finalArgvCount; i++)
free(con->finalArgv[i]);
free(con->leftovers);
free(con->finalArgv);
if (con->appName) free(con->appName);
if (con->aliases) free(con->aliases);
if (con->otherHelp) free(con->otherHelp);
free(con);
}
@ -337,282 +513,6 @@ int poptAddAlias(poptContext con, struct poptAlias newAlias, int flags) {
return 0;
}
int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr) {
char * buf = strcpy(malloc(strlen(s) + 1), s);
char * bufStart = buf;
char * src, * dst;
char quote = '\0';
int argvAlloced = 5;
char ** argv = malloc(sizeof(*argv) * argvAlloced);
char ** argv2;
int argc = 0;
int i;
src = s;
dst = buf;
argv[argc] = buf;
memset(buf, '\0', strlen(s) + 1);
while (*src) {
if (quote == *src) {
quote = '\0';
} else if (quote) {
if (*src == '\\') {
src++;
if (!*src) {
free(argv);
free(bufStart);
return POPT_ERROR_BADQUOTE;
}
if (*src != quote) *buf++ = '\\';
}
*buf++ = *src;
} else if (isspace(*src)) {
if (*argv[argc]) {
buf++, argc++;
if (argc == argvAlloced) {
argvAlloced += 5;
argv = realloc(argv, sizeof(*argv) * argvAlloced);
}
argv[argc] = buf;
}
} else switch (*src) {
case '"':
case '\'':
quote = *src;
break;
case '\\':
src++;
if (!*src) {
free(argv);
free(bufStart);
return POPT_ERROR_BADQUOTE;
}
/* fallthrough */
default:
*buf++ = *src;
}
src++;
}
if (strlen(argv[argc])) {
argc++;
buf++;
}
argv2 = malloc(argc * sizeof(*argv) + (buf - bufStart));
dst = (char *)argv2;
dst += argc * sizeof(*argv);
memcpy(argv2, argv, argc * sizeof(*argv));
memcpy(dst, bufStart, buf - bufStart);
for (i = 0; i < argc; i++) {
argv2[i] = dst + (argv[i] - bufStart);
}
free(argv);
free(bufStart);
*argvPtr = argv2;
*argcPtr = argc;
return 0;
}
static void configLine(poptContext con, char * line) {
int nameLength = strlen(con->appName);
char * opt;
struct poptAlias alias;
if (strncmp(line, con->appName, nameLength)) return;
line += nameLength;
if (!*line || !isspace(*line)) return;
while (*line && isspace(*line)) line++;
if (!strncmp(line, "alias", 5)) {
line += 5;
if (!*line || !isspace(*line)) return;
while (*line && isspace(*line)) line++;
if (!*line) return;
opt = line;
while (*line && !isspace(*line)) line++;
if (!*line) return;
*line++ = '\0';
while (*line && isspace(*line)) line++;
if (!*line) return;
if (!strlen(opt)) return;
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
if (opt[0] == '-' && opt[1] == '-') {
alias.longName = opt + 2;
alias.shortName = '\0';
poptAddAlias(con, alias, 0);
} else if (opt[0] == '-' && !opt[2]) {
alias.longName = NULL;
alias.shortName = opt[1];
poptAddAlias(con, alias, 0);
}
}
}
int poptReadConfigFile(poptContext con, char * fn) {
char * file, * chptr, * end;
char * buf, * dst;
int fd, rc;
int fileLength;
fd = open(fn, O_RDONLY);
if (fd < 0) {
if (errno == ENOENT)
return 0;
else
return POPT_ERROR_ERRNO;
}
fileLength = lseek(fd, 0, SEEK_END);
lseek(fd, 0, 0);
#ifndef HAVE_MMAP
file = (char*) xmalloc (fileLength, "poptReadConfigFile");
if (file == NULL)
#else /* HAVE_MMAP */
file = mmap(NULL, fileLength, PROT_READ, MAP_PRIVATE, fd, 0);
if (file == (void *) -1)
#endif /* HAVE_MMAP */
{
rc = errno;
close(fd);
errno = rc;
return POPT_ERROR_ERRNO;
}
#ifndef HAVE_MMAP
do
{
lseek(fd, 0, 0);
rc = read(fd, file, fileLength);
if (rc == -1 && errno != EINTR)
{
free(file);
return POPT_ERROR_ERRNO;
}
} while (rc != fileLength || (rc == -1 && errno == EINTR));
#endif /* HAVE_MMAP */
close(fd);
dst = buf = malloc(fileLength + 1);
chptr = file;
end = (file + fileLength);
while (chptr < end) {
switch (*chptr) {
case '\n':
*dst = '\0';
dst = buf;
while (*dst && isspace(*dst)) dst++;
if (*dst && *dst != '#') {
configLine(con, dst);
}
chptr++;
break;
case '\\':
*dst++ = *chptr++;
if (chptr < end) {
if (*chptr == '\n')
dst--, chptr++;
/* \ at the end of a line does not insert a \n */
else
*dst++ = *chptr++;
}
break;
default:
*dst++ = *chptr++;
}
}
free (buf);
#ifndef HAVE_MMAP
free (file);
#else
munmap (file, fileLength);
#endif
return 0;
}
int poptReadDefaultConfig(poptContext con, int useEnv) {
char * envName, * envValue, * envValueStart;
char * fn, * home, * chptr;
int rc, skip;
struct poptAlias alias;
if (!con->appName) return 0;
rc = poptReadConfigFile(con, "/etc/popt");
if (rc) return rc;
if ((home = getenv("HOME"))) {
fn = (char *) malloc (strlen(home) + 20);
sprintf(fn, "%s/.popt", home);
rc = poptReadConfigFile(con, fn);
free (fn);
if (rc) return rc;
}
envName = malloc(strlen(con->appName) + 20);
strcpy(envName, con->appName);
chptr = envName;
while (*chptr) {
*chptr = toupper(*chptr);
chptr++;
}
strcat(envName, "_POPT_ALIASES");
if (useEnv && (envValue = getenv(envName))) {
envValue = envValueStart = strcpy(malloc(strlen(envValue) + 1), envValue);
while (envValue && *envValue) {
chptr = strchr(envValue, '=');
if (!chptr) {
envValue = strchr(envValue, '\n');
if (envValue) envValue++;
continue;
}
*chptr = '\0';
skip = 0;
if (!strncmp(envValue, "--", 2)) {
alias.longName = envValue + 2;
alias.shortName = '\0';
} else if (*envValue == '-' && strlen(envValue) == 2) {
alias.longName = NULL;
alias.shortName = envValue[1];
} else {
skip = 1;
}
envValue = chptr + 1;
chptr = strchr(envValue, '\n');
if (chptr) *chptr = '\0';
if (!skip) {
poptParseArgvString(envValue, &alias.argc, &alias.argv);
poptAddAlias(con, alias, 0);
}
if (chptr)
envValue = chptr + 1;
else
envValue = NULL;
}
free(envValueStart);
}
free (envName);
return 0;
}
char * poptBadOption(poptContext con, int flags) {
struct optionStackEntry * os;
@ -633,32 +533,21 @@ char * poptBadOption(poptContext con, int flags) {
const char * poptStrerror(const int error) {
switch (error) {
case POPT_ERROR_NOARG:
return "missing argument";
return POPT_("missing argument");
case POPT_ERROR_BADOPT:
return "unknown option";
return POPT_("unknown option");
case POPT_ERROR_OPTSTOODEEP:
return "aliases nested too deeply";
return POPT_("aliases nested too deeply");
case POPT_ERROR_BADQUOTE:
return "error in paramter quoting";
return POPT_("error in paramter quoting");
case POPT_ERROR_BADNUMBER:
return "invalid numeric value";
return POPT_("invalid numeric value");
case POPT_ERROR_OVERFLOW:
return "number too large or too small";
return POPT_("number too large or too small");
case POPT_ERROR_ERRNO:
#ifdef HAVE_STRERROR
return strerror (errno);
#else
{
extern int sys_nerr;
extern char *sys_errlist [];
if ((0 <= errno) && (errno < sys_nerr))
return sys_errlist[errno];
else
return "strange errno";
}
#endif
return strerror(errno);
default:
return "unknown error";
return POPT_("unknown error");
}
}
@ -676,6 +565,11 @@ int poptStuffArgs(poptContext con, char ** argv) {
con->os->currAlias = NULL;
con->os->argc = i;
con->os->argv = argv;
con->os->stuffed = 1;
return 0;
}
const char * poptGetInvocationName(poptContext con) {
return con->os->argv[0];
}

View File

@ -1,12 +1,34 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
#ifndef H_POPT
#define H_POPT
#include <stdio.h> /* for FILE * */
#define POPT_OPTION_DEPTH 10
#define POPT_ARG_NONE 0
#define POPT_ARG_STRING 1
#define POPT_ARG_INT 2
#define POPT_ARG_LONG 3
#define POPT_ARG_INCLUDE_TABLE 4 /* arg points to table */
#define POPT_ARG_CALLBACK 5 /* table-wide callback... must be
set first in table; arg points
to callback, descrip points to
callback data to pass */
#define POPT_ARG_INTL_DOMAIN 6 /* set the translation domain
for this table and any
included tables; arg points
to the domain string */
#define POPT_ARG_MASK 0x0000FFFF
#define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */
#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
#define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line,
not the subtable */
#define POPT_ERROR_NOARG -10
#define POPT_ERROR_BADOPT -11
@ -16,9 +38,13 @@
#define POPT_ERROR_BADNUMBER -17
#define POPT_ERROR_OVERFLOW -18
/* context creation flags */
/* poptBadOption() flags */
#define POPT_BADOPTION_NOALIAS (1 << 0) /* don't go into an alias */
#define POPT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */
/* poptGetContext() flags */
#define POPT_CONTEXT_NO_EXEC (1 << 0) /* ignore exec expansions */
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /* options can't follow args */
struct poptOption {
const char * longName; /* may be NULL */
@ -26,6 +52,8 @@ struct poptOption {
int argInfo;
void * arg; /* depends on argInfo */
int val; /* 0 means don't return, just update flag */
char * descrip; /* description for autohelp -- may be NULL */
char * argDescrip; /* argument description for autohelp */
};
struct poptAlias {
@ -35,10 +63,25 @@ struct poptAlias {
char ** argv; /* must be free()able */
};
extern struct poptOption poptHelpOptions[];
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
0, "Help options", NULL },
typedef struct poptContext_s * poptContext;
#ifndef __cplusplus
typedef struct poptOption * poptOption;
#endif
enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
POPT_CALLBACK_REASON_POST,
POPT_CALLBACK_REASON_OPTION };
typedef void (*poptCallbackType)(poptContext con,
enum poptCallbackReason reason,
const struct poptOption * opt,
const char * arg, void * data);
poptContext poptGetContext(char * name, int argc, char ** argv,
struct poptOption * options, int flags);
const struct poptOption * options, int flags);
void poptResetContext(poptContext con);
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
@ -62,5 +105,10 @@ int poptReadDefaultConfig(poptContext con, int useEnv);
the same as " and both may include \ quotes */
int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr);
const char * poptStrerror(const int error);
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute);
void poptPrintHelp(poptContext con, FILE * f, int flags);
void poptPrintUsage(poptContext con, FILE * f, int flags);
void poptSetOtherOptionHelp(poptContext con, const char * text);
const char * poptGetInvocationName(poptContext con);
#endif

151
src/poptconfig.c Normal file
View File

@ -0,0 +1,151 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
#include "popt.h"
#include "poptint.h"
static void configLine(poptContext con, char * line) {
int nameLength = strlen(con->appName);
char * opt;
struct poptAlias alias;
char * entryType;
char * longName = NULL;
char shortName = '\0';
if (strncmp(line, con->appName, nameLength)) return;
line += nameLength;
if (!*line || !isspace(*line)) return;
while (*line && isspace(*line)) line++;
entryType = line;
while (!*line || !isspace(*line)) line++;
*line++ = '\0';
while (*line && isspace(*line)) line++;
if (!*line) return;
opt = line;
while (!*line || !isspace(*line)) line++;
*line++ = '\0';
while (*line && isspace(*line)) line++;
if (!*line) return;
if (opt[0] == '-' && opt[1] == '-')
longName = opt + 2;
else if (opt[0] == '-' && !opt[2])
shortName = opt[1];
if (!strcmp(entryType, "alias")) {
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
alias.longName = longName, alias.shortName = shortName;
poptAddAlias(con, alias, 0);
} else if (!strcmp(entryType, "exec")) {
con->execs = realloc(con->execs,
sizeof(*con->execs) * (con->numExecs + 1));
if (longName)
con->execs[con->numExecs].longName = strdup(longName);
else
con->execs[con->numExecs].longName = NULL;
con->execs[con->numExecs].shortName = shortName;
con->execs[con->numExecs].script = strdup(line);
con->numExecs++;
}
}
int poptReadConfigFile(poptContext con, char * fn) {
char * file, * chptr, * end;
char * buf, * dst;
int fd, rc;
int fileLength;
fd = open(fn, O_RDONLY);
if (fd < 0) {
if (errno == ENOENT)
return 0;
else
return POPT_ERROR_ERRNO;
}
fileLength = lseek(fd, 0, SEEK_END);
lseek(fd, 0, 0);
file = alloca(fileLength + 1);
if ((fd = read(fd, file, fileLength)) != fileLength) {
rc = errno;
close(fd);
errno = rc;
return POPT_ERROR_ERRNO;
}
close(fd);
dst = buf = alloca(fileLength + 1);
chptr = file;
end = (file + fileLength);
while (chptr < end) {
switch (*chptr) {
case '\n':
*dst = '\0';
dst = buf;
while (*dst && isspace(*dst)) dst++;
if (*dst && *dst != '#') {
configLine(con, dst);
}
chptr++;
break;
case '\\':
*dst++ = *chptr++;
if (chptr < end) {
if (*chptr == '\n')
dst--, chptr++;
/* \ at the end of a line does not insert a \n */
else
*dst++ = *chptr++;
}
break;
default:
*dst++ = *chptr++;
}
}
return 0;
}
int poptReadDefaultConfig(poptContext con, int useEnv) {
char * fn, * home;
int rc;
if (!con->appName) return 0;
rc = poptReadConfigFile(con, "/etc/popt");
if (rc) return rc;
if (getuid() != geteuid()) return 0;
if ((home = getenv("HOME"))) {
fn = alloca(strlen(home) + 20);
strcpy(fn, home);
strcat(fn, "/.popt");
rc = poptReadConfigFile(con, fn);
if (rc) return rc;
}
return 0;
}

302
src/popthelp.c Normal file
View File

@ -0,0 +1,302 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "popt.h"
#include "poptint.h"
static void displayArgs(poptContext con, enum poptCallbackReason foo,
struct poptOption * key,
const char * arg, void * data) {
if (key->shortName== '?')
poptPrintHelp(con, stdout, 0);
else
poptPrintUsage(con, stdout, 0);
exit(0);
}
struct poptOption poptHelpOptions[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, &displayArgs, '\0', NULL },
{ "help", '?', 0, NULL, '?', N_("Show this help message") },
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message") },
{ NULL, '\0', 0, NULL, 0 }
} ;
static const char *
getTableTranslationDomain(const struct poptOption *table)
{
const struct poptOption *opt;
for(opt = table;
opt->longName || opt->shortName || opt->arg;
opt++) {
if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
return opt->arg;
}
return NULL;
}
static const char * getArgDescrip(const struct poptOption * opt,
const char *translation_domain) {
if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
if (opt->argDescrip) return POPT_(opt->argDescrip);
if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
return POPT_("ARG");
}
static void singleOptionHelp(FILE * f, int maxLeftCol,
const struct poptOption * opt,
const char *translation_domain) {
int indentLength = maxLeftCol + 5;
int lineLength = 79 - indentLength;
const char * help = D_(translation_domain, opt->descrip);
int helpLength;
const char * ch;
char format[10];
char * left = alloca(maxLeftCol + 1);
const char * argDescrip = getArgDescrip(opt, translation_domain);
*left = '\0';
if (opt->longName && opt->shortName)
sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
else if (opt->shortName)
sprintf(left, "-%c", opt->shortName);
else if (opt->longName)
sprintf(left, "--%s", opt->longName);
if (!*left) return ;
if (argDescrip) {
strcat(left, "=");
strcat(left, argDescrip);
}
if (help)
fprintf(f," %-*s ", maxLeftCol, left);
else {
fprintf(f," %s\n", left);
return;
}
helpLength = strlen(help);
while (helpLength > lineLength) {
ch = help + lineLength - 1;
while (ch > help && !isspace(*ch)) ch--;
if (ch == help) break; /* give up */
while (ch > (help + 1) && isspace(*ch)) ch--;
ch++;
sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
fprintf(f, format, help, " ");
help = ch;
while (isspace(*help) && *help) help++;
helpLength = strlen(help);
}
if (helpLength) fprintf(f, "%s\n", help);
}
static int maxArgWidth(const struct poptOption * opt,
const char * translation_domain) {
int max = 0;
int this;
const char * s;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
this = maxArgWidth(opt->arg, translation_domain);
if (this > max) max = this;
} else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
this = opt->shortName ? 2 : 0;
if (opt->longName) {
if (this) this += 2;
this += strlen(opt->longName) + 2;
}
s = getArgDescrip(opt, translation_domain);
if (s)
this += strlen(s) + 1;
if (this > max) max = this;
}
opt++;
}
return max;
}
static void singleTableHelp(FILE * f, const struct poptOption * table,
int left,
const char *translation_domain) {
const struct poptOption * opt;
const char *sub_transdom;
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
singleOptionHelp(f, left, opt, translation_domain);
opt++;
}
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
sub_transdom = getTableTranslationDomain(opt->arg);
if(!sub_transdom)
sub_transdom = translation_domain;
if (opt->descrip)
fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
singleTableHelp(f, opt->arg, left, sub_transdom);
}
opt++;
}
}
static int showHelpIntro(poptContext con, FILE * f) {
int len = 6;
char * fn;
fprintf(f, POPT_("Usage:"));
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
fn = con->optionStack->argv[0];
if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
fprintf(f, " %s", fn);
len += strlen(fn) + 1;
}
return len;
}
void poptPrintHelp(poptContext con, FILE * f, int flags) {
int leftColWidth;
showHelpIntro(con, f);
if (con->otherHelp)
fprintf(f, " %s\n", con->otherHelp);
else
fprintf(f, " %s\n", POPT_("[OPTION...]"));
leftColWidth = maxArgWidth(con->options, NULL);
singleTableHelp(f, con->options, leftColWidth, NULL);
}
static int singleOptionUsage(FILE * f, int cursor,
const struct poptOption * opt,
const char *translation_domain) {
int len = 3;
char shortStr[2];
const char * item = shortStr;
const char * argDescrip = getArgDescrip(opt, translation_domain);
if (opt->shortName) {
if (!(opt->argInfo & POPT_ARG_MASK))
return cursor; /* we did these already */
len++;
*shortStr = opt->shortName;
shortStr[1] = '\0';
} else if (opt->longName) {
len += 1 + strlen(opt->longName);
item = opt->longName;
}
if (len == 3) return cursor;
if (argDescrip)
len += strlen(argDescrip) + 1;
if ((cursor + len) > 79) {
fprintf(f, "\n ");
cursor = 7;
}
fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
argDescrip ? (opt->shortName ? " " : "=") : "",
argDescrip ? argDescrip : "");
return cursor + len + 1;
}
int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
const char *translation_domain) {
const struct poptOption * opt;
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
translation_domain = (const char *)opt->arg;
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
cursor = singleTableUsage(f, cursor, opt->arg,
translation_domain);
else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
cursor = singleOptionUsage(f, cursor, opt, translation_domain);
opt++;
}
return cursor;
}
static int showShortOptions(const struct poptOption * opt, FILE * f,
char * str) {
char s[300]; /* this is larger then the ascii set, so
it should do just fine */
if (!str) {
str = s;
memset(str, 0, sizeof(str));
}
while (opt->longName || opt->shortName || opt->arg) {
if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
str[strlen(str)] = opt->shortName;
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
showShortOptions(opt->arg, f, str);
opt++;
}
if (s != str || !*s)
return 0;
fprintf(f, " [-%s]", s);
return strlen(s) + 4;
}
void poptPrintUsage(poptContext con, FILE * f, int flags) {
int cursor;
cursor = showHelpIntro(con, f);
cursor += showShortOptions(con->options, f, NULL);
singleTableUsage(f, cursor, con->options, NULL);
if (con->otherHelp) {
cursor += strlen(con->otherHelp) + 1;
if (cursor > 79) fprintf(f, "\n ");
fprintf(f, " %s", con->otherHelp);
}
fprintf(f, "\n");
}
void poptSetOtherOptionHelp(poptContext con, const char * text) {
if (con->otherHelp) free(con->otherHelp);
con->otherHelp = strdup(text);
}

93
src/poptparse.c Normal file
View File

@ -0,0 +1,93 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "popt.h"
int poptParseArgvString(char * s, int * argcPtr, char *** argvPtr) {
char * buf = strcpy(alloca(strlen(s) + 1), s);
char * bufStart = buf;
char * src, * dst;
char quote = '\0';
int argvAlloced = 5;
char ** argv = malloc(sizeof(*argv) * argvAlloced);
char ** argv2;
int argc = 0;
int i;
src = s;
dst = buf;
argv[argc] = buf;
memset(buf, '\0', strlen(s) + 1);
while (*src) {
if (quote == *src) {
quote = '\0';
} else if (quote) {
if (*src == '\\') {
src++;
if (!*src) {
free(argv);
return POPT_ERROR_BADQUOTE;
}
if (*src != quote) *buf++ = '\\';
}
*buf++ = *src;
} else if (isspace(*src)) {
if (*argv[argc]) {
buf++, argc++;
if (argc == argvAlloced) {
argvAlloced += 5;
argv = realloc(argv, sizeof(*argv) * argvAlloced);
}
argv[argc] = buf;
}
} else switch (*src) {
case '"':
case '\'':
quote = *src;
break;
case '\\':
src++;
if (!*src) {
free(argv);
return POPT_ERROR_BADQUOTE;
}
/* fallthrough */
default:
*buf++ = *src;
}
src++;
}
if (strlen(argv[argc])) {
argc++, buf++;
}
dst = malloc(argc * sizeof(*argv) + (buf - bufStart));
argv2 = (void *) dst;
dst += argc * sizeof(*argv);
memcpy(argv2, argv, argc * sizeof(*argv));
memcpy(dst, bufStart, buf - bufStart);
for (i = 0; i < argc; i++) {
argv2[i] = dst + (argv[i] - bufStart);
}
free(argv);
*argvPtr = argv2;
*argcPtr = argc;
return 0;
}