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