rpm  5.2.1
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),
83 
84 
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",
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 
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 &
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;
561  bigMode = MODE_CHECKSIG;
562  ka->sign = 0;
563  break;
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 ) &&
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 &&
640  argerror(_("script disabling options may only be specified during "
641  "package installation and erasure"));
642 
643  if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
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())
793 
794  if (!poptPeekArg(optCon))
795  argerror(_("no packages files given for rebuild"));
796 
797  ba->buildAmount =
799  if (bigMode == MODE_REBUILD) {
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())
841 
842  switch (ba->buildChar) {
843  case 'a':
845  /*@fallthrough@*/
846  case 'b':
849  if ((ba->buildChar == 'b') && ba->shortCircuit)
850  /*@innerbreak@*/ break;
851  /*@fallthrough@*/
852  case 'i':
855  if ((ba->buildChar == 'i') && ba->shortCircuit)
856  /*@innerbreak@*/ break;
857  /*@fallthrough@*/
858  case 'c':
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':
869  /*@innerbreak@*/ break;
870  case 's':
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 */
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':
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:
918 
919  if (!poptPeekArg(optCon)) {
920  if (ia->rbtid == 0)
921  argerror(_("no packages given for erase"));
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 
938  if (!ia->incldocs) {
939  if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
940  ;
941  } else if (rpmExpandNumeric("%{_excludedocs}"))
943  }
944 
946 
947  /* we've already ensured !(!ia->prefix && !ia->relocations) */
948  /*@-branchstate@*/
949  if (ia->qva_prefix) {
951  NULL, ia->qva_prefix);
953  NULL, NULL);
954  } else if (ia->relocations) {
956  NULL, NULL);
957  }
958  /*@=branchstate@*/
959 
960  if (!poptPeekArg(optCon)) {
961  if (ia->rbtid == 0)
962  argerror(_("no packages given for install"));
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;
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 =
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
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@*/