rpm 5.2.1

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