2 const char *__progname;
4 #include <rpm/rpmcli.h>
5 #include <rpm/rpmlib.h> /* RPMSIGTAG, rpmReadPackageFile .. */
6 #include <rpm/rpmbuild.h>
7 #include <rpm/rpmlog.h>
10 #include <rpm/rpmts.h>
13 #include "lib/signature.h"
21 MODE_QUERY = (1 << 0),
22 MODE_VERIFY = (1 << 3),
23 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
25 MODE_INSTALL = (1 << 1),
26 MODE_ERASE = (1 << 2),
27 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
29 MODE_CHECKSIG = (1 << 6),
30 MODE_RESIGN = (1 << 7),
31 MODE_KEYRING = (1 << 8),
32 #define MODES_K (MODE_CHECKSIG | MODE_RESIGN | MODE_KEYRING)
34 MODE_INITDB = (1 << 10),
35 MODE_REBUILDDB = (1 << 12),
36 MODE_VERIFYDB = (1 << 13),
37 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB | MODE_VERIFYDB)
43 #define MODES_FOR_DBPATH (MODES_IE | MODES_QV | MODES_DB)
44 #define MODES_FOR_NODEPS (MODES_IE | MODE_VERIFY)
45 #define MODES_FOR_TEST (MODES_IE)
46 #define MODES_FOR_ROOT (MODES_IE | MODES_QV | MODES_DB | MODES_K)
50 /* the structure describing the options we take and the defaults */
51 static struct poptOption optionsTable[] = {
54 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
55 N_("Query/Verify package selection options:"),
57 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
58 N_("Query options (with -q or --query):"),
60 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
61 N_("Verify options (with -V or --verify):"),
63 #endif /* IAM_RPMQV */
66 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0,
67 N_("Signature options:"),
72 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0,
73 N_("Database options:"),
75 #endif /* IAM_RPMDB */
78 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
79 N_("Install/Upgrade/Erase options:"),
81 #endif /* IAM_RPMEIU */
83 { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
85 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
86 N_("Common options for all rpm modes and executables:"),
94 int main(int argc, char *argv[])
97 enum modes bigMode = MODE_UNKNOWN;
99 #if defined(IAM_RPMQV)
100 QVA_t qva = &rpmQVKArgs;
104 struct rpmInstallArguments_s * ia = &rpmIArgs;
107 #if defined(IAM_RPMDB)
108 struct rpmDatabaseArguments_s * da = &rpmDBArgs;
111 #if defined(IAM_RPMK)
112 QVA_t ka = &rpmQVKArgs;
115 #if defined(IAM_RPMK)
116 char * passPhrase = "";
125 optCon = rpmcliInit(argc, argv, optionsTable);
127 /* Set the major mode based on argv[0] */
129 if (rstreq(__progname, "rpmquery")) bigMode = MODE_QUERY;
130 if (rstreq(__progname, "rpmverify")) bigMode = MODE_VERIFY;
133 #if defined(IAM_RPMQV)
134 /* Jumpstart option from argv[0] if necessary. */
136 case MODE_QUERY: qva->qva_mode = 'q'; break;
137 case MODE_VERIFY: qva->qva_mode = 'V'; break;
138 case MODE_CHECKSIG: qva->qva_mode = 'K'; break;
139 case MODE_RESIGN: qva->qva_mode = 'R'; break;
152 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
154 if (bigMode != MODE_UNKNOWN)
155 argerror(_("only one major mode may be specified"));
157 bigMode = MODE_INITDB;
160 if (bigMode != MODE_UNKNOWN)
161 argerror(_("only one major mode may be specified"));
163 bigMode = MODE_REBUILDDB;
166 if (bigMode != MODE_UNKNOWN)
167 argerror(_("only one major mode may be specified"));
169 bigMode = MODE_VERIFYDB;
172 #endif /* IAM_RPMDB */
175 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
176 switch (qva->qva_mode) {
177 case 'q': bigMode = MODE_QUERY; break;
178 case 'V': bigMode = MODE_VERIFY; break;
181 if (qva->qva_sourceCount) {
182 if (qva->qva_sourceCount > 2)
183 argerror(_("one type of query/verify may be performed at a "
186 if (qva->qva_flags && (bigMode & ~MODES_QV))
187 argerror(_("unexpected query flags"));
189 if (qva->qva_queryFormat && (bigMode & ~MODES_QV))
190 argerror(_("unexpected query format"));
192 if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV))
193 argerror(_("unexpected query source"));
195 #endif /* IAM_RPMQV */
198 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
199 { int iflags = (ia->installInterfaceFlags &
200 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
201 int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
204 argerror(_("only one major mode may be specified"));
206 bigMode = MODE_INSTALL;
208 bigMode = MODE_ERASE;
210 #endif /* IAM_RPMEIU */
213 if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
214 switch (ka->qva_mode) {
215 case RPMSIGN_IMPORT_PUBKEY:
216 bigMode = MODE_KEYRING;
218 case RPMSIGN_CHK_SIGNATURE:
219 bigMode = MODE_CHECKSIG;
221 case RPMSIGN_ADD_SIGNATURE:
222 case RPMSIGN_NEW_SIGNATURE:
225 case RPMSIGN_DEL_SIGNATURE:
226 bigMode = MODE_RESIGN;
230 #endif /* IAM_RPMK */
232 #if defined(IAM_RPMEIU)
233 if (!( bigMode == MODE_INSTALL ) &&
234 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
235 argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
236 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
237 argerror(_("files may only be relocated during package installation"));
239 if (ia->relocations && ia->prefix)
240 argerror(_("cannot use --prefix with --relocate or --excludepath"));
242 if (bigMode != MODE_INSTALL && ia->relocations)
243 argerror(_("--relocate and --excludepath may only be used when installing new packages"));
245 if (bigMode != MODE_INSTALL && ia->prefix)
246 argerror(_("--prefix may only be used when installing new packages"));
248 if (ia->prefix && ia->prefix[0] != '/')
249 argerror(_("arguments to --prefix must begin with a /"));
251 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
252 argerror(_("--hash (-h) may only be specified during package "
255 if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
256 argerror(_("--percent may only be specified during package "
259 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
260 argerror(_("--replacepkgs may only be specified during package "
263 if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
264 argerror(_("--excludedocs may only be specified during package "
267 if (bigMode != MODE_INSTALL && ia->incldocs)
268 argerror(_("--includedocs may only be specified during package "
271 if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
272 argerror(_("only one of --excludedocs and --includedocs may be "
275 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
276 argerror(_("--ignorearch may only be specified during package "
279 if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
280 argerror(_("--ignoreos may only be specified during package "
283 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
284 (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
285 argerror(_("--ignoresize may only be specified during package "
288 if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
289 argerror(_("--allmatches may only be specified during package "
292 if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
293 argerror(_("--allfiles may only be specified during package "
296 if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
297 bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
298 argerror(_("--justdb may only be specified during package "
299 "installation and erasure"));
301 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
302 (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
303 argerror(_("script disabling options may only be specified during "
304 "package installation and erasure"));
306 if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
307 (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
308 argerror(_("trigger disabling options may only be specified during "
309 "package installation and erasure"));
311 if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
312 argerror(_("--nodeps may only be specified during package "
313 "building, rebuilding, recompilation, installation,"
314 "erasure, and verification"));
316 if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
317 argerror(_("--test may only be specified during package installation, "
318 "erasure, and building"));
319 #endif /* IAM_RPMEIU */
321 if (rpmcliRootDir && rpmcliRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
322 argerror(_("--root (-r) may only be specified during "
323 "installation, erasure, querying, and "
324 "database rebuilds"));
326 if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
327 argerror(_("arguments to --root (-r) must begin with a /"));
331 rpmSetVerbosity(RPMLOG_WARNING);
333 #if defined(IAM_RPMK)
335 if (bigMode == MODE_RESIGN) {
340 if ((av = poptGetArgs(optCon)) == NULL) {
341 fprintf(stderr, _("no files to sign\n"));
345 if (stat(*av, &sb)) {
346 fprintf(stderr, _("cannot access file %s\n"), *av);
357 if (poptPeekArg(optCon)) {
358 int sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY);
366 passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
367 if (passPhrase == NULL) {
368 fprintf(stderr, _("Pass phrase check failed\n"));
372 fprintf(stderr, _("Pass phrase is good.\n"));
373 passPhrase = xstrdup(passPhrase);
377 _("Invalid %%_signature spec in macro file.\n"));
384 argerror(_("--sign may only be used during package building"));
387 /* Make rpmLookupSignatureType() return 0 ("none") from now on */
388 (void) rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
390 #endif /* IAM_RPMK */
392 if (rpmcliPipeOutput && initPipe())
396 (void) rpmtsSetRootDir(ts, rpmcliRootDir);
400 ec = rpmtsInitDB(ts, 0644);
404 { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
405 rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
406 ec = rpmtsRebuildDB(ts);
407 vsflags = rpmtsSetVSFlags(ts, ovsflags);
410 ec = rpmtsVerifyDB(ts);
412 #endif /* IAM_RPMDB */
416 if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
418 if (!poptPeekArg(optCon)) {
419 argerror(_("no packages given for erase"));
421 ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
427 /* RPMTRANS_FLAG_KEEPOBSOLETE */
430 if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
432 } else if (rpmExpandNumeric("%{_excludedocs}"))
433 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
436 if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
438 /* we've already ensured !(!ia->prefix && !ia->relocations) */
440 ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
441 ia->relocations[0].oldPath = NULL; /* special case magic */
442 ia->relocations[0].newPath = ia->prefix;
443 ia->relocations[1].oldPath = NULL;
444 ia->relocations[1].newPath = NULL;
445 } else if (ia->relocations) {
446 ia->relocations = xrealloc(ia->relocations,
447 sizeof(*ia->relocations) * (ia->numRelocations + 1));
448 ia->relocations[ia->numRelocations].oldPath = NULL;
449 ia->relocations[ia->numRelocations].newPath = NULL;
452 if (!poptPeekArg(optCon)) {
453 argerror(_("no packages given for install"));
455 /* FIX: ia->relocations[0].newPath undefined */
456 ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
460 #endif /* IAM_RPMEIU */
464 if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
465 argerror(_("no arguments given for query"));
467 qva->qva_specQuery = rpmspecQuery;
468 ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
469 qva->qva_specQuery = NULL;
473 { rpmVerifyFlags verifyFlags = VERIFY_ALL;
475 verifyFlags &= ~qva->qva_flags;
476 qva->qva_flags = (rpmQueryFlags) verifyFlags;
478 if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
479 argerror(_("no arguments given for verify"));
480 ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
482 #endif /* IAM_RPMQV */
486 if (!poptPeekArg(optCon))
487 argerror(_("no arguments given"));
488 ec = rpmcliImportPubkeys(ts, (ARGV_const_t) poptGetArgs(optCon));
491 { rpmVerifyFlags verifyFlags =
492 (VERIFY_FILEDIGEST|VERIFY_DIGEST|VERIFY_SIGNATURE);
494 verifyFlags &= ~rpmcliQueryFlags;
495 ka->qva_flags = (rpmQueryFlags) verifyFlags;
496 ec = rpmcliVerifySignatures(ts, ka, (ARGV_const_t) poptGetArgs(optCon));
500 if (!poptPeekArg(optCon))
501 argerror(_("no arguments given"));
502 ec = rpmcliSign((ARGV_const_t) poptGetArgs(optCon),
503 (qva->qva_mode == RPMSIGN_DEL_SIGNATURE), passPhrase);
505 #endif /* IAM_RPMK */
507 #if !defined(IAM_RPMQV)
511 #if !defined(IAM_RPMK)
515 #if !defined(IAM_RPMDB)
520 #if !defined(IAM_RPMEIU)
525 if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
526 printUsage(optCon, stderr, 0);
537 qva->qva_queryFormat = _free(qva->qva_queryFormat);
541 if (ia->relocations != NULL)
542 for (i = 0; i < ia->numRelocations; i++)
543 ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
544 ia->relocations = _free(ia->relocations);