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