|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING 00002 file accompanying popt source distributions, available from 00003 ftp://ftp.redhat.com/pub/code/popt */ 00004 00005 #include "../StdAfx.h" 00006 //#include "system.h" 00007 //#include "popt.h" 00008 #include "poptint.h" 00009 00010 #ifdef _WIN32 00011 #define HAVE_STRERROR 00012 #endif 00013 #ifndef HAVE_STRERROR 00014 static char * strerror(int errno) { 00015 extern int sys_nerr; 00016 extern char * sys_errlist[]; 00017 00018 if ((0 <= errno) && (errno < sys_nerr)) 00019 return sys_errlist[errno]; 00020 else 00021 return POPT_("unknown errno"); 00022 } 00023 #endif 00024 00025 void poptSetExecPath(poptContext con, const char * path, int allowAbsolute) { 00026 if (con->execPath) xfree(con->execPath); 00027 con->execPath = xstrdup(path); 00028 con->execAbsolute = allowAbsolute; 00029 } 00030 00031 static void invokeCallbacks(poptContext con, const struct poptOption * table, 00032 int post) { 00033 const struct poptOption * opt = table; 00034 poptCallbackType cb; 00035 00036 while (opt->longName || opt->shortName || opt->arg) { 00037 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { 00038 invokeCallbacks(con,(struct poptOption*) opt->arg, post); 00039 } else if (((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) && 00040 ((!post && (opt->argInfo & POPT_CBFLAG_PRE)) || 00041 ( post && (opt->argInfo & POPT_CBFLAG_POST)))) { 00042 cb = (poptCallbackType)opt->arg; 00043 cb(con, post ? POPT_CALLBACK_REASON_POST : POPT_CALLBACK_REASON_PRE, 00044 NULL, NULL, opt->descrip); 00045 } 00046 opt++; 00047 } 00048 } 00049 00050 poptContext poptGetContext(const char * name, int argc, const char ** argv, 00051 const struct poptOption * options, int flags) { 00052 poptContext con = (poptContext)malloc(sizeof(*con)); 00053 00054 memset(con, 0, sizeof(*con)); 00055 00056 con->os = con->optionStack; 00057 con->os->argc = argc; 00058 con->os->argv = argv; 00059 con->os->argb = NULL; 00060 00061 if (!(flags & POPT_CONTEXT_KEEP_FIRST)) 00062 con->os->next = 1; /* skip argv[0] */ 00063 00064 con->leftovers = (const char**)calloc( (argc + 1), sizeof(char *) ); 00065 con->options = options; 00066 con->aliases = NULL; 00067 con->numAliases = 0; 00068 con->flags = flags; 00069 con->execs = NULL; 00070 con->numExecs = 0; 00071 con->finalArgvAlloced = argc * 2; 00072 con->finalArgv = (const char**)calloc( con->finalArgvAlloced, sizeof(*con->finalArgv) ); 00073 con->execAbsolute = 1; 00074 con->arg_strip = NULL; 00075 00076 if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) 00077 con->flags |= POPT_CONTEXT_POSIXMEHARDER; 00078 00079 if (name) 00080 con->appName = strcpy((char*)malloc(strlen(name) + 1), name); 00081 00082 invokeCallbacks(con, con->options, 0); 00083 00084 return con; 00085 } 00086 00087 static void cleanOSE(struct optionStackEntry *os) 00088 { 00089 if (os->nextArg) { 00090 xfree(os->nextArg); 00091 os->nextArg = NULL; 00092 } 00093 if (os->argv) { 00094 xfree(os->argv); 00095 os->argv = NULL; 00096 } 00097 if (os->argb) { 00098 PBM_FREE(os->argb); 00099 os->argb = NULL; 00100 } 00101 } 00102 00103 void poptResetContext(poptContext con) { 00104 int i; 00105 00106 while (con->os > con->optionStack) { 00107 cleanOSE(con->os--); 00108 } 00109 if (con->os->argb) { 00110 PBM_FREE(con->os->argb); 00111 con->os->argb = NULL; 00112 } 00113 con->os->currAlias = NULL; 00114 con->os->nextCharArg = NULL; 00115 con->os->nextArg = NULL; 00116 con->os->next = 1; /* skip argv[0] */ 00117 00118 con->numLeftovers = 0; 00119 con->nextLeftover = 0; 00120 con->restLeftover = 0; 00121 con->doExec = NULL; 00122 00123 for (i = 0; i < con->finalArgvCount; i++) { 00124 if (con->finalArgv[i]) { 00125 xfree(con->finalArgv[i]); 00126 con->finalArgv[i] = NULL; 00127 } 00128 } 00129 00130 con->finalArgvCount = 0; 00131 00132 if (con->arg_strip) { 00133 PBM_FREE(con->arg_strip); 00134 con->arg_strip = NULL; 00135 } 00136 } 00137 00138 /* Only one of longName, shortName may be set at a time */ 00139 static int handleExec(poptContext con, char * longName, char shortName) { 00140 int i; 00141 00142 i = con->numExecs - 1; 00143 if (longName) { 00144 while (i >= 0 && (!con->execs[i].longName || 00145 strcmp(con->execs[i].longName, longName))) i--; 00146 } else { 00147 while (i >= 0 && 00148 con->execs[i].shortName != shortName) i--; 00149 } 00150 00151 if (i < 0) return 0; 00152 00153 if (con->flags & POPT_CONTEXT_NO_EXEC) 00154 return 1; 00155 00156 if (con->doExec == NULL) { 00157 con->doExec = con->execs + i; 00158 return 1; 00159 } 00160 00161 /* We already have an exec to do; remember this option for next 00162 time 'round */ 00163 if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) { 00164 con->finalArgvAlloced += 10; 00165 con->finalArgv = (const char**)realloc((void*)con->finalArgv, 00166 sizeof(*con->finalArgv) * con->finalArgvAlloced); 00167 } 00168 00169 i = con->finalArgvCount++; 00170 { char *s =(char*) malloc((longName ? strlen(longName) : 0) + 3); 00171 if (longName) 00172 sprintf(s, "--%s", longName); 00173 else 00174 sprintf(s, "-%c", shortName); 00175 con->finalArgv[i] = s; 00176 } 00177 00178 return 1; 00179 } 00180 00181 /* Only one of longName, shortName may be set at a time */ 00182 static int handleAlias(poptContext con, const char * longName, char shortName, 00183 /*@keep@*/ const char * nextCharArg) { 00184 int i; 00185 00186 if (con->os->currAlias && con->os->currAlias->longName && longName && 00187 !strcmp(con->os->currAlias->longName, longName)) 00188 return 0; 00189 if (con->os->currAlias && shortName && 00190 shortName == con->os->currAlias->shortName) 00191 return 0; 00192 00193 i = con->numAliases - 1; 00194 if (longName) { 00195 while (i >= 0 && (!con->aliases[i].longName || 00196 strcmp(con->aliases[i].longName, longName))) i--; 00197 } else { 00198 while (i >= 0 && 00199 con->aliases[i].shortName != shortName) i--; 00200 } 00201 00202 if (i < 0) return 0; 00203 00204 if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) 00205 return POPT_ERROR_OPTSTOODEEP; 00206 00207 if (nextCharArg && *nextCharArg) 00208 con->os->nextCharArg = nextCharArg; 00209 00210 con->os++; 00211 con->os->next = 0; 00212 con->os->stuffed = 0; 00213 con->os->nextArg = NULL; 00214 con->os->nextCharArg = NULL; 00215 con->os->currAlias = con->aliases + i; 00216 poptDupArgv(con->os->currAlias->argc, con->os->currAlias->argv, 00217 &con->os->argc, &con->os->argv); 00218 con->os->argb = NULL; 00219 00220 return 1; 00221 } 00222 00223 /* 00224 static void execCommand(poptContext con) { 00225 const char ** argv; 00226 int pos = 0; 00227 const char * script = con->doExec->script; 00228 00229 argv = malloc(sizeof(*argv) * 00230 (6 + con->numLeftovers + con->finalArgvCount)); 00231 00232 if (!con->execAbsolute && strchr(script, '/')) return; 00233 00234 if (!strchr(script, '/') && con->execPath) { 00235 char *s = alloca(strlen(con->execPath) + strlen(script) + 2); 00236 sprintf(s, "%s/%s", con->execPath, script); 00237 argv[pos] = s; 00238 } else { 00239 argv[pos] = script; 00240 } 00241 pos++; 00242 00243 argv[pos] = findProgramPath(con->os->argv[0]); 00244 if (argv[pos]) pos++; 00245 argv[pos++] = ";"; 00246 00247 memcpy(argv + pos, con->finalArgv, sizeof(*argv) * con->finalArgvCount); 00248 pos += con->finalArgvCount; 00249 00250 if (con->numLeftovers) { 00251 argv[pos++] = "--"; 00252 memcpy(argv + pos, con->leftovers, sizeof(*argv) * con->numLeftovers); 00253 pos += con->numLeftovers; 00254 } 00255 00256 argv[pos++] = NULL; 00257 00258 #ifdef __hpux 00259 setresuid(getuid(), getuid(),-1); 00260 #else 00261 // 00262 // XXX " ... on BSD systems setuid() should be preferred over setreuid()" 00263 // XXX sez' Timur Bakeyev <mc@bat.ru> 00264 // XXX from Norbert Warmuth <nwarmuth@privat.circular.de> 00265 // 00266 #if defined(HAVE_SETUID) 00267 setuid(getuid()); 00268 #elif defined (HAVE_SETREUID) 00269 setreuid(getuid(), getuid()); //hlauer: not portable to hpux9.01 00270 #else 00271 ; // Can't drop privileges 00272 #endif 00273 #endif 00274 00275 execvp(argv[0], (char *const *)argv); 00276 } 00277 */ 00278 /*@observer@*/ static const struct poptOption * 00279 findOption(const struct poptOption * table, const char * longName, 00280 char shortName, 00281 /*@out@*/ poptCallbackType * callback, /*@out@*/ const void ** callbackData, 00282 int singleDash) 00283 { 00284 const struct poptOption * opt = table; 00285 const struct poptOption * opt2; 00286 const struct poptOption * cb = NULL; 00287 00288 /* This happens when a single - is given */ 00289 if (singleDash && !shortName && !*longName) 00290 shortName = '-'; 00291 00292 while (opt->longName || opt->shortName || opt->arg) { 00293 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { 00294 opt2 = findOption((struct poptOption*)opt->arg, longName, shortName, callback, 00295 callbackData, singleDash); 00296 if (opt2) { 00297 if (*callback && !*callbackData) 00298 *callbackData = opt->descrip; 00299 return opt2; 00300 } 00301 } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) { 00302 cb = opt; 00303 } else if (longName && opt->longName && 00304 (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) && 00305 !strcmp(longName, opt->longName)) { 00306 break; 00307 } else if (shortName && shortName == opt->shortName) { 00308 break; 00309 } 00310 opt++; 00311 } 00312 00313 if (!opt->longName && !opt->shortName) return NULL; 00314 *callbackData = NULL; 00315 *callback = NULL; 00316 if (cb) { 00317 *callback = (poptCallbackType)cb->arg; 00318 if (!(cb->argInfo & POPT_CBFLAG_INC_DATA)) 00319 *callbackData = cb->descrip; 00320 } 00321 00322 return opt; 00323 } 00324 00325 static const char *findNextArg(poptContext con, unsigned argx, int deletE) 00326 { 00327 struct optionStackEntry * os = con->os; 00328 const char * arg; 00329 00330 do { 00331 int i; 00332 arg = NULL; 00333 while (os->next == os->argc && os > con->optionStack) os--; 00334 if (os->next == os->argc && os == con->optionStack) break; 00335 for (i = os->next; i < os->argc; i++) { 00336 if (os->argb && PBM_ISSET(i, os->argb)) continue; 00337 if (*os->argv[i] == '-') continue; 00338 if (--argx > 0) continue; 00339 arg = os->argv[i]; 00340 if (deletE) { 00341 if (os->argb == NULL) os->argb = (pbm_set*)PBM_ALLOC(os->argc); 00342 PBM_SET(i, os->argb); 00343 } 00344 break; 00345 } 00346 if (os > con->optionStack) os--; 00347 } while (arg == NULL); 00348 return arg; 00349 } 00350 00351 static /*@only@*/ const char * expandNextArg(poptContext con, const char * s) 00352 { 00353 const char *a; 00354 size_t alen; 00355 char *t, *te; 00356 size_t tn = strlen(s) + 1; 00357 char c; 00358 00359 te = t = (char*)malloc(tn);; 00360 while ((c = *s++) != '\0') { 00361 switch (c) { 00362 #if 0 /* XXX can't do this */ 00363 case '\\': /* escape */ 00364 c = *s++; 00365 break; 00366 #endif 00367 case '!': 00368 if (!(s[0] == '#' && s[1] == ':' && s[2] == '+')) 00369 break; 00370 if ((a = findNextArg(con, 1, 1)) == NULL) 00371 break; 00372 s += 3; 00373 00374 alen = strlen(a); 00375 tn += alen; 00376 *te = '\0'; 00377 t = (char*)realloc(t, tn); 00378 te = t + strlen(t); 00379 strncpy(te, a, alen); te += alen; 00380 continue; 00381 /*@notreached@*/ break; 00382 default: 00383 break; 00384 } 00385 *te++ = c; 00386 } 00387 *te = '\0'; 00388 t = (char*)realloc(t, strlen(t)+1); /* XXX memory leak, hard to plug */ 00389 return t; 00390 } 00391 00392 static void poptStripArg(poptContext con, int which) 00393 { 00394 if(con->arg_strip == NULL) { 00395 con->arg_strip = (pbm_set*)PBM_ALLOC(con->optionStack[0].argc); 00396 } 00397 PBM_SET(which, con->arg_strip); 00398 } 00399 00400 /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ 00401 int poptGetNextOpt(poptContext con) 00402 { 00403 const struct poptOption * opt = NULL; 00404 int done = 0; 00405 00406 while (!done) { 00407 const char * origOptString = NULL; 00408 poptCallbackType cb = NULL; 00409 const void * cbData = NULL; 00410 const char * longArg = NULL; 00411 int canstrip = 0; 00412 00413 while (!con->os->nextCharArg && con->os->next == con->os->argc 00414 && con->os > con->optionStack) { 00415 cleanOSE(con->os--); 00416 } 00417 if (!con->os->nextCharArg && con->os->next == con->os->argc) { 00418 invokeCallbacks(con, con->options, 1); 00419 //if (con->doExec) execCommand(con); 00420 return -1; 00421 } 00422 00423 /* Process next long option */ 00424 if (!con->os->nextCharArg) { 00425 char * localOptString, * optString; 00426 int thisopt; 00427 00428 if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { 00429 con->os->next++; 00430 continue; 00431 } 00432 thisopt=con->os->next; 00433 origOptString = con->os->argv[con->os->next++]; 00434 00435 if (con->restLeftover || *origOptString != '-') { 00436 con->leftovers[con->numLeftovers++] = origOptString; 00437 if (con->flags & POPT_CONTEXT_POSIXMEHARDER) 00438 con->restLeftover = 1; 00439 continue; 00440 } 00441 00442 /* Make a copy we can hack at */ 00443 localOptString = optString = 00444 strcpy((char*)alloca(strlen(origOptString) + 1), 00445 origOptString); 00446 00447 if (!optString[0]) 00448 return POPT_ERROR_BADOPT; 00449 00450 if (optString[1] == '-' && !optString[2]) { 00451 con->restLeftover = 1; 00452 continue; 00453 } else { 00454 char *oe; 00455 int singleDash; 00456 00457 optString++; 00458 if (*optString == '-') 00459 singleDash = 0, optString++; 00460 else 00461 singleDash = 1; 00462 00463 /* XXX aliases with arg substitution need "--alias=arg" */ 00464 if (handleAlias(con, optString, '\0', NULL)) 00465 continue; 00466 if (handleExec(con, optString, '\0')) 00467 continue; 00468 00469 /* Check for "--long=arg" option. */ 00470 for (oe = optString; *oe && *oe != '='; oe++) 00471 ; 00472 if (*oe == '=') { 00473 *oe++ = '\0'; 00474 /* XXX longArg is mapped back to persistent storage. */ 00475 longArg = origOptString + (oe - localOptString); 00476 } 00477 00478 opt = findOption(con->options, optString, '\0', &cb, &cbData, 00479 singleDash); 00480 if (!opt && !singleDash) 00481 return POPT_ERROR_BADOPT; 00482 } 00483 00484 if (!opt) { 00485 con->os->nextCharArg = origOptString + 1; 00486 } else { 00487 if(con->os == con->optionStack && 00488 opt->argInfo & POPT_ARGFLAG_STRIP) { 00489 canstrip = 1; 00490 poptStripArg(con, thisopt); 00491 } 00492 } 00493 } 00494 00495 /* Process next short option */ 00496 if (con->os->nextCharArg) { 00497 origOptString = con->os->nextCharArg; 00498 00499 con->os->nextCharArg = NULL; 00500 00501 if (handleAlias(con, NULL, *origOptString, 00502 origOptString + 1)) { 00503 origOptString++; 00504 continue; 00505 } 00506 if (handleExec(con, NULL, *origOptString)) 00507 continue; 00508 00509 opt = findOption(con->options, NULL, *origOptString, &cb, 00510 &cbData, 0); 00511 if (!opt) 00512 return POPT_ERROR_BADOPT; 00513 00514 origOptString++; 00515 if (*origOptString) 00516 con->os->nextCharArg = origOptString; 00517 } 00518 00519 if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) { 00520 *((int *)opt->arg) = 1; 00521 } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { 00522 if (opt->arg) 00523 *((int *) opt->arg) = opt->val; 00524 } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { 00525 if (con->os->nextArg) { 00526 xfree(con->os->nextArg); 00527 con->os->nextArg = NULL; 00528 } 00529 if (longArg) { 00530 con->os->nextArg = expandNextArg(con, longArg); 00531 } else if (con->os->nextCharArg) { 00532 con->os->nextArg = expandNextArg(con, con->os->nextCharArg); 00533 con->os->nextCharArg = NULL; 00534 } else { 00535 while (con->os->next == con->os->argc && 00536 con->os > con->optionStack) { 00537 cleanOSE(con->os--); 00538 } 00539 if (con->os->next == con->os->argc) 00540 return POPT_ERROR_NOARG; 00541 00542 /* make sure this isn't part of a short arg or the 00543 result of an alias expansion */ 00544 if(con->os == con->optionStack && 00545 opt->argInfo & POPT_ARGFLAG_STRIP && 00546 canstrip) { 00547 poptStripArg(con, con->os->next); 00548 } 00549 00550 con->os->nextArg = expandNextArg(con, con->os->argv[con->os->next++]); 00551 } 00552 00553 if (opt->arg) { 00554 long aLong; 00555 char *end; 00556 00557 switch (opt->argInfo & POPT_ARG_MASK) { 00558 case POPT_ARG_STRING: 00559 /* XXX memory leak, hard to plug */ 00560 *((const char **) opt->arg) = xstrdup(con->os->nextArg); 00561 break; 00562 00563 case POPT_ARG_INT: 00564 case POPT_ARG_LONG: 00565 aLong = strtol(con->os->nextArg, &end, 0); 00566 if (!(end && *end == '\0')) 00567 return POPT_ERROR_BADNUMBER; 00568 00569 if (aLong == LONG_MIN || aLong == LONG_MAX) 00570 return POPT_ERROR_OVERFLOW; 00571 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { 00572 *((long *) opt->arg) = aLong; 00573 } else { 00574 if (aLong > INT_MAX || aLong < INT_MIN) 00575 return POPT_ERROR_OVERFLOW; 00576 *((int *) opt->arg) = aLong; 00577 } 00578 break; 00579 00580 default: 00581 fprintf(stdout, POPT_("option type (%d) not implemented in popt\n"), 00582 opt->argInfo & POPT_ARG_MASK); 00583 exit(EXIT_FAILURE); 00584 } 00585 } 00586 } 00587 00588 if (cb) 00589 cb(con, POPT_CALLBACK_REASON_OPTION, opt, con->os->nextArg, cbData); 00590 else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)) 00591 done = 1; 00592 00593 if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { 00594 con->finalArgvAlloced += 10; 00595 con->finalArgv = (const char**)realloc((void*)con->finalArgv, 00596 sizeof(*con->finalArgv) * con->finalArgvAlloced); 00597 } 00598 00599 { char *s = (char*)malloc((opt->longName ? strlen(opt->longName) : 0) + 3); 00600 if (opt->longName) 00601 sprintf(s, "--%s", opt->longName); 00602 else 00603 sprintf(s, "-%c", opt->shortName); 00604 con->finalArgv[con->finalArgvCount++] = s; 00605 } 00606 00607 if (opt->arg && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE 00608 && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL) { 00609 con->finalArgv[con->finalArgvCount++] = xstrdup(con->os->nextArg); 00610 } 00611 } 00612 00613 return opt->val; 00614 } 00615 00616 const char * poptGetOptArg(poptContext con) { 00617 const char * ret = con->os->nextArg; 00618 con->os->nextArg = NULL; 00619 return ret; 00620 } 00621 00622 const char * poptGetArg(poptContext con) { 00623 if (con->numLeftovers == con->nextLeftover) return NULL; 00624 return con->leftovers[con->nextLeftover++]; 00625 } 00626 00627 const char * poptPeekArg(poptContext con) { 00628 if (con->numLeftovers == con->nextLeftover) return NULL; 00629 return con->leftovers[con->nextLeftover]; 00630 } 00631 00632 const char ** poptGetArgs(poptContext con) { 00633 if (con->numLeftovers == con->nextLeftover) return NULL; 00634 00635 /* some apps like [like RPM ;-) ] need this NULL terminated */ 00636 con->leftovers[con->numLeftovers] = NULL; 00637 00638 return (con->leftovers + con->nextLeftover); 00639 } 00640 00641 void poptFreeContext(poptContext con) { 00642 int i; 00643 00644 poptResetContext(con); 00645 if (con->os->argb) free(con->os->argb); 00646 00647 for (i = 0; i < con->numAliases; i++) { 00648 if (con->aliases[i].longName) xfree(con->aliases[i].longName); 00649 free((void*)con->aliases[i].argv); 00650 } 00651 00652 for (i = 0; i < con->numExecs; i++) { 00653 if (con->execs[i].longName) xfree(con->execs[i].longName); 00654 xfree(con->execs[i].script); 00655 } 00656 if (con->execs) xfree(con->execs); 00657 00658 free((void*)con->leftovers); 00659 free((void*)con->finalArgv); 00660 if (con->appName) xfree(con->appName); 00661 if (con->aliases) free(con->aliases); 00662 if (con->otherHelp) xfree(con->otherHelp); 00663 if (con->execPath) xfree(con->execPath); 00664 if (con->arg_strip) PBM_FREE(con->arg_strip); 00665 00666 free(con); 00667 } 00668 00669 int poptAddAlias(poptContext con, struct poptAlias newAlias, 00670 /*@unused@*/ int flags) 00671 { 00672 int aliasNum = con->numAliases++; 00673 struct poptAlias * alias; 00674 00675 /* SunOS won't realloc(NULL, ...) */ 00676 if (!con->aliases) 00677 con->aliases = (struct poptAlias*)malloc(sizeof(newAlias) * con->numAliases); 00678 else 00679 con->aliases = (struct poptAlias*)realloc(con->aliases, 00680 sizeof(newAlias) * con->numAliases); 00681 alias = con->aliases + aliasNum; 00682 00683 alias->longName = (newAlias.longName) 00684 ? strcpy((char*)malloc(strlen(newAlias.longName) + 1), newAlias.longName) 00685 : NULL; 00686 alias->shortName = newAlias.shortName; 00687 alias->argc = newAlias.argc; 00688 alias->argv = newAlias.argv; 00689 00690 return 0; 00691 } 00692 00693 const char * poptBadOption(poptContext con, int flags) { 00694 struct optionStackEntry * os; 00695 00696 if (flags & POPT_BADOPTION_NOALIAS) 00697 os = con->optionStack; 00698 else 00699 os = con->os; 00700 00701 return os->argv[os->next - 1]; 00702 } 00703 00704 #define POPT_ERROR_NOARG -10 00705 #define POPT_ERROR_BADOPT -11 00706 #define POPT_ERROR_OPTSTOODEEP -13 00707 #define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */ 00708 #define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */ 00709 00710 const char * /*const*/ poptStrerror(const int error) { 00711 switch (error) { 00712 case POPT_ERROR_NOARG: 00713 return POPT_("missing argument"); 00714 case POPT_ERROR_BADOPT: 00715 return POPT_("unknown option"); 00716 case POPT_ERROR_OPTSTOODEEP: 00717 return POPT_("aliases nested too deeply"); 00718 case POPT_ERROR_BADQUOTE: 00719 return POPT_("error in paramter quoting"); 00720 case POPT_ERROR_BADNUMBER: 00721 return POPT_("invalid numeric value"); 00722 case POPT_ERROR_OVERFLOW: 00723 return POPT_("number too large or too small"); 00724 case POPT_ERROR_ERRNO: 00725 return strerror(errno); 00726 default: 00727 return POPT_("unknown error"); 00728 } 00729 } 00730 00731 int poptStuffArgs(poptContext con, const char ** argv) { 00732 int argc; 00733 00734 if ((con->os - con->optionStack) == POPT_OPTION_DEPTH) 00735 return POPT_ERROR_OPTSTOODEEP; 00736 00737 for (argc = 0; argv[argc]; argc++) 00738 ; 00739 00740 con->os++; 00741 con->os->next = 0; 00742 con->os->nextArg = NULL; 00743 con->os->nextCharArg = NULL; 00744 con->os->currAlias = NULL; 00745 poptDupArgv(argc, argv, &con->os->argc, &con->os->argv); 00746 con->os->argb = NULL; 00747 con->os->stuffed = 1; 00748 00749 return 0; 00750 } 00751 00752 const char * poptGetInvocationName(poptContext con) { 00753 return con->os->argv[0]; 00754 } 00755 00756 int poptStrippedArgv(poptContext con, int argc, char **argv) 00757 { 00758 int i,j=1, numargs=argc; 00759 00760 for(i=1; i<argc; i++) { 00761 if(PBM_ISSET(i, con->arg_strip)) { 00762 numargs--; 00763 } 00764 } 00765 00766 for(i=1; i<argc; i++) { 00767 if(PBM_ISSET(i, con->arg_strip)) { 00768 continue; 00769 } else { 00770 if(j<numargs) { 00771 argv[j++]=argv[i]; 00772 } else { 00773 argv[j++]='\0'; 00774 } 00775 } 00776 } 00777 00778 return(numargs); 00779 }
1.7.6.1