rpm 5.3.12
|
00001 #include "system.h" 00002 extern const char *__progname; 00003 00004 /* Copyright (C) 1998-2002 - Red Hat, Inc. */ 00005 00006 #define _AUTOHELP 00007 00008 #if defined(IAM_RPM) || defined(__LCLINT__) 00009 #define IAM_RPMBT 00010 #define IAM_RPMDB 00011 #define IAM_RPMEIU 00012 #define IAM_RPMQV 00013 #define IAM_RPMK 00014 #endif 00015 00016 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */ 00017 #define _RPMIOB_INTERNAL /* XXX rpmiobSlurp */ 00018 #include "rpmio_internal.h" 00019 #endif 00020 00021 #include <rpmio.h> 00022 #include <rpmiotypes.h> 00023 #include <poptIO.h> 00024 00025 #include <rpmtypes.h> 00026 #include <rpmtag.h> 00027 #include "rpmdb.h" 00028 00029 #if defined(IAM_RPMBT) || defined(IAM_RPMK) 00030 #include "signature.h" 00031 #endif 00032 00033 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */ 00034 #include "rpmns.h" 00035 #define _RPMLUA_INTERNAL 00036 #include "rpmlua.h" 00037 #include "rpmluaext.h" 00038 #endif 00039 00040 #include "rpmversion.h" 00041 #include "rpmps.h" 00042 #include "rpmts.h" 00043 00044 #include "fs.h" /* XXX for rpmFreeFilesystems() */ 00045 00046 #include <rpmbuild.h> 00047 00048 #ifdef IAM_RPMBT 00049 #include "build.h" 00050 #define GETOPT_REBUILD 1003 00051 #define GETOPT_RECOMPILE 1004 00052 #endif 00053 00054 #include <rpmcli.h> 00055 #include <rpmrollback.h> 00056 00057 #include "debug.h" 00058 00059 enum modes { 00060 MODE_UNKNOWN = 0, 00061 00062 MODE_QUERY = (1 << 0), 00063 MODE_VERIFY = (1 << 3), 00064 #define MODES_QV (MODE_QUERY | MODE_VERIFY) 00065 00066 MODE_INSTALL = (1 << 1), 00067 MODE_ERASE = (1 << 2), 00068 #define MODES_IE (MODE_INSTALL | MODE_ERASE) 00069 00070 MODE_BUILD = (1 << 4), 00071 MODE_REBUILD = (1 << 5), 00072 MODE_RECOMPILE = (1 << 8), 00073 MODE_TARBUILD = (1 << 11), 00074 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE) 00075 00076 MODE_CHECKSIG = (1 << 6), 00077 MODE_RESIGN = (1 << 7), 00078 #define MODES_K (MODE_CHECKSIG | MODE_RESIGN) 00079 00080 MODE_REBUILDDB = (1 << 12), 00081 #define MODES_DB (MODE_REBUILDDB) 00082 }; 00083 00084 #define MODES_FOR_DBPATH (MODES_BT | MODES_IE | MODES_QV | MODES_DB) 00085 #define MODES_FOR_NODEPS (MODES_BT | MODES_IE | MODE_VERIFY) 00086 #define MODES_FOR_TEST (MODES_BT | MODES_IE) 00087 #define MODES_FOR_ROOT (MODES_BT | MODES_IE | MODES_QV | MODES_DB | MODES_K) 00088 00089 /* the structure describing the options we take and the defaults */ 00090 /*@unchecked@*/ 00091 static struct poptOption optionsTable[] = { 00092 00093 #ifdef IAM_RPMQV 00094 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0, 00095 N_("Query options (with -q or --query):"), 00096 NULL }, 00097 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0, 00098 N_("Verify options (with -V or --verify):"), 00099 NULL }, 00100 #ifdef NOTYET 00101 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliQVSourcePoptTable, 0, 00102 N_("Source options (with --query or --verify):"), 00103 NULL }, 00104 #endif 00105 #endif /* IAM_RPMQV */ 00106 00107 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU) 00108 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliDepFlagsPoptTable, 0, 00109 N_("Dependency check/order options:"), 00110 NULL }, 00111 #endif /* IAM_RPMQV */ 00112 00113 #ifdef IAM_RPMQV 00114 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioFtsPoptTable, 0, 00115 N_("File tree walk options (with --ftswalk):"), 00116 NULL }, 00117 #endif /* IAM_RPMQV */ 00118 00119 #ifdef IAM_RPMK 00120 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0, 00121 N_("Signature options:"), 00122 NULL }, 00123 #endif /* IAM_RPMK */ 00124 00125 #ifdef IAM_RPMDB 00126 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0, 00127 N_("Database options:"), 00128 NULL }, 00129 #endif /* IAM_RPMDB */ 00130 00131 #ifdef IAM_RPMBT 00132 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0, 00133 N_("Build options with [ <specfile> | <tarball> | <source package> ]:"), 00134 NULL }, 00135 #endif /* IAM_RPMBT */ 00136 00137 #ifdef IAM_RPMEIU 00138 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0, 00139 N_("Install/Upgrade/Erase options:"), 00140 NULL }, 00141 #endif /* IAM_RPMEIU */ 00142 00143 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0, 00144 N_("Common options:"), 00145 NULL }, 00146 00147 POPT_AUTOALIAS 00148 POPT_AUTOHELP 00149 POPT_TABLEEND 00150 }; 00151 00152 #ifdef __MINT__ 00153 /* MiNT cannot dynamically increase the stack. */ 00154 long _stksize = 64 * 1024L; 00155 #endif 00156 00157 /*@exits@*/ static void argerror(const char * desc) 00158 /*@globals __assert_program_name, fileSystem @*/ 00159 /*@modifies fileSystem @*/ 00160 { 00161 fprintf(stderr, _("%s: %s\n"), __progname, desc); 00162 exit(EXIT_FAILURE); 00163 } 00164 00165 #ifdef DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */ 00166 static void printVersion(FILE * fp) 00167 /*@globals rpmEVR, fileSystem @*/ 00168 /*@modifies *fp, fileSystem @*/ 00169 { 00170 fprintf(fp, "%s (" RPM_NAME ") %s\n", __progname, rpmEVR); 00171 if (rpmIsVerbose()) 00172 fprintf(fp, "rpmlib 0x%08x,0x%08x,0x%08x\n", 00173 rpmlibVersion(), rpmlibTimestamp(), rpmlibVendor()); 00174 } 00175 00176 static void printUsage(poptContext con, FILE * fp, int flags) 00177 /*@globals rpmEVR, fileSystem, internalState @*/ 00178 /*@modifies *fp, fileSystem, internalState @*/ 00179 { 00180 printVersion(fp); 00181 fprintf(fp, "\n"); 00182 00183 if (rpmIsVerbose()) 00184 poptPrintHelp(con, fp, flags); 00185 else 00186 poptPrintUsage(con, fp, flags); 00187 } 00188 #endif 00189 00190 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */ 00191 00192 #if !defined(RPM_INTEGRITY_FP) 00193 #error required RPM_INTEGRITY_FP (fingerprint of public key of integrity authority) not defined! 00194 #endif 00195 00196 enum { 00197 INTEGRITY_OK = 0, 00198 INTEGRITY_WARNING = 1, 00199 INTEGRITY_ERROR = 2 00200 }; 00201 00202 static void integrity_check_message(const char *fmt, ...) 00203 { 00204 va_list ap; 00205 00206 va_start(ap, fmt); 00207 fprintf(stderr, "rpm: ATTENTION: INTEGRITY CHECKING DETECTED AN ENVIRONMENT ANOMALY!\nrpm: "); 00208 vfprintf(stderr, fmt, ap); 00209 va_end(ap); 00210 return; 00211 } 00212 00213 static void integrity_check(const char *progname, enum modes progmode_num) 00214 { 00215 rpmts ts = NULL; 00216 rpmlua lua = NULL; 00217 char *spec_fn = NULL; 00218 char *proc_fn = NULL; 00219 char *pkey_fn = NULL; 00220 char *spec = NULL; 00221 char *proc = NULL; 00222 rpmiob spec_iob = NULL; 00223 rpmiob proc_iob = NULL; 00224 const char *result = NULL; 00225 const char *error = NULL; 00226 int xx; 00227 const char *progmode; 00228 int rc = INTEGRITY_ERROR; 00229 00230 /* determine paths of integrity checking related files */ 00231 spec_fn = rpmExpand("%{?_integrity_spec_cfg}%{!?_integrity_spec_cfg:scripts/integrity.cfg}", NULL); 00232 if (spec_fn == NULL || spec_fn[0] == '\0') { 00233 integrity_check_message("ERROR: Integrity Configuration Specification file not configured.\n" 00234 "rpm: HINT: macro %%{_integrity_spec_cfg} not configured correctly.\n"); 00235 goto failure; 00236 } 00237 proc_fn = rpmExpand("%{?_integrity_proc_lua}%{!?_integrity_proc_lua:scripts/integrity.lua}", NULL); 00238 if (proc_fn == NULL || proc_fn[0] == '\0') { 00239 integrity_check_message("ERROR: Integrity Validation Processor file not configured.\n" 00240 "rpm: HINT: macro %%{_integrity_proc_lua} not configured correctly.\n"); 00241 goto failure; 00242 } 00243 pkey_fn = rpmExpand("%{?_integrity_pkey_pgp}%{!?_integrity_pkey_pgp:scripts/integrity.pgp}", NULL); 00244 if (pkey_fn == NULL || pkey_fn[0] == '\0') { 00245 integrity_check_message("ERROR: Integrity Autority Public-Key file not configured.\n" 00246 "rpm: HINT: macro %%{_integrity_pkey_pgp} not configured correctly.\n"); 00247 goto failure; 00248 } 00249 00250 /* create RPM transaction environment and open RPM database */ 00251 ts = rpmtsCreate(); 00252 (void)rpmtsOpenDB(ts, O_RDONLY); 00253 00254 /* check signature on integrity configuration specification file */ 00255 if (rpmnsProbeSignature(ts, spec_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) { 00256 integrity_check_message("ERROR: Integrity Configuration Specification file contains invalid signature.\n" 00257 "rpm: HINT: Check file \"%s\".\n", spec_fn); 00258 goto failure; 00259 } 00260 00261 /* check signature on integrity validation processor file */ 00262 if (rpmnsProbeSignature(ts, proc_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) { 00263 integrity_check_message("ERROR: Integrity Validation Processor file contains invalid signature.\n" 00264 "rpm: HINT: Check file \"%s\".\n", proc_fn); 00265 goto failure; 00266 } 00267 00268 /* load integrity configuration specification file */ 00269 xx = rpmiobSlurp(spec_fn, &spec_iob); 00270 if (!(xx == 0 && spec_iob != NULL)) { 00271 integrity_check_message("ERROR: Unable to load Integrity Configuration Specification file.\n" 00272 "rpm: HINT: Check file \"%s\".\n", spec_fn); 00273 goto failure; 00274 } 00275 spec = rpmiobStr(spec_iob); 00276 00277 /* load integrity validation processor file */ 00278 xx = rpmiobSlurp(proc_fn, &proc_iob); 00279 if (!(xx == 0 && proc_iob != NULL)) { 00280 integrity_check_message("ERROR: Unable to load Integrity Validation Processor file.\n" 00281 "rpm: HINT: Check file \"%s\".\n", proc_fn); 00282 goto failure; 00283 } 00284 proc = rpmiobStr(proc_iob); 00285 00286 /* provision program name and mode */ 00287 if (progname == NULL || progname[0] == '\0') 00288 progname = "rpm"; 00289 switch (progmode_num) { 00290 case MODE_QUERY: progmode = "query"; break; 00291 case MODE_VERIFY: progmode = "verify"; break; 00292 case MODE_CHECKSIG: progmode = "checksig"; break; 00293 case MODE_RESIGN: progmode = "resign"; break; 00294 case MODE_INSTALL: progmode = "install"; break; 00295 case MODE_ERASE: progmode = "erase"; break; 00296 case MODE_BUILD: progmode = "build"; break; 00297 case MODE_REBUILD: progmode = "rebuild"; break; 00298 case MODE_RECOMPILE: progmode = "recompile"; break; 00299 case MODE_TARBUILD: progmode = "tarbuild"; break; 00300 case MODE_REBUILDDB: progmode = "rebuilddb"; break; 00301 case MODE_UNKNOWN: progmode = "unknown"; break; 00302 default: progmode = "unknown"; break; 00303 } 00304 00305 /* execute Integrity Validation Processor via Lua glue code */ 00306 lua = rpmluaNew(); 00307 rpmluaSetPrintBuffer(lua, 1); 00308 rpmluaextActivate(lua); 00309 lua_getfield(lua->L, LUA_GLOBALSINDEX, "integrity"); 00310 lua_getfield(lua->L, -1, "processor"); 00311 lua_remove(lua->L, -2); 00312 lua_pushstring(lua->L, progname); 00313 lua_pushstring(lua->L, progmode); 00314 lua_pushstring(lua->L, spec_fn); 00315 lua_pushstring(lua->L, spec); 00316 lua_pushstring(lua->L, proc_fn); 00317 lua_pushstring(lua->L, proc); 00318 #ifdef RPM_INTEGRITY_MV 00319 lua_pushstring(lua->L, RPM_INTEGRITY_MV); 00320 #else 00321 lua_pushstring(lua->L, "0"); 00322 #endif 00323 if (lua_pcall(lua->L, 7, 1, 0) != 0) { 00324 error = lua_isstring(lua->L, -1) ? lua_tostring(lua->L, -1) : "unknown error"; 00325 lua_pop(lua->L, 1); 00326 integrity_check_message("ERROR: Failed to execute Integrity Validation Processor.\n" 00327 "rpm: ERROR: Lua: %s.\n" 00328 "rpm: HINT: Check file \"%s\".\n", error, proc_fn); 00329 goto failure; 00330 } 00331 00332 /* check Integrity Validation Processor results */ 00333 if (!lua_isstring(lua->L, -1)) { 00334 integrity_check_message("ERROR: Failed to fetch Integrity Validation Processor results.\n" 00335 "rpm: HINT: Check file \"%s\".\n", proc_fn); 00336 goto failure; 00337 } 00338 result = lua_tostring(lua->L, -1); 00339 if (strcmp(result, "OK") == 0) 00340 rc = INTEGRITY_OK; 00341 else if (strncmp(result, "WARNING:", 8) == 0) { 00342 rc = INTEGRITY_WARNING; 00343 integrity_check_message("%s\n", result); 00344 } 00345 else { 00346 rc = INTEGRITY_ERROR; 00347 integrity_check_message("%s\n", result); 00348 } 00349 00350 /* cleanup processing */ 00351 failure: 00352 if (lua != NULL) 00353 rpmluaFree(lua); 00354 if (ts != NULL) 00355 (void)rpmtsFree(ts); 00356 ts = NULL; 00357 if (spec_iob != NULL) 00358 spec_iob = rpmiobFree(spec_iob); 00359 if (proc_iob != NULL) 00360 proc_iob = rpmiobFree(proc_iob); 00361 00362 /* final result handling */ 00363 if (rc != INTEGRITY_OK) { 00364 if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO)) 00365 sleep(4); 00366 if (rc == INTEGRITY_ERROR) 00367 exit(42); 00368 } 00369 return; 00370 } 00371 #endif 00372 00373 /*@-bounds@*/ /* LCL: segfault */ 00374 /*@-mods@*/ /* FIX: shrug */ 00375 #if !defined(__GLIBC__) && !defined(__LCLINT__) 00376 int main(int argc, const char ** argv, /*@unused@*/ char ** envp) 00377 #else 00378 int main(int argc, const char ** argv) 00379 #endif 00380 /*@globals rpmEVR, RPMVERSION, 00381 rpmGlobalMacroContext, rpmCLIMacroContext, 00382 h_errno, fileSystem, internalState@*/ 00383 /*@modifies fileSystem, internalState@*/ 00384 { 00385 poptContext optCon = rpmcliInit(argc, (char *const *)argv, optionsTable); 00386 00387 rpmts ts = NULL; 00388 enum modes bigMode = MODE_UNKNOWN; 00389 00390 #if defined(IAM_RPMQV) 00391 QVA_t qva = &rpmQVKArgs; 00392 #endif 00393 00394 #ifdef IAM_RPMBT 00395 BTA_t ba = &rpmBTArgs; 00396 #endif 00397 00398 #ifdef IAM_RPMEIU 00399 QVA_t ia = &rpmIArgs; 00400 #endif 00401 00402 #if defined(IAM_RPMDB) 00403 QVA_t da = &rpmDBArgs; 00404 #endif 00405 00406 #if defined(IAM_RPMK) 00407 QVA_t ka = &rpmQVKArgs; 00408 #endif 00409 00410 #if defined(IAM_RPMBT) || defined(IAM_RPMK) 00411 char * passPhrase = ""; 00412 #endif 00413 00414 pid_t pipeChild = 0; 00415 int ec = 0; 00416 int status; 00417 int p[2]; 00418 #ifdef IAM_RPMEIU 00419 int xx; 00420 #endif 00421 00422 #if !defined(__GLIBC__) && !defined(__LCLINT__) 00423 environ = envp; 00424 #else 00425 /* XXX limit the fiddle up to linux for now. */ 00426 #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) 00427 (void) initproctitle(argc, (char **)argv, environ); 00428 #endif 00429 #endif 00430 00431 /* Set the major mode based on argv[0] */ 00432 /*@-nullpass@*/ 00433 #ifdef IAM_RPMBT 00434 if (!strcmp(__progname, "rpmb")) bigMode = MODE_BUILD; 00435 if (!strcmp(__progname, "lt-rpmb")) bigMode = MODE_BUILD; 00436 if (!strcmp(__progname, "rpmt")) bigMode = MODE_TARBUILD; 00437 if (!strcmp(__progname, "rpmbuild")) bigMode = MODE_BUILD; 00438 #endif 00439 #ifdef IAM_RPMQV 00440 if (!strcmp(__progname, "rpmq")) bigMode = MODE_QUERY; 00441 if (!strcmp(__progname, "lt-rpmq")) bigMode = MODE_QUERY; 00442 if (!strcmp(__progname, "rpmv")) bigMode = MODE_VERIFY; 00443 if (!strcmp(__progname, "rpmquery")) bigMode = MODE_QUERY; 00444 if (!strcmp(__progname, "rpmverify")) bigMode = MODE_VERIFY; 00445 #endif 00446 #ifdef RPMEIU 00447 if (!strcmp(__progname, "rpme")) bigMode = MODE_ERASE; 00448 if (!strcmp(__progname, "rpmi")) bigMode = MODE_INSTALL; 00449 if (!strcmp(__progname, "lt-rpmi")) bigMode = MODE_INSTALL; 00450 if (!strcmp(__progname, "rpmu")) bigMode = MODE_INSTALL; 00451 #endif 00452 /*@=nullpass@*/ 00453 00454 #if defined(IAM_RPMQV) 00455 /* Jumpstart option from argv[0] if necessary. */ 00456 switch (bigMode) { 00457 case MODE_QUERY: qva->qva_mode = 'q'; break; 00458 case MODE_VERIFY: qva->qva_mode = 'V'; break; 00459 case MODE_CHECKSIG: qva->qva_mode = 'K'; break; 00460 case MODE_RESIGN: qva->qva_mode = 'R'; break; 00461 case MODE_INSTALL: 00462 case MODE_ERASE: 00463 case MODE_BUILD: 00464 case MODE_REBUILD: 00465 case MODE_RECOMPILE: 00466 case MODE_TARBUILD: 00467 case MODE_REBUILDDB: 00468 case MODE_UNKNOWN: 00469 default: 00470 break; 00471 } 00472 #endif 00473 00474 rpmcliConfigured(); 00475 00476 #ifdef IAM_RPMBT 00477 switch (ba->buildMode) { 00478 case 'b': bigMode = MODE_BUILD; break; 00479 case 't': bigMode = MODE_TARBUILD; break; 00480 case 'B': bigMode = MODE_REBUILD; break; 00481 case 'C': bigMode = MODE_RECOMPILE; break; 00482 } 00483 00484 if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN) 00485 bigMode = MODE_BUILD; 00486 00487 if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN) 00488 bigMode = MODE_BUILD; 00489 #endif /* IAM_RPMBT */ 00490 00491 #ifdef IAM_RPMDB 00492 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) { 00493 if (da->rebuild) { 00494 if (bigMode != MODE_UNKNOWN) 00495 argerror(_("only one major mode may be specified")); 00496 else 00497 bigMode = MODE_REBUILDDB; 00498 } 00499 } 00500 #endif /* IAM_RPMDB */ 00501 00502 #ifdef IAM_RPMQV 00503 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) { 00504 switch (qva->qva_mode) { 00505 case 'q': bigMode = MODE_QUERY; break; 00506 case 'V': bigMode = MODE_VERIFY; break; 00507 } 00508 00509 if (qva->qva_sourceCount) { 00510 if (qva->qva_sourceCount > 2) 00511 argerror(_("one type of query/verify may be performed at a " 00512 "time")); 00513 } 00514 if (qva->qva_flags && (bigMode & ~MODES_QV)) 00515 argerror(_("unexpected query flags")); 00516 00517 if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 00518 argerror(_("unexpected query format")); 00519 00520 if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 00521 argerror(_("unexpected query source")); 00522 } 00523 #endif /* IAM_RPMQV */ 00524 00525 #ifdef IAM_RPMEIU 00526 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE)) 00527 { int iflags = (ia->installInterfaceFlags & 00528 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL)); 00529 int eflags = (ia->installInterfaceFlags & INSTALL_ERASE); 00530 00531 if (iflags & eflags) 00532 argerror(_("only one major mode may be specified")); 00533 else if (iflags) 00534 bigMode = MODE_INSTALL; 00535 else if (eflags) 00536 bigMode = MODE_ERASE; 00537 } 00538 #endif /* IAM_RPMEIU */ 00539 00540 #ifdef IAM_RPMK 00541 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) { 00542 switch (ka->qva_mode) { 00543 case RPMSIGN_NONE: 00544 ka->sign = 0; 00545 break; 00546 case RPMSIGN_IMPORT_PUBKEY: 00547 case RPMSIGN_CHK_SIGNATURE: 00548 bigMode = MODE_CHECKSIG; 00549 ka->sign = 0; 00550 break; 00551 case RPMSIGN_ADD_SIGNATURE: 00552 case RPMSIGN_NEW_SIGNATURE: 00553 case RPMSIGN_DEL_SIGNATURE: 00554 bigMode = MODE_RESIGN; 00555 ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE); 00556 break; 00557 } 00558 } 00559 #endif /* IAM_RPMK */ 00560 00561 #if defined(IAM_RPMEIU) 00562 if (!( bigMode == MODE_INSTALL ) && 00563 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE))) 00564 argerror(_("only installation, upgrading, rmsource and rmspec may be forced")); 00565 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE)) 00566 argerror(_("files may only be relocated during package installation")); 00567 00568 if (ia->relocations && ia->qva_prefix) 00569 argerror(_("cannot use --prefix with --relocate or --excludepath")); 00570 00571 if (bigMode != MODE_INSTALL && ia->relocations) 00572 argerror(_("--relocate and --excludepath may only be used when installing new packages")); 00573 00574 if (bigMode != MODE_INSTALL && ia->qva_prefix) 00575 argerror(_("--prefix may only be used when installing new packages")); 00576 00577 if (ia->qva_prefix && ia->qva_prefix[0] != '/') 00578 argerror(_("arguments to --prefix must begin with a /")); 00579 00580 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH)) 00581 argerror(_("--hash (-h) may only be specified during package " 00582 "installation")); 00583 00584 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT)) 00585 argerror(_("--percent may only be specified during package " 00586 "installation")); 00587 00588 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG)) 00589 argerror(_("--replacepkgs may only be specified during package " 00590 "installation")); 00591 00592 if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS)) 00593 argerror(_("--excludedocs may only be specified during package " 00594 "installation")); 00595 00596 if (bigMode != MODE_INSTALL && ia->incldocs) 00597 argerror(_("--includedocs may only be specified during package " 00598 "installation")); 00599 00600 if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS)) 00601 argerror(_("only one of --excludedocs and --includedocs may be " 00602 "specified")); 00603 00604 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH)) 00605 argerror(_("--ignorearch may only be specified during package " 00606 "installation")); 00607 00608 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS)) 00609 argerror(_("--ignoreos may only be specified during package " 00610 "installation")); 00611 00612 if ((ia->installInterfaceFlags & INSTALL_ALLMATCHES) && bigMode != MODE_ERASE) 00613 argerror(_("--allmatches may only be specified during package " 00614 "erasure")); 00615 00616 if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL) 00617 argerror(_("--allfiles may only be specified during package " 00618 "installation")); 00619 00620 if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) && 00621 bigMode != MODE_INSTALL && bigMode != MODE_ERASE) 00622 argerror(_("--justdb may only be specified during package " 00623 "installation and erasure")); 00624 00625 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && 00626 (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers))) 00627 argerror(_("script disabling options may only be specified during " 00628 "package installation and erasure")); 00629 00630 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && 00631 (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers))) 00632 argerror(_("trigger disabling options may only be specified during " 00633 "package installation and erasure")); 00634 00635 if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS)) 00636 argerror(_("--nodeps may only be specified during package " 00637 "building, rebuilding, recompilation, installation, " 00638 "erasure, and verification")); 00639 00640 if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST)) 00641 argerror(_("--test may only be specified during package installation, " 00642 "erasure, and building")); 00643 #endif /* IAM_RPMEIU */ 00644 00645 if (rpmioRootDir && rpmioRootDir[1] && (bigMode & ~MODES_FOR_ROOT)) 00646 argerror(_("--root (-r) may only be specified during " 00647 "installation, erasure, querying, and " 00648 "database rebuilds")); 00649 00650 if (rpmioRootDir) { 00651 switch (urlIsURL(rpmioRootDir)) { 00652 default: 00653 if (bigMode & MODES_FOR_ROOT) 00654 break; 00655 /*@fallthrough@*/ 00656 case URL_IS_UNKNOWN: 00657 if (rpmioRootDir[0] != '/') 00658 argerror(_("arguments to --root (-r) must begin with a /")); 00659 break; 00660 } 00661 } 00662 00663 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */ 00664 integrity_check(__progname, bigMode); 00665 #endif 00666 00667 #if defined(IAM_RPMBT) || defined(IAM_RPMK) 00668 if (0 00669 #if defined(IAM_RPMBT) 00670 || ba->sign 00671 #endif 00672 #if defined(IAM_RPMK) 00673 || ka->sign 00674 #endif 00675 ) 00676 /*@-branchstate@*/ 00677 { 00678 if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD || 00679 bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD) 00680 { 00681 const char ** av; 00682 struct stat sb; 00683 int errors = 0; 00684 00685 if ((av = poptGetArgs(optCon)) == NULL) { 00686 fprintf(stderr, _("no files to sign\n")); 00687 errors++; 00688 } else 00689 while (*av) { 00690 if (Stat(*av, &sb)) { 00691 fprintf(stderr, _("cannot access file %s\n"), *av); 00692 errors++; 00693 } 00694 av++; 00695 } 00696 00697 if (errors) { 00698 ec = errors; 00699 goto exit; 00700 } 00701 00702 00703 if (poptPeekArg(optCon) 00704 #if defined(IAM_RPMBT) 00705 && !ba->nopassword 00706 #endif 00707 #if defined(IAM_RPMK) 00708 && !ka->nopassword 00709 #endif 00710 ) 00711 { 00712 passPhrase = Getpass(_("Enter pass phrase: ")); 00713 if (rpmCheckPassPhrase(passPhrase)) { 00714 fprintf(stderr, _("Pass phrase check failed\n")); 00715 ec = EXIT_FAILURE; 00716 goto exit; 00717 } 00718 fprintf(stderr, _("Pass phrase is good.\n")); 00719 /* XXX Getpass() should realloc instead. */ 00720 passPhrase = xstrdup(passPhrase); 00721 } 00722 } 00723 } 00724 /*@=branchstate@*/ 00725 #endif /* IAM_RPMBT || IAM_RPMK */ 00726 00727 if (rpmioPipeOutput) { 00728 if (pipe(p) < 0) { 00729 fprintf(stderr, _("creating a pipe for --pipe failed: %m\n")); 00730 goto exit; 00731 } 00732 00733 if (!(pipeChild = fork())) { 00734 (void) close(p[1]); 00735 (void) dup2(p[0], STDIN_FILENO); 00736 (void) close(p[0]); 00737 (void) execl("/bin/sh", "/bin/sh", "-c", rpmioPipeOutput, NULL); 00738 fprintf(stderr, _("exec failed\n")); 00739 } 00740 00741 (void) close(p[0]); 00742 (void) dup2(p[1], STDOUT_FILENO); 00743 (void) close(p[1]); 00744 } 00745 00746 ts = rpmtsCreate(); 00747 (void) rpmtsSetRootDir(ts, rpmioRootDir); 00748 switch (bigMode) { 00749 #ifdef IAM_RPMDB 00750 case MODE_REBUILDDB: 00751 { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}"); 00752 rpmVSFlags ovsflags; 00753 if (rpmcliQueryFlags & VERIFY_DIGEST) 00754 vsflags |= _RPMVSF_NODIGESTS; 00755 if (rpmcliQueryFlags & VERIFY_SIGNATURE) 00756 vsflags |= _RPMVSF_NOSIGNATURES; 00757 ovsflags = rpmtsSetVSFlags(ts, vsflags); 00758 ec = rpmtsRebuildDB(ts); 00759 vsflags = rpmtsSetVSFlags(ts, ovsflags); 00760 } break; 00761 #endif /* IAM_RPMDB */ 00762 00763 #ifdef IAM_RPMBT 00764 case MODE_REBUILD: 00765 case MODE_RECOMPILE: 00766 { const char * pkg; 00767 int nbuilds = 0; 00768 00769 while (!rpmIsVerbose()) 00770 rpmIncreaseVerbosity(); 00771 00772 if (!poptPeekArg(optCon)) 00773 argerror(_("no packages files given for rebuild")); 00774 00775 ba->buildAmount = 00776 RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK; 00777 if (bigMode == MODE_REBUILD) { 00778 ba->buildAmount |= RPMBUILD_PACKAGEBINARY; 00779 ba->buildAmount |= RPMBUILD_RMSOURCE; 00780 ba->buildAmount |= RPMBUILD_RMSPEC; 00781 ba->buildAmount |= RPMBUILD_CLEAN; 00782 ba->buildAmount |= RPMBUILD_RMBUILD; 00783 } 00784 00785 while ((pkg = poptGetArg(optCon))) { 00786 if (nbuilds++ > 0) { 00787 rpmFreeMacros(NULL); 00788 rpmFreeRpmrc(); 00789 (void) rpmReadConfigFiles(NULL, NULL); 00790 } 00791 ba->specFile = NULL; 00792 ba->cookie = NULL; 00793 ec = rpmInstallSource(ts, pkg, &ba->specFile, &ba->cookie); 00794 if (ec == 0) { 00795 ba->rootdir = rpmioRootDir; 00796 ba->passPhrase = passPhrase; 00797 ec = build(ts, ba, NULL); 00798 } 00799 ba->cookie = _free(ba->cookie); 00800 ba->specFile = _free(ba->specFile); 00801 00802 if (ec) 00803 /*@loopbreak@*/ break; 00804 } 00805 00806 } break; 00807 00808 case MODE_BUILD: 00809 case MODE_TARBUILD: 00810 { int nbuilds = 0; 00811 00812 #if defined(RPM_VENDOR_OPENPKG) /* no-auto-verbose-increase-for-track-and-fetch */ 00813 if (ba->buildChar != 't' && ba->buildChar != 'f') 00814 #endif 00815 while (!rpmIsVerbose()) 00816 rpmIncreaseVerbosity(); 00817 00818 switch (ba->buildChar) { 00819 case 'a': 00820 ba->buildAmount |= RPMBUILD_PACKAGESOURCE; 00821 /*@fallthrough@*/ 00822 case 'b': 00823 ba->buildAmount |= RPMBUILD_PACKAGEBINARY; 00824 ba->buildAmount |= RPMBUILD_CLEAN; 00825 #if defined(RPM_VENDOR_MANDRIVA) 00826 if ((ba->buildChar == 'a' || ba->buildChar == 'b') && ba->shortCircuit) 00827 #else 00828 if ((ba->buildChar == 'b') && ba->shortCircuit) 00829 #endif 00830 /*@innerbreak@*/ break; 00831 /*@fallthrough@*/ 00832 case 'i': 00833 ba->buildAmount |= RPMBUILD_INSTALL; 00834 ba->buildAmount |= RPMBUILD_CHECK; 00835 if ((ba->buildChar == 'i') && ba->shortCircuit) 00836 /*@innerbreak@*/ break; 00837 /*@fallthrough@*/ 00838 case 'c': 00839 ba->buildAmount |= RPMBUILD_BUILD; 00840 if ((ba->buildChar == 'c') && ba->shortCircuit) 00841 /*@innerbreak@*/ break; 00842 /*@fallthrough@*/ 00843 case 'p': 00844 ba->buildAmount |= RPMBUILD_PREP; 00845 /*@innerbreak@*/ break; 00846 00847 case 'l': 00848 ba->buildAmount |= RPMBUILD_FILECHECK; 00849 /*@innerbreak@*/ break; 00850 case 's': 00851 ba->buildAmount |= RPMBUILD_PACKAGESOURCE; 00852 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* no-deps-on-building-srpms */ 00853 /* enforce no dependency checking when rolling a source RPM */ 00854 ba->noDeps = 1; 00855 #endif 00856 /*@innerbreak@*/ break; 00857 case 't': /* support extracting the "%track" script/section */ 00858 ba->buildAmount |= RPMBUILD_TRACK; 00859 /* enforce no dependency checking and expansion of %setup, %patch and %prep macros */ 00860 ba->noDeps = 1; 00861 rpmDefineMacro(NULL, "setup #", RMIL_CMDLINE); 00862 rpmDefineMacro(NULL, "patch #", RMIL_CMDLINE); 00863 rpmDefineMacro(NULL, "prep %%prep", RMIL_CMDLINE); 00864 /*@innerbreak@*/ break; 00865 case 'f': 00866 ba->buildAmount |= RPMBUILD_FETCHSOURCE; 00867 ba->noDeps = 1; 00868 /*@innerbreak@*/ break; 00869 } 00870 00871 if (!poptPeekArg(optCon)) { 00872 if (bigMode == MODE_BUILD) 00873 argerror(_("no spec files given for build")); 00874 else 00875 argerror(_("no tar files given for build")); 00876 } 00877 00878 while ((ba->specFile = poptGetArg(optCon))) { 00879 if (nbuilds++ > 0) { 00880 rpmFreeMacros(NULL); 00881 rpmFreeRpmrc(); 00882 (void) rpmReadConfigFiles(NULL, NULL); 00883 } 00884 ba->rootdir = rpmioRootDir; 00885 ba->passPhrase = passPhrase; 00886 ba->cookie = NULL; 00887 ec = build(ts, ba, NULL); 00888 if (ec) 00889 /*@loopbreak@*/ break; 00890 } 00891 } break; 00892 #endif /* IAM_RPMBT */ 00893 00894 #ifdef IAM_RPMEIU 00895 case MODE_ERASE: 00896 ia->depFlags = global_depFlags; 00897 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS; 00898 00899 if (!poptPeekArg(optCon)) { 00900 if (ia->rbtid == 0) 00901 argerror(_("no packages given for erase")); 00902 ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; 00903 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; 00904 ia->rbCheck = rpmcliInstallCheck; 00905 ia->rbOrder = rpmcliInstallOrder; 00906 ia->rbRun = rpmcliInstallRun; 00907 ec += rpmRollback(ts, ia, NULL); 00908 } else { 00909 ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon)); 00910 } 00911 break; 00912 00913 case MODE_INSTALL: 00914 00915 /* RPMTRANS_FLAG_KEEPOBSOLETE */ 00916 00917 ia->depFlags = global_depFlags; 00918 if (!ia->incldocs) { 00919 if (ia->transFlags & RPMTRANS_FLAG_NODOCS) { 00920 ; 00921 } else if (rpmExpandNumeric("%{_excludedocs}")) 00922 ia->transFlags |= RPMTRANS_FLAG_NODOCS; 00923 } 00924 00925 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS; 00926 00927 /* we've already ensured !(!ia->prefix && !ia->relocations) */ 00928 /*@-branchstate@*/ 00929 if (ia->qva_prefix) { 00930 xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, 00931 NULL, ia->qva_prefix); 00932 xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, 00933 NULL, NULL); 00934 } else if (ia->relocations) { 00935 xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations, 00936 NULL, NULL); 00937 } 00938 /*@=branchstate@*/ 00939 00940 if (!poptPeekArg(optCon)) { 00941 if (ia->rbtid == 0) 00942 argerror(_("no packages given for install")); 00943 ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS; 00944 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE; 00945 ia->rbCheck = rpmcliInstallCheck; 00946 ia->rbOrder = rpmcliInstallOrder; 00947 ia->rbRun = rpmcliInstallRun; 00948 /*@i@*/ ec += rpmRollback(ts, ia, NULL); 00949 } else { 00950 /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */ 00951 ec += rpmcliInstall(ts, ia, (const char **)poptGetArgs(optCon)); 00952 /*@=compdef =compmempass@*/ 00953 } 00954 break; 00955 00956 #endif /* IAM_RPMEIU */ 00957 00958 #ifdef IAM_RPMQV 00959 case MODE_QUERY: 00960 if (!poptPeekArg(optCon) 00961 && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST)) 00962 argerror(_("no arguments given for query")); 00963 00964 qva->depFlags = global_depFlags; 00965 qva->qva_specQuery = rpmspecQuery; 00966 ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon)); 00967 qva->qva_specQuery = NULL; 00968 break; 00969 00970 case MODE_VERIFY: 00971 { rpmVerifyFlags verifyFlags = VERIFY_ALL; 00972 00973 qva->depFlags = global_depFlags; 00974 verifyFlags &= ~qva->qva_flags; 00975 qva->qva_flags = (rpmQueryFlags) verifyFlags; 00976 00977 if (!poptPeekArg(optCon) 00978 && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST)) 00979 argerror(_("no arguments given for verify")); 00980 ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon)); 00981 } break; 00982 #endif /* IAM_RPMQV */ 00983 00984 #ifdef IAM_RPMK 00985 case MODE_CHECKSIG: 00986 { rpmVerifyFlags verifyFlags = 00987 (VERIFY_FDIGEST|VERIFY_HDRCHK|VERIFY_DIGEST|VERIFY_SIGNATURE); 00988 00989 verifyFlags &= ~ka->qva_flags; 00990 ka->qva_flags = (rpmQueryFlags) verifyFlags; 00991 } /*@fallthrough@*/ 00992 case MODE_RESIGN: 00993 if (!poptPeekArg(optCon)) 00994 argerror(_("no arguments given")); 00995 ka->passPhrase = passPhrase; 00996 ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon)); 00997 break; 00998 #endif /* IAM_RPMK */ 00999 01000 #if !defined(IAM_RPMQV) 01001 case MODE_QUERY: 01002 case MODE_VERIFY: 01003 #endif 01004 #if !defined(IAM_RPMK) 01005 case MODE_CHECKSIG: 01006 case MODE_RESIGN: 01007 #endif 01008 #if !defined(IAM_RPMDB) 01009 case MODE_REBUILDDB: 01010 #endif 01011 #if !defined(IAM_RPMBT) 01012 case MODE_BUILD: 01013 case MODE_REBUILD: 01014 case MODE_RECOMPILE: 01015 case MODE_TARBUILD: 01016 #endif 01017 #if !defined(IAM_RPMEIU) 01018 case MODE_INSTALL: 01019 case MODE_ERASE: 01020 #endif 01021 case MODE_UNKNOWN: 01022 #ifdef DYING /* XXX rpmIsVerbose alone stops usage spewage with every --eval */ 01023 if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) { 01024 printUsage(optCon, stderr, 0); 01025 ec = argc; 01026 } 01027 #endif 01028 break; 01029 } 01030 01031 #if defined(IAM_RPMBT) || defined(IAM_RPMK) 01032 exit: 01033 #endif /* IAM_RPMBT || IAM_RPMK */ 01034 01035 (void)rpmtsFree(ts); 01036 ts = NULL; 01037 01038 if (pipeChild) { 01039 (void) fclose(stdout); 01040 (void) waitpid(pipeChild, &status, 0); 01041 } 01042 01043 #ifdef IAM_RPMQV 01044 qva->qva_queryFormat = _free(qva->qva_queryFormat); 01045 #endif 01046 01047 #ifdef IAM_RPMBT 01048 freeNames(); 01049 /* XXX _specPool/_pkgPool teardown should be done somewhere else. */ 01050 { extern rpmioPool _pkgPool; 01051 extern rpmioPool _specPool; 01052 _pkgPool = rpmioFreePool(_pkgPool); 01053 _specPool = rpmioFreePool(_specPool); 01054 } 01055 #endif 01056 01057 #ifdef IAM_RPMEIU 01058 ia->relocations = rpmfiFreeRelocations(ia->relocations); 01059 #endif 01060 01061 optCon = rpmcliFini(optCon); 01062 01063 /* XXX limit the fiddle up to linux for now. */ 01064 #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) 01065 (void) finiproctitle(); 01066 #endif 01067 01068 /* XXX don't overflow single byte exit status */ 01069 /* XXX status 255 is special to xargs(1) */ 01070 if (ec > 254) ec = 254; 01071 01072 rpmlog(RPMLOG_DEBUG, D_("exit code: %d\n"), ec); 01073 01074 /*@-globstate@*/ 01075 return ec; 01076 /*@=globstate@*/ 01077 } 01078 /*@=mods@*/ 01079 /*@=bounds@*/