rpm 5.3.12
lib/poptALL.c
Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 extern const char *__progname;
00008 
00009 #if defined(RPM_VENDOR_WINDRIVER)
00010 const char *__usrlibrpm = USRLIBRPM;
00011 const char *__etcrpm = SYSCONFIGDIR;
00012 #endif
00013 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
00014 const char *__localedir = LOCALEDIR;
00015 #endif
00016 
00017 #define _RPMIOB_INTERNAL
00018 #include <rpmio.h>
00019 #include <rpmiotypes.h>
00020 #include <fts.h>
00021 #include <mire.h>
00022 #include <poptIO.h>
00023 
00024 #include <rpmjs.h>
00025 #include <rpmruby.h>
00026 
00027 #include <rpmtag.h>
00028 #include <rpmtypes.h>
00029 #include <rpmrc.h>
00030 #include <rpmversion.h>
00031 #include <rpmcli.h>
00032 
00033 #include <rpmns.h>              /* XXX rpmnsClean() */
00034 
00035 #include <fs.h>                 /* XXX rpmFreeFilesystems() */
00036 
00037 #include "debug.h"
00038 
00039 /*@unchecked@*/ /*@only@*/ /*@null@*/
00040 extern unsigned int * keyids;
00041 
00042 #define POPT_SHOWVERSION        -999
00043 #define POPT_SHOWRC             -998
00044 #define POPT_QUERYTAGS          -997
00045 #define POPT_PREDEFINE          -996
00046 #define POPT_UNDEFINE           -994
00047 
00048 /*@access headerTagIndices @*/          /* XXX rpmcliFini */
00049 /*@access headerTagTableEntry @*/       /* XXX rpmcliFini */
00050 
00051 /*@unchecked@*/
00052 static int _debug = 0;
00053 
00054 /*@-exportheadervar@*/
00055 /*@unchecked@*/
00056 extern int _rpmds_nopromote;
00057 
00058 /*@unchecked@*/
00059 extern int _fps_debug;
00060 
00061 /*@unchecked@*/
00062 extern int _fsm_debug;
00063 
00064 /*@unchecked@*/
00065 extern int _fsm_threads;
00066 
00067 /*@unchecked@*/
00068 extern int _hdr_debug;
00069 /*@unchecked@*/
00070 extern int _hdrqf_debug;
00071 
00072 /*@unchecked@*/
00073 extern int _pkgio_debug;
00074 
00075 /*@unchecked@*/
00076 extern int _rpmrepo_debug;
00077 
00078 /*@unchecked@*/
00079 extern int _print_pkts;
00080 
00081 /*@unchecked@*/
00082 extern int _psm_debug;
00083 /*@unchecked@*/
00084 extern rpmioPool _psmPool;
00085 
00086 /*@unchecked@*/
00087 extern int _psm_threads;
00088 
00089 /*@unchecked@*/
00090 extern int _rpmal_debug;
00091 
00092 /*@unchecked@*/
00093 extern int _rpmdb_debug;
00094 
00095 /*@unchecked@*/
00096 extern int _rpmds_debug;
00097 /*@unchecked@*/
00098 extern rpmioPool _rpmdsPool;
00099 
00100 /*@unchecked@*/
00101        int _rpmfc_debug;
00102 /*@unchecked@*/
00103 extern rpmioPool _rpmfcPool;
00104 
00105 /*@unchecked@*/
00106 extern int _rpmfi_debug;
00107 /*@unchecked@*/
00108 extern rpmioPool _rpmfiPool;
00109 
00110 /*@unchecked@*/
00111 extern int _rpmgi_debug;
00112 /*@unchecked@*/
00113 extern rpmioPool _rpmgiPool;
00114 
00115 /*@unchecked@*/
00116 extern int _rpmmi_debug;
00117 
00118 /*@unchecked@*/
00119 extern int _rpmps_debug;
00120 /*@unchecked@*/
00121 extern rpmioPool _rpmpsPool;
00122 
00123 /*@unchecked@*/
00124 extern int _rpmsq_debug;
00125 
00126 /*@unchecked@*/
00127 extern int _rpmte_debug;
00128 /*@unchecked@*/
00129 extern rpmioPool _rpmtePool;
00130 /*@unchecked@*/
00131 extern rpmioPool _rpmtsiPool;
00132 
00133 /*@unchecked@*/
00134 extern int _rpmts_debug;
00135 /*@unchecked@*/
00136 extern rpmioPool _rpmtsPool;
00137 
00138 /*@unchecked@*/
00139 extern int _rpmwf_debug;
00140 
00141 /*@unchecked@*/
00142 extern int _rpmts_macros;
00143 
00144 /*@unchecked@*/
00145 extern int _rpmts_stats;
00146 
00147 /*@unchecked@*/
00148 extern int _hdr_stats;
00149 
00150 /*@unchecked@*/
00151 rpmQueryFlags rpmcliQueryFlags;
00152 
00153 /*@unchecked@*/ /*@null@*/
00154 const char * rpmcliTargets = NULL;
00155 
00156 /*@unchecked@*/
00157 static int rpmcliInitialized = -1;
00158 
00159 #ifdef WITH_LUA
00160 /*@unchecked@*/
00161 extern const char *rpmluaFiles;
00162 #endif
00163 
00164 /*@-readonlytrans@*/    /* argv loading prevents observer, xstrdup needed. */
00165 /*@unchecked@*/
00166 static char *rpmpoptfiles = RPMPOPTFILES;
00167 /*@=readonlytrans@*/
00168 
00172 static void printVersion(FILE * fp)
00173         /*@globals rpmEVR, fileSystem, internalState @*/
00174         /*@modifies *fp, fileSystem, internalState @*/
00175 {
00176     fprintf(fp, _("%s (" RPM_NAME ") %s\n"), __progname, rpmEVR);
00177     if (rpmIsVerbose())
00178         fprintf(fp, "rpmlib 0x%08x,0x%08x,0x%08x\n", (unsigned)rpmlibVersion(),
00179                 (unsigned)rpmlibTimestamp(), (unsigned)rpmlibVendor());
00180 }
00181 
00182 void rpmcliConfigured(void)
00183         /*@globals rpmcliInitialized, rpmCLIMacroContext, rpmGlobalMacroContext,
00184                 h_errno, fileSystem, internalState @*/
00185         /*@modifies rpmcliInitialized, rpmCLIMacroContext, rpmGlobalMacroContext,
00186                 fileSystem, internalState @*/
00187 {
00188 
00189     if (rpmcliInitialized < 0) {
00190         char * t = NULL;
00191         if (rpmcliTargets != NULL) {
00192             char *te;
00193             t = xstrdup(rpmcliTargets);
00194             if ((te = strchr(t, ',')) != NULL)
00195                 *te = '\0';
00196         }
00197         rpmcliInitialized = rpmReadConfigFiles(NULL, t);
00198         t = _free(t);
00199     }
00200     if (rpmcliInitialized)
00201         exit(EXIT_FAILURE);
00202 }
00203 
00204 /* ========== all-rpm-modes popt args */
00205 
00206 static const char * rpmcliEvalSlurp(const char * arg)
00207         /*@globals rpmGlobalMacroContext @*/
00208         /*@modifies rpmGlobalMacroContext @*/
00209 {
00210     const char * pre = "";
00211     const char * post = "";
00212     rpmiob iob = NULL;
00213     const char * val = NULL;
00214     struct stat sb;
00215     int xx;
00216 
00217     if (!strcmp(arg, "-")) {    /* Macros from stdin arg. */
00218         xx = rpmiobSlurp(arg, &iob);
00219     } else
00220     if ((arg[0] == '/' || strchr(arg, ' ') == NULL)
00221      && !Stat(arg, &sb)
00222      && S_ISREG(sb.st_mode)) {  /* Macros from a file arg. */
00223         xx = rpmiobSlurp(arg, &iob);
00224     } else {                    /* Macros from string arg. */
00225         iob = rpmiobAppend(rpmiobNew(strlen(arg)+1), arg, 0);
00226     }
00227 
00228     val = rpmExpand(pre, iob->b, post, NULL);
00229     iob = rpmiobFree(iob);
00230     return val;
00231 }
00232 
00235 static void rpmcliAllArgCallback(poptContext con,
00236                 /*@unused@*/ enum poptCallbackReason reason,
00237                 const struct poptOption * opt, const char * arg,
00238                 /*@unused@*/ const void * data)
00239         /*@globals pgpDigVSFlags, rpmcliTargets, rpmcliQueryFlags, rpmCLIMacroContext,
00240                 rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
00241         /*@modifies con, pgpDigVSFlags, rpmcliTargets, rpmcliQueryFlags, rpmCLIMacroContext,
00242                 rpmGlobalMacroContext, fileSystem, internalState @*/
00243 {
00244 
00245     /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
00246     if (opt->arg == NULL)
00247     switch (opt->val) {
00248     case POPT_PREDEFINE:
00249         (void) rpmDefineMacro(NULL, arg, RMIL_CMDLINE);
00250         break;
00251     case 'D':
00252     {   char *s, *t;
00253         /* XXX Convert '-' in macro name to underscore, skip leading %. */
00254         s = t = xstrdup(arg);
00255         while (*t && !xisspace(*t)) {
00256             if (*t == '-') *t = '_';
00257             t++;
00258         }
00259         t = s;
00260         if (*t == '%') t++;
00261         rpmcliConfigured();
00262 /*@-type@*/
00263         /* XXX adding macro to global context isn't Right Thing Todo. */
00264         (void) rpmDefineMacro(NULL, t, RMIL_CMDLINE);
00265         (void) rpmDefineMacro(rpmCLIMacroContext, t, RMIL_CMDLINE);
00266 /*@=type@*/
00267         s = _free(s);
00268     }   break;
00269     case POPT_UNDEFINE:
00270     {   char *s, *t;
00271         /* XXX Convert '-' in macro name to underscore, skip leading %. */
00272         s = t = xstrdup(arg);
00273         while (*t && !xisspace(*t)) {
00274             if (*t == '-') *t = '_';
00275             t++;
00276         }
00277         t = s;
00278         if (*t == '%') t++;
00279 /*@-type@*/
00280         rpmcliConfigured();
00281         (void) rpmUndefineMacro(NULL, t);
00282         (void) rpmUndefineMacro(rpmCLIMacroContext, t);
00283 /*@=type@*/
00284         s = _free(s);
00285     }   break;
00286     case 'E':
00287 assert(arg != NULL);
00288         rpmcliConfigured();
00289     {   const char * val = rpmcliEvalSlurp(arg);
00290         size_t val_len = fwrite(val, strlen(val), 1, stdout);
00291         if (val_len > 0 && val[val_len - 1] != '\n')
00292             fprintf(stdout, "\n");
00293         val = _free(val);
00294     }   break;
00295     case POPT_SHOWVERSION:
00296         printVersion(stdout);
00297 /*@i@*/ con = rpmcliFini(con);
00298         exit(EXIT_SUCCESS);
00299         /*@notreached@*/ break;
00300     case POPT_SHOWRC:
00301         rpmcliConfigured();
00302         (void) rpmShowRC(stdout);
00303 /*@i@*/ con = rpmcliFini(con);
00304         exit(EXIT_SUCCESS);
00305         /*@notreached@*/ break;
00306     case POPT_QUERYTAGS:
00307         rpmDisplayQueryTags(NULL, NULL, NULL);
00308 /*@i@*/ con = rpmcliFini(con);
00309         exit(EXIT_SUCCESS);
00310         /*@notreached@*/ break;
00311     case RPMCLI_POPT_NODIGEST:
00312         rpmcliQueryFlags |= VERIFY_DIGEST;
00313         pgpDigVSFlags |= _RPMVSF_NODIGESTS;
00314         break;
00315 
00316     case RPMCLI_POPT_NOSIGNATURE:
00317         rpmcliQueryFlags |= VERIFY_SIGNATURE;
00318         pgpDigVSFlags |= _RPMVSF_NOSIGNATURES;
00319         break;
00320 
00321     case RPMCLI_POPT_NOHDRCHK:
00322         rpmcliQueryFlags |= VERIFY_HDRCHK;
00323         pgpDigVSFlags |= RPMVSF_NOHDRCHK;
00324         break;
00325 
00326     case RPMCLI_POPT_TARGETPLATFORM:
00327         if (rpmcliTargets == NULL)
00328             rpmcliTargets = xstrdup(arg);
00329         else {
00330 /*@-modobserver @*/
00331             char * t = (char *) rpmcliTargets;
00332             size_t nb = strlen(t) + (sizeof(",")-1) + strlen(arg) + 1;
00333 /*@i@*/     t = xrealloc(t, nb);
00334             (void) stpcpy( stpcpy(t, ","), arg);
00335             rpmcliTargets = t;
00336 /*@=modobserver @*/
00337         }
00338         break;
00339     }
00340 }
00341 
00342 /*@unchecked@*/
00343 int global_depFlags = RPMDEPS_FLAG_ADDINDEPS;
00344 
00345 /*@unchecked@*/
00346 struct poptOption rpmcliDepFlagsPoptTable[] = {
00347  { "noaid", '\0', POPT_BIT_CLR|POPT_ARGFLAG_TOGGLE, &global_depFlags, RPMDEPS_FLAG_ADDINDEPS,
00348         N_("Add packages to resolve dependencies"), NULL },
00349  { "anaconda", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00350         &global_depFlags, RPMDEPS_FLAG_ANACONDA|RPMDEPS_FLAG_DEPLOOPS,
00351         N_("Use anaconda \"presentation order\""), NULL},
00352  { "deploops", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00353         &global_depFlags, RPMDEPS_FLAG_DEPLOOPS,
00354         N_("Print dependency loops as warning"), NULL},
00355  { "nosuggest", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE,
00356         &global_depFlags, RPMDEPS_FLAG_NOSUGGEST,
00357         N_("Do not suggest missing dependency resolution(s)"), NULL},
00358  { "noconflicts", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00359         &global_depFlags, RPMDEPS_FLAG_NOCONFLICTS,
00360         N_("Do not check added package conflicts"), NULL},
00361  { "nolinktos", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00362         &global_depFlags, RPMDEPS_FLAG_NOLINKTOS,
00363         N_("Ignore added package requires on symlink targets"), NULL},
00364  { "noobsoletes", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00365         &global_depFlags, RPMDEPS_FLAG_NOOBSOLETES,
00366         N_("Ignore added package obsoletes"), NULL},
00367  { "noparentdirs", '\0', POPT_BIT_SET|POPT_ARGFLAG_TOGGLE|POPT_ARGFLAG_DOC_HIDDEN,
00368         &global_depFlags, RPMDEPS_FLAG_NOPARENTDIRS,
00369         N_("Ignore added package requires on file parent directory"), NULL},
00370  { "norequires", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00371         &global_depFlags, RPMDEPS_FLAG_NOREQUIRES,
00372         N_("Do not check added package requires"), NULL},
00373  { "noupgrade", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
00374         &global_depFlags, RPMDEPS_FLAG_NOUPGRADE,
00375         N_("Ignore added package upgrades"), NULL},
00376    POPT_TABLEEND
00377 };
00378 
00379 /*@-bitwisesigned -compmempass @*/
00380 /*@unchecked@*/
00381 struct poptOption rpmcliAllPoptTable[] = {
00382 /*@-type@*/ /* FIX: cast? */
00383  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
00384         rpmcliAllArgCallback, 0, NULL, NULL },
00385 /*@=type@*/
00386 
00387  { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_debug, -1,
00388         N_("Debug generic operations"), NULL},
00389 
00390  { "predefine", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_PREDEFINE,
00391         N_("Predefine MACRO with value EXPR"),
00392         N_("'MACRO EXPR'") },
00393 
00394  { "define", 'D', POPT_ARG_STRING, NULL, 'D',
00395         N_("Define MACRO with value EXPR"),
00396         N_("'MACRO EXPR'") },
00397  { "undefine", '\0', POPT_ARG_STRING, NULL, POPT_UNDEFINE,
00398         N_("Undefine MACRO"),
00399         N_("'MACRO'") },
00400  { "eval", 'E', POPT_ARG_STRING, NULL, 'E',
00401         N_("Print macro expansion of EXPR"),
00402         N_("'EXPR'") },
00403  { "macros", '\0', POPT_ARG_STRING, &rpmMacrofiles, 0,
00404         N_("Read <FILE:...> instead of default file(s)"),
00405         N_("<FILE:...>") },
00406 #ifdef WITH_LUA
00407  { "rpmlua", '\0', POPT_ARG_STRING, &rpmluaFiles, 0,
00408         N_("Read <FILE:...> instead of default RPM Lua file(s)"),
00409         N_("<FILE:...>") },
00410 #endif
00411  { "rpmpopt", '\0', POPT_ARG_STRING, NULL, 0,
00412         N_("Read <FILE:...> instead of default POPT file(s)"),
00413         N_("<FILE:...>") },
00414 
00415  { "target", '\0', POPT_ARG_STRING, NULL,  RPMCLI_POPT_TARGETPLATFORM,
00416         N_("Specify target platform"), N_("CPU-VENDOR-OS") },
00417 
00418  { "nodigest", '\0', 0, NULL, RPMCLI_POPT_NODIGEST,
00419         N_("Don't verify package digest(s)"), NULL },
00420  { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOHDRCHK,
00421         N_("Don't verify database header(s) when retrieved"), NULL },
00422  { "nosignature", '\0', 0, NULL, RPMCLI_POPT_NOSIGNATURE,
00423         N_("Don't verify package signature(s)"), NULL },
00424 
00425  { "querytags", '\0', 0, NULL, POPT_QUERYTAGS,
00426         N_("Display known query tags"), NULL },
00427  { "showrc", '\0', 0, NULL, POPT_SHOWRC,
00428         N_("Display macro and configuration values"), NULL },
00429  { "version", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, POPT_SHOWVERSION,
00430         N_("Print the version"), NULL },
00431 
00432  { "promoteepoch", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_nopromote, 0,
00433         NULL, NULL},
00434 
00435  { "fpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fps_debug, -1,
00436         N_("Debug file FingerPrintS"), NULL},
00437  { "fsmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_debug, -1,
00438         N_("Debug payload File State Machine"), NULL},
00439  { "fsmthreads", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_threads, -1,
00440         N_("Use threads for File State Machine"), NULL},
00441  { "hdrdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_hdr_debug, -1,
00442         NULL, NULL},
00443  { "hdrqfdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_hdrqf_debug, -1,
00444         NULL, NULL},
00445  { "macrosused", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_macros, -1,
00446         N_("Display macros used"), NULL},
00447  { "pkgiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_pkgio_debug, -1,
00448         NULL, NULL},
00449  { "prtpkts", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_print_pkts, -1,
00450         N_("Display OpenPGP (RFC 2440/4880) parsing"), NULL},
00451  { "psmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_psm_debug, -1,
00452         N_("Debug Package State Machine"), NULL},
00453  { "psmthreads", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_psm_threads, -1,
00454         N_("Use threads for Package State Machine"), NULL},
00455  { "rpmdsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_debug, -1,
00456         N_("Debug rpmds Dependency Set"), NULL},
00457  { "rpmfcdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfc_debug, -1,
00458         N_("Debug rpmfc File Classifier"), NULL},
00459  { "rpmfidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfi_debug, -1,
00460         N_("Debug rpmfi File Info"), NULL},
00461  { "rpmgidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmgi_debug, -1,
00462         N_("Debug rpmgi Generalized Iterator"), NULL},
00463  { "rpmmidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmmi_debug, -1,
00464         N_("Debug rpmmi Match Iterator"), NULL},
00465  { "rpmnsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmns_debug, -1,
00466         N_("Debug rpmns Name Space"), NULL},
00467  { "rpmpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmps_debug, -1,
00468         N_("Debug rpmps Problem Set"), NULL},
00469  { "rpmtedebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmte_debug, -1,
00470         N_("Debug rpmte Transaction Element"), NULL},
00471  { "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1,
00472         N_("Debug rpmts Transaction Set"), NULL},
00473  { "rpmwfdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmwf_debug, -1,
00474         N_("Debug rpmwf Wrapper Format"), NULL},
00475  { "stats", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_stats, -1,
00476         N_("Display operation statistics"), NULL},
00477 
00478  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
00479         NULL, NULL},
00480 
00481    POPT_TABLEEND
00482 };
00483 /*@=bitwisesigned =compmempass @*/
00484 
00485 poptContext
00486 rpmcliFini(poptContext optCon)
00487         /*@globals keyids @*/
00488         /*@modifies keyids @*/
00489 {
00490 /*@-nestedextern@*/
00491     extern rpmioPool _rpmjsPool;
00492     extern rpmioPool _rpmrubyPool;
00493     extern rpmioPool _headerPool;
00494     extern rpmioPool _rpmmiPool;
00495     extern rpmioPool _dbiPool;
00496     extern rpmioPool _rpmdbPool;
00497     extern rpmioPool _rpmrepoPool;
00498     extern rpmioPool _rpmwfPool;
00499     extern const char * evr_tuple_order;
00500     extern const char * evr_tuple_match;
00501     extern miRE evr_tuple_mire;
00502 /*@=nestedextern@*/
00503 
00504 /*@-mods@*/
00505     evr_tuple_order = _free(evr_tuple_order);
00506     evr_tuple_match = _free(evr_tuple_match);
00507     evr_tuple_mire = mireFree(evr_tuple_mire);
00508 
00509 /*@-onlyunqglobaltrans@*/
00510     /* Realease (and dereference) embedded interpreter global objects first. */
00511     _rpmjsI = rpmjsFree(_rpmjsI);
00512     _rpmjsPool = rpmioFreePool(_rpmjsPool);
00513     _rpmrubyI = rpmrubyFree(_rpmrubyI);
00514     _rpmrubyPool = rpmioFreePool(_rpmrubyPool);
00515 
00516     _rpmgiPool = rpmioFreePool(_rpmgiPool);
00517     _rpmmiPool = rpmioFreePool(_rpmmiPool);
00518 
00519     _psmPool = rpmioFreePool(_psmPool);
00520     _rpmtsiPool = rpmioFreePool(_rpmtsiPool);
00521 
00522     _rpmtsPool = rpmioFreePool(_rpmtsPool);
00523     _rpmtePool = rpmioFreePool(_rpmtePool);
00524     _rpmpsPool = rpmioFreePool(_rpmpsPool);
00525 
00526     _rpmfcPool = rpmioFreePool(_rpmfcPool);
00527 
00528     rpmnsClean();
00529 
00530     _rpmdsPool = rpmioFreePool(_rpmdsPool);
00531     _rpmfiPool = rpmioFreePool(_rpmfiPool);
00532 
00533     _rpmwfPool = rpmioFreePool(_rpmwfPool);
00534     _rpmdbPool = rpmioFreePool(_rpmdbPool);
00535     _rpmrepoPool = rpmioFreePool(_rpmrepoPool);
00536     _dbiPool = rpmioFreePool(_dbiPool);
00537     _headerPool = rpmioFreePool(_headerPool);
00538 /*@=onlyunqglobaltrans@*/
00539 /*@=mods@*/
00540 
00541     /* XXX this should be done in the rpmioClean() wrapper. */
00542     /* keeps memory leak checkers quiet */
00543     rpmFreeMacros(NULL);
00544 /*@i@*/ rpmFreeMacros(rpmCLIMacroContext);
00545 
00546     rpmFreeRpmrc();     /* XXX mireFreeAll(platpat) before rpmioFreePool. */
00547 
00548     rpmFreeFilesystems();
00549 /*@i@*/ rpmcliTargets = _free(rpmcliTargets);
00550 
00551     keyids = _free(keyids);
00552 
00553     tagClean(NULL);     /* Free header tag indices. */
00554 
00555     rpmioClean();       /* XXX rpmioFreePool()'s after everything else. */
00556 
00557     optCon = poptFreeContext(optCon);
00558 
00559 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
00560     /*@-noeffect@*/
00561     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00562     /*@=noeffect@*/
00563 #endif
00564 
00565 /*@-globstate@*/
00566     return NULL;
00567 /*@=globstate@*/
00568 }
00569 
00570 static inline int checkfd(const char * devnull, int fdno, int flags)
00571         /*@*/
00572 {
00573     struct stat sb;
00574     int ret = 0;
00575 
00576     if (fstat(fdno, &sb) == -1 && errno == EBADF)
00577         ret = (open(devnull, flags) == fdno) ? 1 : 2;
00578     return ret;
00579 }
00580 
00581 #if defined(RPM_VENDOR_WINDRIVER)
00582 void setRuntimeRelocPaths(void)
00583 {
00584     /* 
00585      * This is just an example of setting the values using env
00586      * variables....  if they're not set, we make sure they get set
00587      * for helper apps...  We probably want to escape "%" in the path
00588      * to avoid macro expansion.. someone might have a % in a path...
00589      */
00590 
00591     __usrlibrpm = getenv("RPM_USRLIBRPM");
00592     __etcrpm = getenv("RPM_ETCRPM");
00593 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
00594     __localedir = getenv("RPM_LOCALEDIR");
00595 #endif
00596 
00597     if ( __usrlibrpm == NULL ) {
00598         __usrlibrpm = USRLIBRPM ;
00599         setenv("RPM_USRLIBRPM", USRLIBRPM, 0);
00600     }
00601 
00602     if ( __etcrpm == NULL ) {
00603         __etcrpm = SYSCONFIGDIR ;
00604         setenv("RPM_ETCRPM", SYSCONFIGDIR, 0);
00605     }
00606 
00607 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
00608     if ( __localedir == NULL ) {
00609         __localedir = LOCALEDIR ;
00610         setenv("RPM_LOCALEDIR", LOCALEDIR, 0);
00611     }
00612 #endif
00613 }
00614 #endif
00615 
00616 /*@-globstate@*/
00617 poptContext
00618 rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
00619         /*@globals rpmpoptfiles @*/
00620         /*@modifies rpmpoptfiles @*/
00621 {
00622     poptContext optCon;
00623     int rc;
00624     int xx;
00625     int i;
00626 
00627 #if defined(HAVE_MCHECK_H) && defined(HAVE_MTRACE)
00628     /*@-noeffect@*/
00629     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
00630     /*@=noeffect@*/
00631 #endif
00632 /*@-globs -mods@*/
00633     setprogname(argv[0]);       /* Retrofit glibc __progname */
00634 
00635     /* XXX glibc churn sanity */
00636     if (__progname == NULL) {
00637         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
00638         else __progname = argv[0];
00639     }
00640 /*@=globs =mods@*/
00641 
00642     /* Insure that stdin/stdout/stderr are open, lest stderr end up in rpmdb. */
00643    {    static const char _devnull[] = "/dev/null";
00644 #if defined(STDIN_FILENO)
00645         (void) checkfd(_devnull, STDIN_FILENO, O_RDONLY);
00646 #endif
00647 #if defined(STDOUT_FILENO)
00648         (void) checkfd(_devnull, STDOUT_FILENO, O_WRONLY);
00649 #endif
00650 #if defined(STDERR_FILENO)
00651         (void) checkfd(_devnull, STDERR_FILENO, O_WRONLY);
00652 #endif
00653    }
00654 
00655 #if defined(RPM_VENDOR_WINDRIVER)
00656     (void) setRuntimeRelocPaths();
00657 #endif
00658 
00659 #if defined(ENABLE_NLS) && !defined(__LCLINT__)
00660     (void) setlocale(LC_ALL, "" );
00661     (void) bindtextdomain(PACKAGE, __localedir);
00662     (void) textdomain(PACKAGE);
00663 #endif
00664 
00665     rpmSetVerbosity(RPMLOG_NOTICE);
00666 
00667     if (optionsTable == NULL) {
00668         /* Read rpm configuration (if not already read). */
00669         rpmcliConfigured();
00670         return NULL;
00671     }
00672 
00673     /* read all RPM POPT configuration files */
00674     for (i = 1; i < argc; i++) {
00675         if (strcmp(argv[i], "--rpmpopt") == 0 && i+1 < argc) {
00676             rpmpoptfiles = argv[i+1];
00677             break;
00678         }
00679         else if (strncmp(argv[i], "--rpmpopt=", 10) == 0) {
00680             rpmpoptfiles = argv[i]+10;
00681             break;
00682         }
00683     }
00684 
00685     /* XXX strip off the "lt-" prefix so that rpmpopt aliases "work". */
00686 {   static const char lt_[] = "lt-";
00687     const char * s = __progname;
00688     if (!strncmp(s, lt_, sizeof(lt_)-1))
00689         s += sizeof(lt_)-1;
00690 /*@-nullpass -temptrans@*/
00691     optCon = poptGetContext(s, argc, (const char **)argv, optionsTable, 0);
00692 /*@=nullpass =temptrans@*/
00693 }
00694 
00695 #if defined(RPM_VENDOR_OPENPKG) /* stick-with-rpm-file-sanity-checking */ || \
00696     !defined(POPT_ERROR_BADCONFIG)      /* XXX POPT 1.15 retrofit */
00697   { char * path_buf = xstrdup(rpmpoptfiles);
00698     char *path;
00699     char *path_next;
00700 
00701     for (path = path_buf; path != NULL && *path != '\0'; path = path_next) {
00702         const char **av;
00703         int ac;
00704 
00705         /* locate start of next path element */
00706         path_next = strchr(path, ':');
00707         if (path_next != NULL && *path_next == ':')
00708             *path_next++ = '\0';
00709         else
00710             path_next = path + strlen(path);
00711 
00712         /* glob-expand the path element */
00713         ac = 0;
00714         av = NULL;
00715         if ((xx = rpmGlob(path, &ac, &av)) != 0)
00716             continue;
00717 
00718         /* work-off each resulting file from the path element */
00719         for (i = 0; i < ac; i++) {
00720             const char *fn = av[i];
00721             if (fn[0] == '@' /* attention */) {
00722                 fn++;
00723                 if (!rpmSecuritySaneFile(fn)) {
00724                     rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", fn);
00725                     /*@innercontinue@*/ continue;
00726                 }
00727             }
00728             (void) poptReadConfigFile(optCon, fn);
00729             av[i] = _free(av[i]);
00730         }
00731         av = _free(av);
00732     }
00733     path_buf = _free(path_buf);
00734   }
00735 #else
00736     /* XXX FIXME: better error message is needed. */
00737     if ((xx = poptReadConfigFiles(optCon, rpmpoptfiles)) != 0)
00738         rpmlog(RPMLOG_WARNING, "existing POPT configuration file \"%s\" considered INSECURE -- not loaded\n", rpmpoptfiles);
00739 #endif
00740 
00741 #if defined(RPM_VENDOR_WINDRIVER)
00742     {   const char * poptAliasFn = rpmGetPath(__usrlibrpm, "/rpmpopt", NULL);
00743         (void) poptReadConfigFile(optCon, poptAliasFn);
00744         poptAliasFn = _free(poptAliasFn);
00745     }
00746 #endif
00747 
00748     /* read standard POPT configuration files */
00749     /* XXX FIXME: the 2nd arg useEnv flag is UNUSED. */
00750     (void) poptReadDefaultConfig(optCon, 1);
00751 
00752 #if defined(RPM_VENDOR_WINDRIVER)
00753     {   const char * poptExecPath = rpmGetPath(__usrlibrpm, NULL);
00754         poptSetExecPath(optCon, poptExecPath, 1);
00755         poptExecPath = _free(poptExecPath);
00756     }
00757 #else
00758     poptSetExecPath(optCon, USRLIBRPM, 1);
00759 #endif
00760 
00761     /* Process all options, whine if unknown. */
00762     while ((rc = poptGetNextOpt(optCon)) > 0) {
00763         const char * optArg = poptGetOptArg(optCon);
00764 /*@-dependenttrans -observertrans@*/    /* Avoid popt memory leaks. */
00765         optArg = _free(optArg);
00766 /*@=dependenttrans =observertrans @*/
00767         switch (rc) {
00768         default:
00769 /*@-nullpass@*/
00770             fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
00771                 __progname, rc);
00772 /*@=nullpass@*/
00773             exit(EXIT_FAILURE);
00774 
00775             /*@notreached@*/ /*@switchbreak@*/ break;
00776         }
00777     }
00778 
00779     if (rc < -1) {
00780 /*@-nullpass@*/
00781         fprintf(stderr, "%s: %s: %s\n", __progname,
00782                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
00783                 poptStrerror(rc));
00784 /*@=nullpass@*/
00785         exit(EXIT_FAILURE);
00786     }
00787 
00788     /* Read rpm configuration (if not already read). */
00789     rpmcliConfigured();
00790 
00791     if (_debug) {
00792         rpmIncreaseVerbosity();
00793         rpmIncreaseVerbosity();
00794     }
00795 
00796     /* Initialize header stat collection. */
00797 /*@-mods@*/
00798     _hdr_stats = _rpmts_stats;
00799 /*@=mods@*/
00800 
00801     return optCon;
00802 }
00803 /*@=globstate@*/