rpm
5.2.1
|
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@*/