rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmqv.c
Go to the documentation of this file.
1 #include "system.h"
2 extern const char *__progname;
3
4 /* Copyright (C) 1998-2002 - Red Hat, Inc. */
5
6 #define _AUTOHELP
7
8 #if defined(IAM_RPM) || defined(__LCLINT__)
9 #define IAM_RPMBT
10 #define IAM_RPMDB
11 #define IAM_RPMEIU
12 #define IAM_RPMQV
13 #define IAM_RPMK
14 #endif
15
16 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */
17 #define _RPMIOB_INTERNAL /* XXX rpmiobSlurp */
18 #include "rpmio_internal.h"
19 #endif
20
21 #include <rpmio.h>
22 #include <rpmiotypes.h>
23 #include <poptIO.h>
24
25 #include <rpmtypes.h>
26 #include <rpmtag.h>
27 #include "rpmdb.h"
28
29 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
30 #include "signature.h"
31 #endif
32
33 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */
34 #include "rpmns.h"
35 #define _RPMLUA_INTERNAL
36 #include "rpmlua.h"
37 #include "rpmluaext.h"
38 #endif
39
40 #include "rpmversion.h"
41 #include "rpmps.h"
42 #include "rpmts.h"
43
44 #include "fs.h" /* XXX for rpmFreeFilesystems() */
45
46 #include <rpmbuild.h>
47
48 #ifdef IAM_RPMBT
49 #include "build.h"
50 #define GETOPT_REBUILD 1003
51 #define GETOPT_RECOMPILE 1004
52 #endif
53
54 #include <rpmcli.h>
55 #include <rpmrollback.h>
56
57 #include "debug.h"
58
59 enum modes {
60
61 MODE_QUERY = (1 << 0),
62 MODE_VERIFY = (1 << 3),
63 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
64
65 MODE_INSTALL = (1 << 1),
66 MODE_ERASE = (1 << 2),
67 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
68
69 MODE_BUILD = (1 << 4),
70 MODE_REBUILD = (1 << 5),
71 MODE_RECOMPILE = (1 << 8),
72 MODE_TARBUILD = (1 << 11),
73 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE)
74
75 MODE_CHECKSIG = (1 << 6),
76 MODE_RESIGN = (1 << 7),
77 #define MODES_K (MODE_CHECKSIG | MODE_RESIGN)
78
79 MODE_INITDB = (1 << 10),
80 MODE_REBUILDDB = (1 << 12),
81 MODE_VERIFYDB = (1 << 13),
82 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB | MODE_VERIFYDB)
83
84
85 MODE_UNKNOWN = 0
86 };
87
88 #define MODES_FOR_DBPATH (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
89 #define MODES_FOR_NODEPS (MODES_BT | MODES_IE | MODE_VERIFY)
90 #define MODES_FOR_TEST (MODES_BT | MODES_IE)
91 #define MODES_FOR_ROOT (MODES_BT | MODES_IE | MODES_QV | MODES_DB | MODES_K)
92
93 /* the structure describing the options we take and the defaults */
94 /*@unchecked@*/
95 static struct poptOption optionsTable[] = {
96
97 #ifdef IAM_RPMQV
98 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
99 N_("Query options (with -q or --query):"),
100 NULL },
101 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
102 N_("Verify options (with -V or --verify):"),
103 NULL },
104 #ifdef NOTYET
105 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliQVSourcePoptTable, 0,
106 N_("Source options (with --query or --verify):"),
107 NULL },
108 #endif
109 #endif /* IAM_RPMQV */
110
111 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU)
112 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliDepFlagsPoptTable, 0,
113 N_("Dependency check/order options:"),
114 NULL },
115 #endif /* IAM_RPMQV */
116
117 #ifdef IAM_RPMQV
118 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioFtsPoptTable, 0,
119 N_("File tree walk options (with --ftswalk):"),
120 NULL },
121 #endif /* IAM_RPMQV */
122
123 #ifdef IAM_RPMK
124 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0,
125 N_("Signature options:"),
126 NULL },
127 #endif /* IAM_RPMK */
128
129 #ifdef IAM_RPMDB
130 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0,
131 N_("Database options:"),
132 NULL },
133 #endif /* IAM_RPMDB */
134
135 #ifdef IAM_RPMBT
136 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
137 N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
138 NULL },
139 #endif /* IAM_RPMBT */
140
141 #ifdef IAM_RPMEIU
142 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
143 N_("Install/Upgrade/Erase options:"),
144 NULL },
145 #endif /* IAM_RPMEIU */
146
147 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
148 N_("Common options:"),
149 NULL },
150
151 POPT_AUTOALIAS
152 POPT_AUTOHELP
153 POPT_TABLEEND
154 };
155
156 #ifdef __MINT__
157 /* MiNT cannot dynamically increase the stack. */
158 long _stksize = 64 * 1024L;
159 #endif
160
161 /*@exits@*/ static void argerror(const char * desc)
162 /*@globals __assert_program_name, fileSystem @*/
163 /*@modifies fileSystem @*/
164 {
165 fprintf(stderr, _("%s: %s\n"), __progname, desc);
166 exit(EXIT_FAILURE);
167 }
168
169 static void printVersion(FILE * fp)
170 /*@globals rpmEVR, fileSystem @*/
171 /*@modifies *fp, fileSystem @*/
172 {
173 fprintf(fp, "%s (" RPM_NAME ") %s\n", __progname, rpmEVR);
174 if (rpmIsVerbose())
175 fprintf(fp, "rpmlib 0x%08x,0x%08x,0x%08x\n",
176 rpmlibVersion(), rpmlibTimestamp(), rpmlibVendor());
177 }
178
179 static void printUsage(poptContext con, FILE * fp, int flags)
180 /*@globals rpmEVR, fileSystem, internalState @*/
181 /*@modifies *fp, fileSystem, internalState @*/
182 {
183 printVersion(fp);
184 fprintf(fp, "\n");
185
186 if (rpmIsVerbose())
187 poptPrintHelp(con, fp, flags);
188 else
189 poptPrintUsage(con, fp, flags);
190 }
191
192 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */
193
194 #if !defined(RPM_INTEGRITY_FP)
195 #error required RPM_INTEGRITY_FP (fingerprint of public key of integrity authority) not defined!
196 #endif
197
198 enum {
199 INTEGRITY_OK = 0,
200 INTEGRITY_WARNING = 1,
201 INTEGRITY_ERROR = 2
202 };
203
204 static void integrity_check_message(const char *fmt, ...)
205 {
206 va_list ap;
207
208 va_start(ap, fmt);
209 fprintf(stderr, "rpm: ATTENTION: INTEGRITY CHECKING DETECTED AN ENVIRONMENT ANOMALY!\nrpm: ");
210 vfprintf(stderr, fmt, ap);
211 va_end(ap);
212 return;
213 }
214
215 static void integrity_check(const char *progname, enum modes progmode_num)
216 {
217 rpmts ts = NULL;
218 rpmlua lua = NULL;
219 char *spec_fn = NULL;
220 char *proc_fn = NULL;
221 char *pkey_fn = NULL;
222 char *spec = NULL;
223 char *proc = NULL;
224 rpmiob spec_iob = NULL;
225 rpmiob proc_iob = NULL;
226 const char *result = NULL;
227 const char *error = NULL;
228 int xx;
229 const char *progmode;
230 int rc = INTEGRITY_ERROR;
231
232 /* determine paths of integrity checking related files */
233 spec_fn = rpmExpand("%{?_integrity_spec_cfg}%{!?_integrity_spec_cfg:scripts/integrity.cfg}", NULL);
234 if (spec_fn == NULL || spec_fn[0] == '\0') {
235 integrity_check_message("ERROR: Integrity Configuration Specification file not configured.\n"
236 "rpm: HINT: macro %%{_integrity_spec_cfg} not configured correctly.\n");
237 goto failure;
238 }
239 proc_fn = rpmExpand("%{?_integrity_proc_lua}%{!?_integrity_proc_lua:scripts/integrity.lua}", NULL);
240 if (proc_fn == NULL || proc_fn[0] == '\0') {
241 integrity_check_message("ERROR: Integrity Validation Processor file not configured.\n"
242 "rpm: HINT: macro %%{_integrity_proc_lua} not configured correctly.\n");
243 goto failure;
244 }
245 pkey_fn = rpmExpand("%{?_integrity_pkey_pgp}%{!?_integrity_pkey_pgp:scripts/integrity.pgp}", NULL);
246 if (pkey_fn == NULL || pkey_fn[0] == '\0') {
247 integrity_check_message("ERROR: Integrity Autority Public-Key file not configured.\n"
248 "rpm: HINT: macro %%{_integrity_pkey_pgp} not configured correctly.\n");
249 goto failure;
250 }
251
252 /* create RPM transaction environment and open RPM database */
253 ts = rpmtsCreate();
254 (void)rpmtsOpenDB(ts, O_RDONLY);
255
256 /* check signature on integrity configuration specification file */
257 if (rpmnsProbeSignature(ts, spec_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) {
258 integrity_check_message("ERROR: Integrity Configuration Specification file contains invalid signature.\n"
259 "rpm: HINT: Check file \"%s\".\n", spec_fn);
260 goto failure;
261 }
262
263 /* check signature on integrity validation processor file */
264 if (rpmnsProbeSignature(ts, proc_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) {
265 integrity_check_message("ERROR: Integrity Validation Processor file contains invalid signature.\n"
266 "rpm: HINT: Check file \"%s\".\n", proc_fn);
267 goto failure;
268 }
269
270 /* load integrity configuration specification file */
271 xx = rpmiobSlurp(spec_fn, &spec_iob);
272 if (!(xx == 0 && spec_iob != NULL)) {
273 integrity_check_message("ERROR: Unable to load Integrity Configuration Specification file.\n"
274 "rpm: HINT: Check file \"%s\".\n", spec_fn);
275 goto failure;
276 }
277 spec = rpmiobStr(spec_iob);
278
279 /* load integrity validation processor file */
280 xx = rpmiobSlurp(proc_fn, &proc_iob);
281 if (!(xx == 0 && proc_iob != NULL)) {
282 integrity_check_message("ERROR: Unable to load Integrity Validation Processor file.\n"
283 "rpm: HINT: Check file \"%s\".\n", proc_fn);
284 goto failure;
285 }
286 proc = rpmiobStr(proc_iob);
287
288 /* provision program name and mode */
289 if (progname == NULL || progname[0] == '\0')
290 progname = "rpm";
291 switch (progmode_num) {
292 case MODE_QUERY: progmode = "query"; break;
293 case MODE_VERIFY: progmode = "verify"; break;
294 case MODE_CHECKSIG: progmode = "checksig"; break;
295 case MODE_RESIGN: progmode = "resign"; break;
296 case MODE_INSTALL: progmode = "install"; break;
297 case MODE_ERASE: progmode = "erase"; break;
298 case MODE_BUILD: progmode = "build"; break;
299 case MODE_REBUILD: progmode = "rebuild"; break;
300 case MODE_RECOMPILE: progmode = "recompile"; break;
301 case MODE_TARBUILD: progmode = "tarbuild"; break;
302 case MODE_INITDB: progmode = "initdb"; break;
303 case MODE_REBUILDDB: progmode = "rebuilddb"; break;
304 case MODE_VERIFYDB: progmode = "verifydb"; break;
305 case MODE_UNKNOWN: progmode = "unknown"; break;
306 default: progmode = "unknown"; break;
307 }
308
309 /* execute Integrity Validation Processor via Lua glue code */
310 lua = rpmluaNew();
311 rpmluaSetPrintBuffer(lua, 1);
312 rpmluaextActivate(lua);
313 lua_getfield(lua->L, LUA_GLOBALSINDEX, "integrity");
314 lua_getfield(lua->L, -1, "processor");
315 lua_remove(lua->L, -2);
316 lua_pushstring(lua->L, progname);
317 lua_pushstring(lua->L, progmode);
318 lua_pushstring(lua->L, spec_fn);
319 lua_pushstring(lua->L, spec);
320 lua_pushstring(lua->L, proc_fn);
321 lua_pushstring(lua->L, proc);
322 #ifdef RPM_INTEGRITY_MV
323 lua_pushstring(lua->L, RPM_INTEGRITY_MV);
324 #else
325 lua_pushstring(lua->L, "0");
326 #endif
327 if (lua_pcall(lua->L, 7, 1, 0) != 0) {
328 error = lua_isstring(lua->L, -1) ? lua_tostring(lua->L, -1) : "unknown error";
329 lua_pop(lua->L, 1);
330 integrity_check_message("ERROR: Failed to execute Integrity Validation Processor.\n"
331 "rpm: ERROR: Lua: %s.\n"
332 "rpm: HINT: Check file \"%s\".\n", error, proc_fn);
333 goto failure;
334 }
335
336 /* check Integrity Validation Processor results */
337 if (!lua_isstring(lua->L, -1)) {
338 integrity_check_message("ERROR: Failed to fetch Integrity Validation Processor results.\n"
339 "rpm: HINT: Check file \"%s\".\n", proc_fn);
340 goto failure;
341 }
342 result = lua_tostring(lua->L, -1);
343 if (strcmp(result, "OK") == 0)
344 rc = INTEGRITY_OK;
345 else if (strncmp(result, "WARNING:", 8) == 0) {
346 rc = INTEGRITY_WARNING;
347 integrity_check_message("%s\n", result);
348 }
349 else {
350 rc = INTEGRITY_ERROR;
351 integrity_check_message("%s\n", result);
352 }
353
354 /* cleanup processing */
355 failure:
356 if (lua != NULL)
357 rpmluaFree(lua);
358 if (ts != NULL)
359 (void)rpmtsFree(ts);
360 ts = NULL;
361 if (spec_iob != NULL)
362 spec_iob = rpmiobFree(spec_iob);
363 if (proc_iob != NULL)
364 proc_iob = rpmiobFree(proc_iob);
365
366 /* final result handling */
367 if (rc != INTEGRITY_OK) {
368 if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO))
369 sleep(4);
370 if (rc == INTEGRITY_ERROR)
371 exit(42);
372 }
373 return;
374 }
375 #endif
376
377 /*@-bounds@*/ /* LCL: segfault */
378 /*@-mods@*/ /* FIX: shrug */
379 #if !defined(__GLIBC__) && !defined(__LCLINT__)
380 int main(int argc, const char ** argv, /*@unused@*/ char ** envp)
381 #else
382 int main(int argc, const char ** argv)
383 #endif
384 /*@globals rpmEVR, RPMVERSION,
385 rpmGlobalMacroContext, rpmCLIMacroContext,
386 h_errno, fileSystem, internalState@*/
387 /*@modifies fileSystem, internalState@*/
388 {
389 poptContext optCon = rpmcliInit(argc, (char *const *)argv, optionsTable);
390
391 rpmts ts = NULL;
392 enum modes bigMode = MODE_UNKNOWN;
393
394 #if defined(IAM_RPMQV)
395 QVA_t qva = &rpmQVKArgs;
396 #endif
397
398 #ifdef IAM_RPMBT
399 BTA_t ba = &rpmBTArgs;
400 #endif
401
402 #ifdef IAM_RPMEIU
403 QVA_t ia = &rpmIArgs;
404 #endif
405
406 #if defined(IAM_RPMDB)
407 QVA_t da = &rpmDBArgs;
408 #endif
409
410 #if defined(IAM_RPMK)
411 QVA_t ka = &rpmQVKArgs;
412 #endif
413
414 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
415 char * passPhrase = "";
416 #endif
417
418 pid_t pipeChild = 0;
419 int ec = 0;
420 int status;
421 int p[2];
422 #ifdef IAM_RPMEIU
423 int xx;
424 #endif
425
426 #if !defined(__GLIBC__) && !defined(__LCLINT__)
427 environ = envp;
428 #endif
429
430 /* Set the major mode based on argv[0] */
431 /*@-nullpass@*/
432 #ifdef IAM_RPMBT
433 if (!strcmp(__progname, "rpmb")) bigMode = MODE_BUILD;
434 if (!strcmp(__progname, "lt-rpmb")) bigMode = MODE_BUILD;
435 if (!strcmp(__progname, "rpmt")) bigMode = MODE_TARBUILD;
436 if (!strcmp(__progname, "rpmbuild")) bigMode = MODE_BUILD;
437 #endif
438 #ifdef IAM_RPMQV
439 if (!strcmp(__progname, "rpmq")) bigMode = MODE_QUERY;
440 if (!strcmp(__progname, "lt-rpmq")) bigMode = MODE_QUERY;
441 if (!strcmp(__progname, "rpmv")) bigMode = MODE_VERIFY;
442 if (!strcmp(__progname, "rpmquery")) bigMode = MODE_QUERY;
443 if (!strcmp(__progname, "rpmverify")) bigMode = MODE_VERIFY;
444 #endif
445 #ifdef RPMEIU
446 if (!strcmp(__progname, "rpme")) bigMode = MODE_ERASE;
447 if (!strcmp(__progname, "rpmi")) bigMode = MODE_INSTALL;
448 if (!strcmp(__progname, "lt-rpmi")) bigMode = MODE_INSTALL;
449 if (!strcmp(__progname, "rpmu")) bigMode = MODE_INSTALL;
450 #endif
451 /*@=nullpass@*/
452
453 #if defined(IAM_RPMQV)
454 /* Jumpstart option from argv[0] if necessary. */
455 switch (bigMode) {
456 case MODE_QUERY: qva->qva_mode = 'q'; break;
457 case MODE_VERIFY: qva->qva_mode = 'V'; break;
458 case MODE_CHECKSIG: qva->qva_mode = 'K'; break;
459 case MODE_RESIGN: qva->qva_mode = 'R'; break;
460 case MODE_INSTALL:
461 case MODE_ERASE:
462 case MODE_BUILD:
463 case MODE_REBUILD:
464 case MODE_RECOMPILE:
465 case MODE_TARBUILD:
466 case MODE_INITDB:
467 case MODE_REBUILDDB:
468 case MODE_VERIFYDB:
469 case MODE_UNKNOWN:
470 default:
471 break;
472 }
473 #endif
474
475 rpmcliConfigured();
476
477 #ifdef IAM_RPMBT
478 switch (ba->buildMode) {
479 case 'b': bigMode = MODE_BUILD; break;
480 case 't': bigMode = MODE_TARBUILD; break;
481 case 'B': bigMode = MODE_REBUILD; break;
482 case 'C': bigMode = MODE_RECOMPILE; break;
483 }
484
485 if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
486 bigMode = MODE_BUILD;
487
488 if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
489 bigMode = MODE_BUILD;
490 #endif /* IAM_RPMBT */
491
492 #ifdef IAM_RPMDB
493 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
494 if (da->init) {
495 if (bigMode != MODE_UNKNOWN)
496 argerror(_("only one major mode may be specified"));
497 else
498 bigMode = MODE_INITDB;
499 } else
500 if (da->rebuild) {
501 if (bigMode != MODE_UNKNOWN)
502 argerror(_("only one major mode may be specified"));
503 else
504 bigMode = MODE_REBUILDDB;
505 } else
506 if (da->verify) {
507 if (bigMode != MODE_UNKNOWN)
508 argerror(_("only one major mode may be specified"));
509 else
510 bigMode = MODE_VERIFYDB;
511 }
512 }
513 #endif /* IAM_RPMDB */
514
515 #ifdef IAM_RPMQV
516 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
517 switch (qva->qva_mode) {
518 case 'q': bigMode = MODE_QUERY; break;
519 case 'V': bigMode = MODE_VERIFY; break;
520 }
521
522 if (qva->qva_sourceCount) {
523 if (qva->qva_sourceCount > 2)
524 argerror(_("one type of query/verify may be performed at a "
525 "time"));
526 }
527 if (qva->qva_flags && (bigMode & ~MODES_QV))
528 argerror(_("unexpected query flags"));
529
530 if (qva->qva_queryFormat && (bigMode & ~MODES_QV))
531 argerror(_("unexpected query format"));
532
533 if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV))
534 argerror(_("unexpected query source"));
535 }
536 #endif /* IAM_RPMQV */
537
538 #ifdef IAM_RPMEIU
539 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
540 { int iflags = (ia->installInterfaceFlags &
541 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
542 int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
543
544 if (iflags & eflags)
545 argerror(_("only one major mode may be specified"));
546 else if (iflags)
547 bigMode = MODE_INSTALL;
548 else if (eflags)
549 bigMode = MODE_ERASE;
550 }
551 #endif /* IAM_RPMEIU */
552
553 #ifdef IAM_RPMK
554 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
555 switch (ka->qva_mode) {
556 case RPMSIGN_NONE:
557 ka->sign = 0;
558 break;
559 case RPMSIGN_IMPORT_PUBKEY:
560 case RPMSIGN_CHK_SIGNATURE:
561 bigMode = MODE_CHECKSIG;
562 ka->sign = 0;
563 break;
564 case RPMSIGN_ADD_SIGNATURE:
565 case RPMSIGN_NEW_SIGNATURE:
566 case RPMSIGN_DEL_SIGNATURE:
567 bigMode = MODE_RESIGN;
568 ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE);
569 break;
570 }
571 }
572 #endif /* IAM_RPMK */
573
574 #if defined(IAM_RPMEIU)
575 if (!( bigMode == MODE_INSTALL ) &&
576 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
577 argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
578 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
579 argerror(_("files may only be relocated during package installation"));
580
581 if (ia->relocations && ia->qva_prefix)
582 argerror(_("cannot use --prefix with --relocate or --excludepath"));
583
584 if (bigMode != MODE_INSTALL && ia->relocations)
585 argerror(_("--relocate and --excludepath may only be used when installing new packages"));
586
587 if (bigMode != MODE_INSTALL && ia->qva_prefix)
588 argerror(_("--prefix may only be used when installing new packages"));
589
590 if (ia->qva_prefix && ia->qva_prefix[0] != '/')
591 argerror(_("arguments to --prefix must begin with a /"));
592
593 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
594 argerror(_("--hash (-h) may only be specified during package "
595 "installation"));
596
597 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
598 argerror(_("--percent may only be specified during package "
599 "installation"));
600
601 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
602 argerror(_("--replacepkgs may only be specified during package "
603 "installation"));
604
605 if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
606 argerror(_("--excludedocs may only be specified during package "
607 "installation"));
608
609 if (bigMode != MODE_INSTALL && ia->incldocs)
610 argerror(_("--includedocs may only be specified during package "
611 "installation"));
612
613 if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
614 argerror(_("only one of --excludedocs and --includedocs may be "
615 "specified"));
616
617 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
618 argerror(_("--ignorearch may only be specified during package "
619 "installation"));
620
621 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
622 argerror(_("--ignoreos may only be specified during package "
623 "installation"));
624
625 if ((ia->installInterfaceFlags & INSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
626 argerror(_("--allmatches may only be specified during package "
627 "erasure"));
628
629 if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
630 argerror(_("--allfiles may only be specified during package "
631 "installation"));
632
633 if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
634 bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
635 argerror(_("--justdb may only be specified during package "
636 "installation and erasure"));
637
638 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
639 (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
640 argerror(_("script disabling options may only be specified during "
641 "package installation and erasure"));
642
643 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
644 (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
645 argerror(_("trigger disabling options may only be specified during "
646 "package installation and erasure"));
647
648 if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
649 argerror(_("--nodeps may only be specified during package "
650 "building, rebuilding, recompilation, installation, "
651 "erasure, and verification"));
652
653 if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
654 argerror(_("--test may only be specified during package installation, "
655 "erasure, and building"));
656 #endif /* IAM_RPMEIU */
657
658 if (rpmioRootDir && rpmioRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
659 argerror(_("--root (-r) may only be specified during "
660 "installation, erasure, querying, and "
661 "database rebuilds"));
662
663 if (rpmioRootDir) {
664 switch (urlIsURL(rpmioRootDir)) {
665 default:
666 if (bigMode & MODES_FOR_ROOT)
667 break;
668 /*@fallthrough@*/
669 case URL_IS_UNKNOWN:
670 if (rpmioRootDir[0] != '/')
671 argerror(_("arguments to --root (-r) must begin with a /"));
672 break;
673 }
674 }
675
676 #if defined(RPM_VENDOR_OPENPKG) /* integrity-checking */
677 integrity_check(__progname, bigMode);
678 #endif
679
680 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
681 if (0
682 #if defined(IAM_RPMBT)
683 || ba->sign
684 #endif
685 #if defined(IAM_RPMK)
686 || ka->sign
687 #endif
688 )
689 /*@-branchstate@*/
690 {
691 if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
692 bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD)
693 {
694 const char ** av;
695 struct stat sb;
696 int errors = 0;
697
698 if ((av = poptGetArgs(optCon)) == NULL) {
699 fprintf(stderr, _("no files to sign\n"));
700 errors++;
701 } else
702 while (*av) {
703 if (Stat(*av, &sb)) {
704 fprintf(stderr, _("cannot access file %s\n"), *av);
705 errors++;
706 }
707 av++;
708 }
709
710 if (errors) {
711 ec = errors;
712 goto exit;
713 }
714
715 if (poptPeekArg(optCon)
716 #if defined(IAM_RPMBT)
717 && !ba->nopassword
718 #endif
719 #if defined(IAM_RPMK)
720 && !ka->nopassword
721 #endif
722 )
723 {
724 passPhrase = Getpass(_("Enter pass phrase: "));
725 if (rpmCheckPassPhrase(passPhrase)) {
726 fprintf(stderr, _("Pass phrase check failed\n"));
727 ec = EXIT_FAILURE;
728 goto exit;
729 }
730 fprintf(stderr, _("Pass phrase is good.\n"));
731 /* XXX Getpass() should realloc instead. */
732 passPhrase = xstrdup(passPhrase);
733 }
734 }
735 }
736 /*@=branchstate@*/
737 #endif /* IAM_RPMBT || IAM_RPMK */
738
739 if (rpmioPipeOutput) {
740 if (pipe(p) < 0) {
741 fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
742 goto exit;
743 }
744
745 if (!(pipeChild = fork())) {
746 (void) close(p[1]);
747 (void) dup2(p[0], STDIN_FILENO);
748 (void) close(p[0]);
749 (void) execl("/bin/sh", "/bin/sh", "-c", rpmioPipeOutput, NULL);
750 fprintf(stderr, _("exec failed\n"));
751 }
752
753 (void) close(p[0]);
754 (void) dup2(p[1], STDOUT_FILENO);
755 (void) close(p[1]);
756 }
757
758 ts = rpmtsCreate();
759 (void) rpmtsSetRootDir(ts, rpmioRootDir);
760 switch (bigMode) {
761 #ifdef IAM_RPMDB
762 case MODE_INITDB:
763 #if defined(SUPPORT_INITDB)
764 ec = rpmtsInitDB(ts, 0644);
765 #else
766 ec = -1;
767 #endif
768 break;
769
770 case MODE_REBUILDDB:
771 { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
772 rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
773 ec = rpmtsRebuildDB(ts);
774 vsflags = rpmtsSetVSFlags(ts, ovsflags);
775 } break;
776 case MODE_VERIFYDB:
777 #if defined(SUPPORT_VERIFYDB)
778 ec = rpmtsVerifyDB(ts);
779 #else
780 ec = -1;
781 #endif
782 break;
783 #endif /* IAM_RPMDB */
784
785 #ifdef IAM_RPMBT
786 case MODE_REBUILD:
787 case MODE_RECOMPILE:
788 { const char * pkg;
789 int nbuilds = 0;
790
791 while (!rpmIsVerbose())
792 rpmIncreaseVerbosity();
793
794 if (!poptPeekArg(optCon))
795 argerror(_("no packages files given for rebuild"));
796
797 ba->buildAmount =
798 RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
799 if (bigMode == MODE_REBUILD) {
800 ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
801 ba->buildAmount |= RPMBUILD_RMSOURCE;
802 ba->buildAmount |= RPMBUILD_RMSPEC;
803 ba->buildAmount |= RPMBUILD_CLEAN;
804 ba->buildAmount |= RPMBUILD_RMBUILD;
805 }
806
807 while ((pkg = poptGetArg(optCon))) {
808 const char * specFile = NULL;
809
810 if (nbuilds++ > 0) {
811 rpmFreeMacros(NULL);
812 rpmFreeRpmrc();
813 (void) rpmReadConfigFiles(NULL, NULL);
814 }
815 ba->cookie = NULL;
816 ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
817 if (ec == 0) {
818 ba->rootdir = rpmioRootDir;
819 ba->passPhrase = passPhrase;
820 ec = build(ts, specFile, ba, NULL);
821 }
822 ba->cookie = _free(ba->cookie);
823 specFile = _free(specFile);
824
825 if (ec)
826 /*@loopbreak@*/ break;
827 }
828
829 } break;
830
831 case MODE_BUILD:
832 case MODE_TARBUILD:
833 { const char * pkg;
834 int nbuilds = 0;
835
836 #if defined(RPM_VENDOR_OPENPKG) /* no-auto-verbose-increase-for-track-and-fetch */
837 if (ba->buildChar != 't' && ba->buildChar != 'f')
838 #endif
839 while (!rpmIsVerbose())
840 rpmIncreaseVerbosity();
841
842 switch (ba->buildChar) {
843 case 'a':
844 ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
845 /*@fallthrough@*/
846 case 'b':
847 ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
848 ba->buildAmount |= RPMBUILD_CLEAN;
849 if ((ba->buildChar == 'b') && ba->shortCircuit)
850 /*@innerbreak@*/ break;
851 /*@fallthrough@*/
852 case 'i':
853 ba->buildAmount |= RPMBUILD_INSTALL;
854 ba->buildAmount |= RPMBUILD_CHECK;
855 if ((ba->buildChar == 'i') && ba->shortCircuit)
856 /*@innerbreak@*/ break;
857 /*@fallthrough@*/
858 case 'c':
859 ba->buildAmount |= RPMBUILD_BUILD;
860 if ((ba->buildChar == 'c') && ba->shortCircuit)
861 /*@innerbreak@*/ break;
862 /*@fallthrough@*/
863 case 'p':
864 ba->buildAmount |= RPMBUILD_PREP;
865 /*@innerbreak@*/ break;
866
867 case 'l':
868 ba->buildAmount |= RPMBUILD_FILECHECK;
869 /*@innerbreak@*/ break;
870 case 's':
871 ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
872 #if defined(RPM_VENDOR_OPENPKG) || defined(RPM_VENDOR_MANDRIVA) || defined(RPM_VENDOR_ARK) /* no-deps-on-building-srpms */
873 /* enforce no dependency checking when rolling a source RPM */
874 ba->noDeps = 1;
875 #endif
876 /*@innerbreak@*/ break;
877 case 't': /* support extracting the "%track" script/section */
878 ba->buildAmount |= RPMBUILD_TRACK;
879 /* enforce no dependency checking and expansion of %setup, %patch and %prep macros */
880 ba->noDeps = 1;
881 rpmDefineMacro(NULL, "setup #", RMIL_CMDLINE);
882 rpmDefineMacro(NULL, "patch #", RMIL_CMDLINE);
883 rpmDefineMacro(NULL, "prep %%prep", RMIL_CMDLINE);
884 /*@innerbreak@*/ break;
885 case 'f':
886 ba->buildAmount |= RPMBUILD_FETCHSOURCE;
887 ba->noDeps = 1;
888 /*@innerbreak@*/ break;
889 }
890
891 if (!poptPeekArg(optCon)) {
892 if (bigMode == MODE_BUILD)
893 argerror(_("no spec files given for build"));
894 else
895 argerror(_("no tar files given for build"));
896 }
897
898 while ((pkg = poptGetArg(optCon))) {
899 if (nbuilds++ > 0) {
900 rpmFreeMacros(NULL);
901 rpmFreeRpmrc();
902 (void) rpmReadConfigFiles(NULL, NULL);
903 }
904 ba->rootdir = rpmioRootDir;
905 ba->passPhrase = passPhrase;
906 ba->cookie = NULL;
907 ec = build(ts, pkg, ba, NULL);
908 if (ec)
909 /*@loopbreak@*/ break;
910 }
911 } break;
912 #endif /* IAM_RPMBT */
913
914 #ifdef IAM_RPMEIU
915 case MODE_ERASE:
916 ia->depFlags = global_depFlags;
917 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
918
919 if (!poptPeekArg(optCon)) {
920 if (ia->rbtid == 0)
921 argerror(_("no packages given for erase"));
922 ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
923 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
924 ia->rbCheck = rpmcliInstallCheck;
925 ia->rbOrder = rpmcliInstallOrder;
926 ia->rbRun = rpmcliInstallRun;
927 ec += rpmRollback(ts, ia, NULL);
928 } else {
929 ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon));
930 }
931 break;
932
933 case MODE_INSTALL:
934
935 /* RPMTRANS_FLAG_KEEPOBSOLETE */
936
937 ia->depFlags = global_depFlags;
938 if (!ia->incldocs) {
939 if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
940 ;
941 } else if (rpmExpandNumeric("%{_excludedocs}"))
942 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
943 }
944
945 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
946
947 /* we've already ensured !(!ia->prefix && !ia->relocations) */
948 /*@-branchstate@*/
949 if (ia->qva_prefix) {
950 xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
951 NULL, ia->qva_prefix);
952 xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
953 NULL, NULL);
954 } else if (ia->relocations) {
955 xx = rpmfiAddRelocation(&ia->relocations, &ia->nrelocations,
956 NULL, NULL);
957 }
958 /*@=branchstate@*/
959
960 if (!poptPeekArg(optCon)) {
961 if (ia->rbtid == 0)
962 argerror(_("no packages given for install"));
963 ia->transFlags |= RPMTRANS_FLAG_NOFDIGESTS;
964 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
965 ia->rbCheck = rpmcliInstallCheck;
966 ia->rbOrder = rpmcliInstallOrder;
967 ia->rbRun = rpmcliInstallRun;
968 /*@i@*/ ec += rpmRollback(ts, ia, NULL);
969 } else {
970 /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */
971 ec += rpmcliInstall(ts, ia, (const char **)poptGetArgs(optCon));
972 /*@=compdef =compmempass@*/
973 }
974 break;
975
976 #endif /* IAM_RPMEIU */
977
978 #ifdef IAM_RPMQV
979 case MODE_QUERY:
980 if (!poptPeekArg(optCon)
981 && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST))
982 argerror(_("no arguments given for query"));
983
984 qva->depFlags = global_depFlags;
985 qva->qva_specQuery = rpmspecQuery;
986 ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon));
987 qva->qva_specQuery = NULL;
988 break;
989
990 case MODE_VERIFY:
991 { rpmVerifyFlags verifyFlags = VERIFY_ALL;
992
993 qva->depFlags = global_depFlags;
994 verifyFlags &= ~qva->qva_flags;
995 qva->qva_flags = (rpmQueryFlags) verifyFlags;
996
997 if (!poptPeekArg(optCon)
998 && !(qva->qva_source == RPMQV_ALL || qva->qva_source == RPMQV_HDLIST))
999 argerror(_("no arguments given for verify"));
1000 ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon));
1001 } break;
1002 #endif /* IAM_RPMQV */
1003
1004 #ifdef IAM_RPMK
1005 case MODE_CHECKSIG:
1006 { rpmVerifyFlags verifyFlags =
1007 (VERIFY_FDIGEST|VERIFY_HDRCHK|VERIFY_DIGEST|VERIFY_SIGNATURE);
1008
1009 verifyFlags &= ~ka->qva_flags;
1010 ka->qva_flags = (rpmQueryFlags) verifyFlags;
1011 } /*@fallthrough@*/
1012 case MODE_RESIGN:
1013 if (!poptPeekArg(optCon))
1014 argerror(_("no arguments given"));
1015 ka->passPhrase = passPhrase;
1016 ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon));
1017 break;
1018 #endif /* IAM_RPMK */
1019
1020 #if !defined(IAM_RPMQV)
1021 case MODE_QUERY:
1022 case MODE_VERIFY:
1023 #endif
1024 #if !defined(IAM_RPMK)
1025 case MODE_CHECKSIG:
1026 case MODE_RESIGN:
1027 #endif
1028 #if !defined(IAM_RPMDB)
1029 case MODE_INITDB:
1030 case MODE_REBUILDDB:
1031 case MODE_VERIFYDB:
1032 #endif
1033 #if !defined(IAM_RPMBT)
1034 case MODE_BUILD:
1035 case MODE_REBUILD:
1036 case MODE_RECOMPILE:
1037 case MODE_TARBUILD:
1038 #endif
1039 #if !defined(IAM_RPMEIU)
1040 case MODE_INSTALL:
1041 case MODE_ERASE:
1042 #endif
1043 case MODE_UNKNOWN:
1044 if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
1045 printUsage(optCon, stderr, 0);
1046 ec = argc;
1047 }
1048 break;
1049 }
1050
1051 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
1052 exit:
1053 #endif /* IAM_RPMBT || IAM_RPMK */
1054
1055 (void)rpmtsFree(ts);
1056 ts = NULL;
1057
1058 if (pipeChild) {
1059 (void) fclose(stdout);
1060 (void) waitpid(pipeChild, &status, 0);
1061 }
1062
1063 #ifdef IAM_RPMQV
1064 qva->qva_queryFormat = _free(qva->qva_queryFormat);
1065 #endif
1066
1067 #ifdef IAM_RPMBT
1068 freeNames();
1069 #endif
1070
1071 #ifdef IAM_RPMEIU
1072 ia->relocations = rpmfiFreeRelocations(ia->relocations);
1073 #endif
1074
1075 optCon = rpmcliFini(optCon);
1076
1077 /* XXX don't overflow single byte exit status */
1078 /* XXX status 255 is special to xargs(1) */
1079 if (ec > 254) ec = 254;
1080
1081 /*@-globstate@*/
1082 return ec;
1083 /*@=globstate@*/
1084 }
1085 /*@=mods@*/
1086 /*@=bounds@*/