4032b9212a95bc8b2bf47e96ff0d7bd6bc347936
[platform/upstream/rpm.git] / rpmqv.c
1 #include "system.h"
2 const char *__progname;
3
4 #define _AUTOHELP
5
6 #include <sys/wait.h>
7 #if HAVE_MCHECK_H
8 #include <mcheck.h>
9 #endif
10
11 #include <rpm/rpmcli.h>
12 #include <rpm/rpmlib.h>                 /* RPMSIGTAG, rpmReadPackageFile .. */
13 #include <rpm/rpmbuild.h>
14 #include <rpm/rpmlog.h>
15 #include <rpm/rpmfileutil.h>
16 #include <rpm/rpmdb.h>
17 #include <rpm/rpmps.h>
18 #include <rpm/rpmts.h>
19
20 #if defined(IAM_RPMK)
21 #include "lib/signature.h"
22 #endif
23
24 #include "debug.h"
25
26 enum modes {
27
28     MODE_QUERY          = (1 <<  0),
29     MODE_VERIFY         = (1 <<  3),
30 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
31
32     MODE_INSTALL        = (1 <<  1),
33     MODE_ERASE          = (1 <<  2),
34 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
35
36     MODE_CHECKSIG       = (1 <<  6),
37     MODE_RESIGN         = (1 <<  7),
38 #define MODES_K  (MODE_CHECKSIG | MODE_RESIGN)
39
40     MODE_INITDB         = (1 << 10),
41     MODE_REBUILDDB      = (1 << 12),
42     MODE_VERIFYDB       = (1 << 13),
43 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB | MODE_VERIFYDB)
44
45
46     MODE_UNKNOWN        = 0
47 };
48
49 #define MODES_FOR_DBPATH        (MODES_IE | MODES_QV | MODES_DB)
50 #define MODES_FOR_NODEPS        (MODES_IE | MODE_VERIFY)
51 #define MODES_FOR_TEST          (MODES_IE)
52 #define MODES_FOR_ROOT          (MODES_IE | MODES_QV | MODES_DB | MODES_K)
53
54 static int quiet;
55
56 /* the structure describing the options we take and the defaults */
57 static struct poptOption optionsTable[] = {
58
59 #ifdef  IAM_RPMQV
60  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
61         N_("Query/Verify package selection options:"),
62         NULL },
63  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
64         N_("Query options (with -q or --query):"),
65         NULL },
66  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
67         N_("Verify options (with -V or --verify):"),
68         NULL },
69 #endif  /* IAM_RPMQV */
70
71 #ifdef  IAM_RPMK
72  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0,
73         N_("Signature options:"),
74         NULL },
75 #endif  /* IAM_RPMK */
76
77 #ifdef  IAM_RPMDB
78  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0,
79         N_("Database options:"),
80         NULL },
81 #endif  /* IAM_RPMDB */
82
83 #ifdef  IAM_RPMEIU
84  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
85         N_("Install/Upgrade/Erase options:"),
86         NULL },
87 #endif  /* IAM_RPMEIU */
88
89  { "quiet", '\0', 0, &quiet, 0,                 NULL, NULL},
90
91  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
92         N_("Common options for all rpm modes and executables:"),
93         NULL },
94
95    POPT_AUTOALIAS
96    POPT_AUTOHELP
97    POPT_TABLEEND
98 };
99
100 #ifdef __MINT__
101 /* MiNT cannot dynamically increase the stack.  */
102 long _stksize = 64 * 1024L;
103 #endif
104
105 RPM_GNUC_NORETURN
106 static void argerror(const char * desc)
107 {
108     fprintf(stderr, _("%s: %s\n"), __progname, desc);
109     exit(EXIT_FAILURE);
110 }
111
112 static void printVersion(FILE * fp)
113 {
114     fprintf(fp, _("RPM version %s\n"), rpmEVR);
115 }
116
117 static void printBanner(FILE * fp)
118 {
119     fprintf(fp, _("Copyright (C) 1998-2002 - Red Hat, Inc.\n"));
120     fprintf(fp, _("This program may be freely redistributed under the terms of the GNU GPL\n"));
121 }
122
123 static void printUsage(poptContext con, FILE * fp, int flags)
124 {
125     printVersion(fp);
126     printBanner(fp);
127     fprintf(fp, "\n");
128
129     if (rpmIsVerbose())
130         poptPrintHelp(con, fp, flags);
131     else
132         poptPrintUsage(con, fp, flags);
133 }
134
135 int main(int argc, char *argv[])
136 {
137     rpmts ts = NULL;
138     enum modes bigMode = MODE_UNKNOWN;
139
140 #if defined(IAM_RPMQV)
141     QVA_t qva = &rpmQVKArgs;
142 #endif
143
144 #ifdef  IAM_RPMEIU
145    struct rpmInstallArguments_s * ia = &rpmIArgs;
146 #endif
147
148 #if defined(IAM_RPMDB)
149    struct rpmDatabaseArguments_s * da = &rpmDBArgs;
150 #endif
151
152 #if defined(IAM_RPMK)
153    QVA_t ka = &rpmQVKArgs;
154 #endif
155
156 #if defined(IAM_RPMK)
157     char * passPhrase = "";
158 #endif
159
160     int arg;
161
162     const char *optArg, *poptCtx;
163     pid_t pipeChild = 0;
164     poptContext optCon;
165     int ec = 0;
166     int status;
167     int p[2];
168 #ifdef  IAM_RPMEIU
169     int i;
170 #endif
171         
172 #if HAVE_MCHECK_H && HAVE_MTRACE
173     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
174 #endif
175     setprogname(argv[0]);       /* Retrofit glibc __progname */
176
177     /* XXX glibc churn sanity */
178     if (__progname == NULL) {
179         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
180         else __progname = argv[0];
181     }
182
183     /* Set the major mode based on argv[0] */
184 #ifdef  IAM_RPMQV
185     if (rstreq(__progname, "rpmquery")) bigMode = MODE_QUERY;
186     if (rstreq(__progname, "rpmverify")) bigMode = MODE_VERIFY;
187 #endif
188
189 #if defined(IAM_RPMQV)
190     /* Jumpstart option from argv[0] if necessary. */
191     switch (bigMode) {
192     case MODE_QUERY:    qva->qva_mode = 'q';    break;
193     case MODE_VERIFY:   qva->qva_mode = 'V';    break;
194     case MODE_CHECKSIG: qva->qva_mode = 'K';    break;
195     case MODE_RESIGN:   qva->qva_mode = 'R';    break;
196     case MODE_INSTALL:
197     case MODE_ERASE:
198     case MODE_INITDB:
199     case MODE_REBUILDDB:
200     case MODE_VERIFYDB:
201     case MODE_UNKNOWN:
202     default:
203         break;
204     }
205 #endif
206
207 #if defined(ENABLE_NLS)
208     /* set up the correct locale */
209     (void) setlocale(LC_ALL, "" );
210
211     bindtextdomain(PACKAGE, LOCALEDIR);
212     textdomain(PACKAGE);
213 #endif
214
215     rpmSetVerbosity(RPMLOG_NOTICE);     /* XXX silly use by showrc */
216
217     /* Only build has it's own set of aliases, everything else uses rpm */
218     poptCtx = "rpm";
219
220     /* Make a first pass through the arguments, looking for --rcfile */
221     /* We need to handle that before dealing with the rest of the arguments. */
222     /* XXX popt argv definition should be fixed instead of casting... */
223     optCon = poptGetContext(poptCtx, argc, (const char **)argv, optionsTable, 0);
224     {
225         char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL);
226         (void) poptReadConfigFile(optCon, poptfile);
227         free(poptfile);
228     }
229     (void) poptReadDefaultConfig(optCon, 1);
230     poptSetExecPath(optCon, rpmConfigDir(), 1);
231
232     while ((arg = poptGetNextOpt(optCon)) > 0) {
233         optArg = poptGetOptArg(optCon);
234
235         switch (arg) {
236         default:
237             fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
238             exit(EXIT_FAILURE);
239         }
240     }
241
242     if (arg < -1) {
243         fprintf(stderr, "%s: %s\n", 
244                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
245                 poptStrerror(arg));
246         exit(EXIT_FAILURE);
247     }
248
249     rpmcliConfigured();
250
251 #ifdef  IAM_RPMDB
252   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
253     if (da->init) {
254         if (bigMode != MODE_UNKNOWN) 
255             argerror(_("only one major mode may be specified"));
256         else
257             bigMode = MODE_INITDB;
258     } else
259     if (da->rebuild) {
260         if (bigMode != MODE_UNKNOWN) 
261             argerror(_("only one major mode may be specified"));
262         else
263             bigMode = MODE_REBUILDDB;
264     } else
265     if (da->verify) {
266         if (bigMode != MODE_UNKNOWN) 
267             argerror(_("only one major mode may be specified"));
268         else
269             bigMode = MODE_VERIFYDB;
270     }
271   }
272 #endif  /* IAM_RPMDB */
273
274 #ifdef  IAM_RPMQV
275   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
276     switch (qva->qva_mode) {
277     case 'q':   bigMode = MODE_QUERY;           break;
278     case 'V':   bigMode = MODE_VERIFY;          break;
279     }
280
281     if (qva->qva_sourceCount) {
282         if (qva->qva_sourceCount > 2)
283             argerror(_("one type of query/verify may be performed at a "
284                         "time"));
285     }
286     if (qva->qva_flags && (bigMode & ~MODES_QV)) 
287         argerror(_("unexpected query flags"));
288
289     if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
290         argerror(_("unexpected query format"));
291
292     if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
293         argerror(_("unexpected query source"));
294   }
295 #endif  /* IAM_RPMQV */
296
297 #ifdef  IAM_RPMEIU
298   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
299     {   int iflags = (ia->installInterfaceFlags &
300                 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
301         int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
302
303         if (iflags & eflags)
304             argerror(_("only one major mode may be specified"));
305         else if (iflags)
306             bigMode = MODE_INSTALL;
307         else if (eflags)
308             bigMode = MODE_ERASE;
309     }
310 #endif  /* IAM_RPMEIU */
311
312 #ifdef  IAM_RPMK
313   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
314         switch (ka->qva_mode) {
315         case RPMSIGN_NONE:
316             ka->sign = 0;
317             break;
318         case RPMSIGN_IMPORT_PUBKEY:
319         case RPMSIGN_CHK_SIGNATURE:
320             bigMode = MODE_CHECKSIG;
321             ka->sign = 0;
322             break;
323         case RPMSIGN_ADD_SIGNATURE:
324         case RPMSIGN_NEW_SIGNATURE:
325         case RPMSIGN_DEL_SIGNATURE:
326             bigMode = MODE_RESIGN;
327             ka->sign = (ka->qva_mode != RPMSIGN_DEL_SIGNATURE);
328             break;
329         }
330   }
331 #endif  /* IAM_RPMK */
332
333 #if defined(IAM_RPMEIU)
334     if (!( bigMode == MODE_INSTALL ) &&
335 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
336         argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
337     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
338         argerror(_("files may only be relocated during package installation"));
339
340     if (ia->relocations && ia->prefix)
341         argerror(_("cannot use --prefix with --relocate or --excludepath"));
342
343     if (bigMode != MODE_INSTALL && ia->relocations)
344         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
345
346     if (bigMode != MODE_INSTALL && ia->prefix)
347         argerror(_("--prefix may only be used when installing new packages"));
348
349     if (ia->prefix && ia->prefix[0] != '/') 
350         argerror(_("arguments to --prefix must begin with a /"));
351
352     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
353         argerror(_("--hash (-h) may only be specified during package "
354                         "installation"));
355
356     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
357         argerror(_("--percent may only be specified during package "
358                         "installation"));
359
360     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
361         argerror(_("--replacepkgs may only be specified during package "
362                         "installation"));
363
364     if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
365         argerror(_("--excludedocs may only be specified during package "
366                    "installation"));
367
368     if (bigMode != MODE_INSTALL && ia->incldocs)
369         argerror(_("--includedocs may only be specified during package "
370                    "installation"));
371
372     if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
373         argerror(_("only one of --excludedocs and --includedocs may be "
374                  "specified"));
375   
376     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
377         argerror(_("--ignorearch may only be specified during package "
378                    "installation"));
379
380     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
381         argerror(_("--ignoreos may only be specified during package "
382                    "installation"));
383
384     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
385         (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
386         argerror(_("--ignoresize may only be specified during package "
387                    "installation"));
388
389     if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
390         argerror(_("--allmatches may only be specified during package "
391                    "erasure"));
392
393     if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
394         argerror(_("--allfiles may only be specified during package "
395                    "installation"));
396
397     if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
398         bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
399         argerror(_("--justdb may only be specified during package "
400                    "installation and erasure"));
401
402     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
403         (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
404         argerror(_("script disabling options may only be specified during "
405                    "package installation and erasure"));
406
407     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
408         (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
409         argerror(_("trigger disabling options may only be specified during "
410                    "package installation and erasure"));
411
412     if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
413         argerror(_("--nodeps may only be specified during package "
414                    "building, rebuilding, recompilation, installation,"
415                    "erasure, and verification"));
416
417     if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
418         argerror(_("--test may only be specified during package installation, "
419                  "erasure, and building"));
420 #endif  /* IAM_RPMEIU */
421
422     if (rpmcliRootDir && rpmcliRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
423         argerror(_("--root (-r) may only be specified during "
424                  "installation, erasure, querying, and "
425                  "database rebuilds"));
426
427     if (rpmcliRootDir) {
428         switch (urlIsURL(rpmcliRootDir)) {
429         default:
430             if (bigMode & MODES_FOR_ROOT)
431                 break;
432         case URL_IS_UNKNOWN:
433             if (rpmcliRootDir[0] != '/')
434                 argerror(_("arguments to --root (-r) must begin with a /"));
435             break;
436         }
437     }
438
439     if (quiet)
440         rpmSetVerbosity(RPMLOG_WARNING);
441
442 #if defined(IAM_RPK)
443     if (ka->sign) {
444         if (bigMode == MODE_RESIGN) {
445             const char ** av;
446             struct stat sb;
447             int errors = 0;
448
449             if ((av = poptGetArgs(optCon)) == NULL) {
450                 fprintf(stderr, _("no files to sign\n"));
451                 errors++;
452             } else
453             while (*av) {
454                 if (stat(*av, &sb)) {
455                     fprintf(stderr, _("cannot access file %s\n"), *av);
456                     errors++;
457                 }
458                 av++;
459             }
460
461             if (errors) {
462                 ec = errors;
463                 goto exit;
464             }
465
466             if (poptPeekArg(optCon)) {
467                 int sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY);
468                 switch (sigTag) {
469                   case 0:
470                     break;
471                   case RPMSIGTAG_PGP:
472                   case RPMSIGTAG_GPG:
473                   case RPMSIGTAG_DSA:
474                   case RPMSIGTAG_RSA:
475                     passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
476                     if (passPhrase == NULL) {
477                         fprintf(stderr, _("Pass phrase check failed\n"));
478                         ec = EXIT_FAILURE;
479                         goto exit;
480                     }
481                     fprintf(stderr, _("Pass phrase is good.\n"));
482                     passPhrase = xstrdup(passPhrase);
483                     break;
484                   default:
485                     fprintf(stderr,
486                             _("Invalid %%_signature spec in macro file.\n"));
487                     ec = EXIT_FAILURE;
488                     goto exit;
489                     break;
490                 }
491             }
492         } else {
493             argerror(_("--sign may only be used during package building"));
494         }
495     } else {
496         /* Make rpmLookupSignatureType() return 0 ("none") from now on */
497         (void) rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
498     }
499 #endif  /* IAM_RPMK */
500
501     if (rpmcliPipeOutput) {
502         if (pipe(p) < 0) {
503             fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
504             goto exit;
505         }
506
507         if (!(pipeChild = fork())) {
508             (void) signal(SIGPIPE, SIG_DFL);
509             (void) close(p[1]);
510             (void) dup2(p[0], STDIN_FILENO);
511             (void) close(p[0]);
512             (void) execl("/bin/sh", "/bin/sh", "-c", rpmcliPipeOutput, NULL);
513             fprintf(stderr, _("exec failed\n"));
514         }
515
516         (void) close(p[0]);
517         (void) dup2(p[1], STDOUT_FILENO);
518         (void) close(p[1]);
519     }
520         
521     ts = rpmtsCreate();
522     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
523     switch (bigMode) {
524 #ifdef  IAM_RPMDB
525     case MODE_INITDB:
526         ec = rpmtsInitDB(ts, 0644);
527         break;
528
529     case MODE_REBUILDDB:
530     {   rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
531         rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
532         ec = rpmtsRebuildDB(ts);
533         vsflags = rpmtsSetVSFlags(ts, ovsflags);
534     }   break;
535     case MODE_VERIFYDB:
536         ec = rpmtsVerifyDB(ts);
537         break;
538 #endif  /* IAM_RPMDB */
539
540 #ifdef  IAM_RPMEIU
541     case MODE_ERASE:
542         if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
543
544         if (!poptPeekArg(optCon)) {
545             argerror(_("no packages given for erase"));
546         } else {
547             ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
548         }
549         break;
550
551     case MODE_INSTALL:
552
553         /* RPMTRANS_FLAG_KEEPOBSOLETE */
554
555         if (!ia->incldocs) {
556             if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
557                 ;
558             } else if (rpmExpandNumeric("%{_excludedocs}"))
559                 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
560         }
561
562         if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
563
564         /* we've already ensured !(!ia->prefix && !ia->relocations) */
565         if (ia->prefix) {
566             ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
567             ia->relocations[0].oldPath = NULL;   /* special case magic */
568             ia->relocations[0].newPath = ia->prefix;
569             ia->relocations[1].oldPath = NULL;
570             ia->relocations[1].newPath = NULL;
571         } else if (ia->relocations) {
572             ia->relocations = xrealloc(ia->relocations, 
573                         sizeof(*ia->relocations) * (ia->numRelocations + 1));
574             ia->relocations[ia->numRelocations].oldPath = NULL;
575             ia->relocations[ia->numRelocations].newPath = NULL;
576         }
577
578         if (!poptPeekArg(optCon)) {
579             argerror(_("no packages given for install"));
580         } else {
581             /* FIX: ia->relocations[0].newPath undefined */
582             ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
583         }
584         break;
585
586 #endif  /* IAM_RPMEIU */
587
588 #ifdef  IAM_RPMQV
589     case MODE_QUERY:
590         if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
591             argerror(_("no arguments given for query"));
592
593         qva->qva_specQuery = rpmspecQuery;
594         ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
595         qva->qva_specQuery = NULL;
596         break;
597
598     case MODE_VERIFY:
599     {   rpmVerifyFlags verifyFlags = VERIFY_ALL;
600
601         verifyFlags &= ~qva->qva_flags;
602         qva->qva_flags = (rpmQueryFlags) verifyFlags;
603
604         if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
605             argerror(_("no arguments given for verify"));
606         ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
607     }   break;
608 #endif  /* IAM_RPMQV */
609
610 #ifdef IAM_RPMK
611     case MODE_CHECKSIG:
612     {   rpmVerifyFlags verifyFlags =
613                 (VERIFY_FILEDIGEST|VERIFY_DIGEST|VERIFY_SIGNATURE);
614
615         verifyFlags &= ~ka->qva_flags;
616         ka->qva_flags = (rpmQueryFlags) verifyFlags;
617     }  
618     case MODE_RESIGN:
619         if (!poptPeekArg(optCon))
620             argerror(_("no arguments given"));
621         ka->passPhrase = passPhrase;
622         ec = rpmcliSign(ts, ka, (ARGV_const_t) poptGetArgs(optCon));
623         break;
624 #endif  /* IAM_RPMK */
625         
626 #if !defined(IAM_RPMQV)
627     case MODE_QUERY:
628     case MODE_VERIFY:
629 #endif
630 #if !defined(IAM_RPMK)
631     case MODE_CHECKSIG:
632     case MODE_RESIGN:
633 #endif
634 #if !defined(IAM_RPMDB)
635     case MODE_INITDB:
636     case MODE_REBUILDDB:
637     case MODE_VERIFYDB:
638 #endif
639 #if !defined(IAM_RPMEIU)
640     case MODE_INSTALL:
641     case MODE_ERASE:
642 #endif
643     case MODE_UNKNOWN:
644         if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
645             printUsage(optCon, stderr, 0);
646             ec = argc;
647         }
648         break;
649     }
650
651 exit:
652
653     ts = rpmtsFree(ts);
654
655     optCon = poptFreeContext(optCon);
656     rpmFreeMacros(NULL);
657         rpmFreeMacros(rpmCLIMacroContext);
658     rpmFreeRpmrc();
659
660     if (pipeChild) {
661         (void) fclose(stdout);
662         (void) waitpid(pipeChild, &status, 0);
663     }
664
665     /* keeps memory leak checkers quiet */
666     rpmlogClose();
667
668 #ifdef  IAM_RPMQV
669     qva->qva_queryFormat = _free(qva->qva_queryFormat);
670 #endif
671
672 #ifdef  IAM_RPMEIU
673     if (ia->relocations != NULL)
674     for (i = 0; i < ia->numRelocations; i++)
675         ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
676     ia->relocations = _free(ia->relocations);
677 #endif
678
679 #if HAVE_MCHECK_H && HAVE_MTRACE
680     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
681 #endif
682
683     /* XXX Avoid exit status overflow. Status 255 is special to xargs(1) */
684     if (ec > 254) ec = 254;
685
686     return ec;
687 }