add (disabled for now) dependency check to rpmgraph.
[platform/upstream/rpm.git] / rpmqv.c
1 #include "system.h"
2
3 #define _AUTOHELP
4
5 #if defined(IAM_RPM) || defined(__LCLINT__)
6 #define IAM_RPMBT
7 #define IAM_RPMDB
8 #define IAM_RPMEIU
9 #define IAM_RPMQV
10 #define IAM_RPMK
11 #endif
12
13 #include <rpmcli.h>
14 #include <rpmbuild.h>
15
16 #include "rpmdb.h"
17 #include "rpmps.h"
18 #include "rpmts.h"
19
20 #define POPT_NODEPS             1025
21 #define POPT_FORCE              1026
22 #define POPT_NOMD5              1027
23 #define POPT_NOSCRIPTS          1028
24
25 #ifdef  IAM_RPMBT
26 #include "build.h"
27 #define GETOPT_REBUILD          1003
28 #define GETOPT_RECOMPILE        1004
29 #endif
30
31 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
32 #include "signature.h"
33 #endif
34
35 #include "debug.h"
36
37 #define GETOPT_SHOWRC           1018
38 #define GETOPT_DEFINEMACRO      1020
39 #define GETOPT_EVALMACRO        1021
40 #ifdef  NOTYET
41 #define GETOPT_RCFILE           1022
42 #endif
43
44 enum modes {
45
46     MODE_QUERY          = (1 <<  0),
47     MODE_VERIFY         = (1 <<  3),
48     MODE_QUERYTAGS      = (1 <<  9),
49 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
50
51     MODE_INSTALL        = (1 <<  1),
52     MODE_ERASE          = (1 <<  2),
53 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
54
55     MODE_BUILD          = (1 <<  4),
56     MODE_REBUILD        = (1 <<  5),
57     MODE_RECOMPILE      = (1 <<  8),
58     MODE_TARBUILD       = (1 << 11),
59 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE)
60
61     MODE_CHECKSIG       = (1 <<  6),
62     MODE_RESIGN         = (1 <<  7),
63 #define MODES_K  (MODE_CHECKSIG | MODE_RESIGN)
64
65     MODE_INITDB         = (1 << 10),
66     MODE_REBUILDDB      = (1 << 12),
67     MODE_VERIFYDB       = (1 << 13),
68 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB | MODE_VERIFYDB)
69
70
71     MODE_UNKNOWN        = 0
72 };
73
74 #define MODES_FOR_DBPATH        (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
75 #define MODES_FOR_NODEPS        (MODES_BT | MODES_IE | MODE_VERIFY)
76 #define MODES_FOR_TEST          (MODES_BT | MODES_IE)
77 #define MODES_FOR_ROOT          (MODES_BT | MODES_IE | MODES_QV | MODES_DB | MODES_K)
78
79 /*@-exportheadervar@*/
80 /*@unchecked@*/
81 extern int _ftp_debug;
82 /*@unchecked@*/
83 extern int noLibio;
84 /*@unchecked@*/
85 extern int _rpmio_debug;
86
87 /*@=exportheadervar@*/
88
89 /* options for all executables */
90
91 /*@unchecked@*/
92 static int help = 0;
93 /*@unchecked@*/
94 static int noUsageMsg = 0;
95 /*@unchecked@*/
96 /*@observer@*/ /*@null@*/
97 static const char * pipeOutput = NULL;
98 /*@unchecked@*/
99 static int quiet = 0;
100 /*@unchecked@*/
101 /*@observer@*/ /*@null@*/
102 static const char * rcfile = NULL;
103 /*@unchecked@*/
104 /*@observer@*/ /*@null@*/
105 static char * rootdir = "/";
106 /*@unchecked@*/
107 static int showrc = 0;
108 /*@unchecked@*/
109 static int showVersion = 0;
110
111 /*@unchecked@*/
112 static struct poptOption rpmAllPoptTable[] = {
113  { "version", '\0', 0, &showVersion, 0,
114         N_("print the version of rpm being used"),
115         NULL },
116  { "quiet", '\0', 0, &quiet, 0,
117         N_("provide less detailed output"), NULL},
118  { "verbose", 'v', 0, 0, 'v',
119         N_("provide more detailed output"), NULL},
120  { "define", '\0', POPT_ARG_STRING, 0, GETOPT_DEFINEMACRO,
121         N_("define MACRO with value EXPR"), N_("'MACRO EXPR'") },
122  { "eval", '\0', POPT_ARG_STRING, 0, GETOPT_EVALMACRO,
123         N_("print macro expansion of EXPR"), N_("'EXPR'") },
124  { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &pipeOutput, 0,
125         N_("send stdout to <cmd>"), N_("<cmd>") },
126  { "root", 'r', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &rootdir, 0,
127         N_("use <dir> as the top level directory"), N_("<dir>") },
128  { "macros", '\0', POPT_ARG_STRING, &macrofiles, 0,
129         N_("read <file:...> instead of default macro file(s)"),
130         N_("<file:...>") },
131 #if !defined(GETOPT_RCFILE)
132  { "rcfile", '\0', POPT_ARG_STRING, &rcfile, 0,
133         N_("read <file:...> instead of default rpmrc file(s)"),
134         N_("<file:...>") },
135 #else
136  { "rcfile", '\0', 0, 0, GETOPT_RCFILE, 
137         N_("read <file:...> instead of default rpmrc file(s)"),
138         N_("<file:...>") },
139 #endif
140  { "showrc", '\0', 0, &showrc, GETOPT_SHOWRC,
141         N_("display final rpmrc and macro configuration"),
142         NULL },
143
144 #if HAVE_LIBIO_H && defined(_G_IO_IO_FILE_VERSION)
145  { "nolibio", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noLibio, 1,
146         N_("disable use of libio(3) API"), NULL},
147 #endif
148  { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
149         N_("debug protocol data stream"), NULL},
150  { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
151         N_("debug rpmio I/O"), NULL},
152  { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
153         N_("debug URL cache handling"), NULL},
154
155    POPT_TABLEEND
156 };
157
158 /* the structure describing the options we take and the defaults */
159 /*@unchecked@*/
160 static struct poptOption optionsTable[] = {
161
162  /* XXX colliding options */
163 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU) || defined(IAM_RPMBT)
164  {  NULL, 'i', POPT_ARGFLAG_DOC_HIDDEN, 0, 'i',                 NULL, NULL},
165  {  "nodeps", 0, POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_NODEPS,       NULL, NULL},
166  {  "noscripts", 0, POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_NOSCRIPTS, NULL, NULL},
167  {  "nomd5", 0, POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_NOMD5,         NULL, NULL},
168  {  "force", 0, POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_FORCE,         NULL, NULL},
169 #endif
170
171 #ifdef  IAM_RPMQV
172  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
173         N_("Query options (with -q or --query):"),
174         NULL },
175  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
176         N_("Verify options (with -V or --verify):"),
177         NULL },
178 #endif  /* IAM_RPMQV */
179
180 #ifdef  IAM_RPMK
181  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0,
182         N_("Signature options:"),
183         NULL },
184 #endif  /* IAM_RPMK */
185
186 #ifdef  IAM_RPMDB
187  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0,
188         N_("Database options:"),
189         NULL },
190 #endif  /* IAM_RPMDB */
191
192 #ifdef  IAM_RPMBT
193  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
194         N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
195         NULL },
196 #endif  /* IAM_RPMBT */
197
198 #ifdef  IAM_RPMEIU
199  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
200         N_("Install/Upgrade/Erase options:"),
201         NULL },
202 #endif  /* IAM_RPMEIU */
203
204  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmAllPoptTable, 0,
205         N_("Common options for all rpm modes:"),
206         NULL },
207
208    POPT_AUTOALIAS
209    POPT_AUTOHELP
210    POPT_TABLEEND
211 };
212
213 #ifdef __MINT__
214 /* MiNT cannot dynamically increase the stack.  */
215 long _stksize = 64 * 1024L;
216 #endif
217
218 /*@exits@*/ static void argerror(const char * desc)
219         /*@globals __assert_program_name, fileSystem @*/
220         /*@modifies fileSystem @*/
221 {
222     fprintf(stderr, _("%s: %s\n"), __progname, desc);
223     exit(EXIT_FAILURE);
224 }
225
226 static void printVersion(void)
227         /*@globals rpmEVR, fileSystem @*/
228         /*@modifies fileSystem @*/
229 {
230     fprintf(stdout, _("RPM version %s\n"), rpmEVR);
231 }
232
233 static void printBanner(void)
234         /*@globals fileSystem @*/
235         /*@modifies fileSystem @*/
236 {
237     (void) puts(_("Copyright (C) 1998-2002 - Red Hat, Inc."));
238     (void) puts(_("This program may be freely redistributed under the terms of the GNU GPL"));
239 }
240
241 static void printUsage(void)
242         /*@globals __assert_program_name, rpmEVR, fileSystem @*/
243         /*@modifies fileSystem @*/
244 {
245     FILE * fp = stdout;
246     printVersion();
247     printBanner();
248     (void) puts("");
249
250     fprintf(fp, _("Usage: %s {--help}\n"), __progname);
251     fprintf(fp,   "       %s {--version}\n" , __progname);
252
253 #ifdef  IAM_RPMEIU
254 #ifdef  DYING
255 --dbpath        all
256 --ftpproxy etc  all
257 --force         alias for --replacepkgs --replacefiles
258 --includedocs   handle as option in table
259                 --erase forbids many options
260 #endif  /* DYING */
261 #endif  /* IAM_RPMEIU */
262
263 #ifdef  IAM_RPMQV
264 #ifdef  DYING   /* XXX popt glue needing --help doco. */
265 --dbpath        all
266 --ftpproxy etc  all
267 -i,--info       Q
268 -R,--requires   Q
269 -P,--provides   Q
270 --scripts       Q
271 --triggeredby   Q
272 --changelog     Q
273 --triggers      Q
274 --querytags     !V
275 --setperms      V
276 --setugids      V
277 #endif  /* DYING */
278 #endif  /* IAM_RPMQV */
279
280 }
281
282 /*@-mods@*/ /* FIX: shrug */
283 #if !defined(__GLIBC__) && !defined(__LCLINT__)
284 int main(int argc, const char ** argv, /*@unused@*/ char ** envp)
285 #else
286 int main(int argc, const char ** argv)
287 #endif
288         /*@globals __assert_program_name, rpmEVR, RPMVERSION,
289                 rpmGlobalMacroContext, rpmCLIMacroContext,
290                 fileSystem, internalState@*/
291         /*@modifies __assert_program_name,
292                 fileSystem, internalState@*/
293 {
294     rpmts ts = NULL;
295     enum modes bigMode = MODE_UNKNOWN;
296
297 #ifdef  IAM_RPMQV
298     QVA_t qva = &rpmQVKArgs;
299 #endif
300
301 #ifdef  IAM_RPMBT
302     BTA_t ba = &rpmBTArgs;
303 #endif
304
305 #ifdef  IAM_RPMEIU
306    struct rpmInstallArguments_s * ia = &rpmIArgs;
307 #endif
308
309 #if defined(IAM_RPMDB)
310    struct rpmDatabaseArguments_s * da = &rpmDBArgs;
311 #endif
312
313 #if defined(IAM_RPMK)
314    QVA_t ka = &rpmQVKArgs;
315 #endif
316
317 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
318     char * passPhrase = "";
319 #endif
320
321     int arg;
322     int gotDbpath = 0;
323
324     const char * optArg;
325     pid_t pipeChild = 0;
326     poptContext optCon;
327     int ec = 0;
328     int status;
329     int p[2];
330 #ifdef  IAM_RPMEIU
331     int i;
332 #endif
333         
334 #if HAVE_MCHECK_H && HAVE_MTRACE
335     /*@-noeffect@*/
336     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
337     /*@=noeffect@*/
338 #endif
339     setprogname(argv[0]);       /* Retrofit glibc __progname */
340
341 #if !defined(__GLIBC__) && !defined(__LCLINT__)
342     environ = envp;
343 #endif  
344
345     /* XXX glibc churn sanity */
346     if (__progname == NULL) {
347         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
348         else __progname = argv[0];
349     }
350
351     /* Set the major mode based on argv[0] */
352     /*@-nullpass@*/
353 #ifdef  IAM_RPMBT
354     if (!strcmp(__progname, "rpmb"))    bigMode = MODE_BUILD;
355     if (!strcmp(__progname, "rpmt"))    bigMode = MODE_TARBUILD;
356     if (!strcmp(__progname, "rpmbuild"))        bigMode = MODE_BUILD;
357 #endif
358 #ifdef  IAM_RPMQV
359     if (!strcmp(__progname, "rpmq"))    bigMode = MODE_QUERY;
360     if (!strcmp(__progname, "rpmv"))    bigMode = MODE_VERIFY;
361     if (!strcmp(__progname, "rpmquery"))        bigMode = MODE_QUERY;
362     if (!strcmp(__progname, "rpmverify"))       bigMode = MODE_VERIFY;
363 #endif
364 #ifdef  RPMEIU
365     if (!strcmp(__progname, "rpme"))    bigMode = MODE_ERASE;
366     if (!strcmp(__progname, "rpmi"))    bigMode = MODE_INSTALL;
367     if (!strcmp(__progname, "rpmu"))    bigMode = MODE_INSTALL;
368 #endif
369     /*@=nullpass@*/
370
371     /* set the defaults for the various command line options */
372     _ftp_debug = 0;
373
374 #if HAVE_LIBIO_H && defined(_G_IO_IO_FILE_VERSION)
375     noLibio = 0;
376 #else
377     noLibio = 1;
378 #endif
379     _rpmio_debug = 0;
380
381     /* XXX Eliminate query linkage loop */
382     specedit = 0;
383     /*@-type@*/ /* FIX: casts? */
384     parseSpecVec = parseSpec;
385     freeSpecVec = freeSpec;
386     /*@=type@*/
387
388     /* set up the correct locale */
389     (void) setlocale(LC_ALL, "" );
390
391 #ifdef  __LCLINT__
392 #define LOCALEDIR       "/usr/share/locale"
393 #endif
394     bindtextdomain(PACKAGE, LOCALEDIR);
395     textdomain(PACKAGE);
396
397     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
398
399     /* Make a first pass through the arguments, looking for --rcfile */
400     /* We need to handle that before dealing with the rest of the arguments. */
401     /*@-nullpass -temptrans@*/
402     optCon = poptGetContext(__progname, argc, argv, optionsTable, 0);
403     /*@=nullpass =temptrans@*/
404     (void) poptReadConfigFile(optCon, LIBRPMALIAS_FILENAME);
405     (void) poptReadDefaultConfig(optCon, 1);
406     poptSetExecPath(optCon, RPMCONFIGDIR, 1);
407
408     /* reading rcfile early makes it easy to override */
409     /* XXX only --rcfile (and --showrc) need this pre-parse */
410
411     while ((arg = poptGetNextOpt(optCon)) > 0) {
412         switch(arg) {
413         case 'v':
414             rpmIncreaseVerbosity();     /* XXX silly use by showrc */
415             /*@switchbreak@*/ break;
416         default:
417             /*@switchbreak@*/ break;
418       }
419     }
420
421     if (rpmReadConfigFiles(rcfile, NULL))  
422         exit(EXIT_FAILURE);
423
424     if (showrc) {
425         (void) rpmShowRC(stdout);
426         exit(EXIT_SUCCESS);
427     }
428
429     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
430
431     poptResetContext(optCon);
432
433 #ifdef  IAM_RPMQV
434     qva->qva_queryFormat = _free(qva->qva_queryFormat);
435     memset(qva, 0, sizeof(*qva));
436     qva->qva_source = RPMQV_PACKAGE;
437     qva->qva_fflags = RPMFILE_ALL;
438     qva->qva_mode = ' ';
439     qva->qva_char = ' ';
440 #endif
441
442 #ifdef  IAM_RPMBT
443     ba->buildRootOverride = _free(ba->buildRootOverride);
444     ba->targets = _free(ba->targets);
445     memset(ba, 0, sizeof(*ba));
446     ba->buildMode = ' ';
447     ba->buildChar = ' ';
448 #endif
449
450 #ifdef  IAM_RPMDB
451     memset(da, 0, sizeof(*da));
452 #endif
453
454 #ifdef  IAM_RPMK
455     ka->qva_queryFormat = _free(ka->qva_queryFormat);
456     memset(ka, 0, sizeof(*ka));
457     ka->qva_source = RPMQV_PACKAGE;
458     ka->qva_fflags = RPMFILE_ALL;
459     ka->qva_mode = ' ';
460     ka->qva_char = ' ';
461 #endif
462
463 #ifdef  IAM_RPMEIU
464     if (ia->relocations != NULL)
465     for (i = 0; i < ia->numRelocations; i++)
466         ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
467     ia->relocations = _free(ia->relocations);
468     memset(ia, 0, sizeof(*ia));
469     ia->transFlags = RPMTRANS_FLAG_NONE;
470     ia->probFilter = RPMPROB_FILTER_NONE;
471     ia->installInterfaceFlags = INSTALL_NONE;
472     ia->eraseInterfaceFlags = UNINSTALL_NONE;
473 #endif
474
475     while ((arg = poptGetNextOpt(optCon)) > 0) {
476         optArg = poptGetOptArg(optCon);
477
478         switch (arg) {
479             
480         case 'v':
481             rpmIncreaseVerbosity();
482             /*@switchbreak@*/ break;
483
484 /* XXX options used in multiple rpm modes */
485 #if defined(IAM_RPMQV) || defined(IAM_RPMK)
486         case POPT_NOMD5:
487 #ifdef  IAM_RPMQV
488             if (bigMode == MODE_VERIFY || qva->qva_mode == 'V')
489                 qva->qva_flags |= VERIFY_MD5;
490             else
491 #endif
492 #ifdef  IAM_RPMK
493             if (bigMode & MODES_K)
494                 ka->qva_flags |= VERIFY_MD5;
495             else
496 #endif
497 #ifdef IAM_RPMEIU
498             if (bigMode & MODES_IE)
499                 ia->transFlags |= RPMTRANS_FLAG_NOMD5;
500             else
501 #endif
502                 {};
503             /*@switchbreak@*/ break;
504 #endif  /* IAM_RPMQV || IAM_RPMK */
505
506 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU) || defined(IAM_RPMBT)
507         case POPT_NODEPS:
508 #ifdef  IAM_RPMQV
509             if (bigMode == MODE_VERIFY || qva->qva_mode == 'V')
510                 qva->qva_flags |= VERIFY_DEPS;
511             else
512 #endif
513 #ifdef  IAM_RPMEIU
514             if ((bigMode & MODES_IE) ||
515                 (ia->installInterfaceFlags &
516             (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL|INSTALL_ERASE)))
517                 ia->noDeps = 1;
518             else
519 #endif
520 #ifdef  IAM_RPMBT
521             if ((bigMode & MODES_BT) || ba->buildMode != ' ')
522                 ba->noDeps = 1;
523             else
524 #endif
525                 /*@-ifempty@*/ ;
526             /*@switchbreak@*/ break;
527
528         case POPT_FORCE:
529 #ifdef  IAM_RPMEIU
530             if ((bigMode & MODES_IE) ||
531                 (ia->installInterfaceFlags &
532             (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL|INSTALL_ERASE)))
533                 ia->probFilter |=
534                         ( RPMPROB_FILTER_REPLACEPKG
535                         | RPMPROB_FILTER_REPLACEOLDFILES
536                         | RPMPROB_FILTER_REPLACENEWFILES
537                         | RPMPROB_FILTER_OLDPACKAGE);
538             else
539 #endif
540 #ifdef  IAM_RPMBT
541             if ((bigMode & MODES_BT) || ba->buildMode != ' ')
542                 ba->force = 1;
543             else
544 #endif
545                 /*@-ifempty@*/ ;
546             /*@switchbreak@*/ break;
547
548         case 'i':
549 #ifdef  IAM_RPMQV
550             if (bigMode == MODE_QUERY || qva->qva_mode == 'q') {
551                 /*@-nullassign -readonlytrans@*/
552                 const char * infoCommand[] = { "--info", NULL };
553                 /*@=nullassign =readonlytrans@*/
554                 (void) poptStuffArgs(optCon, infoCommand);
555             } else
556 #endif
557 #ifdef  IAM_RPMEIU
558             if (bigMode == MODE_INSTALL ||
559                 (ia->installInterfaceFlags &
560                     (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL)))
561                 /*@-ifempty@*/ ;
562             else if (bigMode == MODE_UNKNOWN) {
563                 /*@-nullassign -readonlytrans@*/
564                 const char * installCommand[] = { "--install", NULL };
565                 /*@=nullassign =readonlytrans@*/
566                 (void) poptStuffArgs(optCon, installCommand);
567             } else
568 #endif
569                 /*@-ifempty@*/ ;
570             /*@switchbreak@*/ break;
571
572         case POPT_NOSCRIPTS:
573 #ifdef  IAM_RPMQV
574             if (bigMode == MODE_VERIFY || qva->qva_mode == 'V')
575                 qva->qva_flags |= VERIFY_SCRIPT;
576             else
577 #endif
578 #ifdef  IAM_RPMEIU
579             if ((bigMode & MODES_IE) ||
580                 (ia->installInterfaceFlags &
581             (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL|INSTALL_ERASE)))
582                 ia->transFlags |= (_noTransScripts | _noTransTriggers);
583             else
584 #endif
585                 /*@-ifempty@*/ ;
586             /*@switchbreak@*/ break;
587
588 #endif  /* IAM_RPMQV || IAM_RPMEIU || IAM_RPMBT */
589
590         case GETOPT_DEFINEMACRO:
591             if (optArg) {
592                 (void) rpmDefineMacro(NULL, optArg, RMIL_CMDLINE);
593 /*@i@*/         (void) rpmDefineMacro(rpmCLIMacroContext, optArg,RMIL_CMDLINE);
594             }
595             noUsageMsg = 1;
596             /*@switchbreak@*/ break;
597
598         case GETOPT_EVALMACRO:
599             if (optArg) {
600                 const char *val = rpmExpand(optArg, NULL);
601                 fprintf(stdout, "%s\n", val);
602                 val = _free(val);
603             }
604             noUsageMsg = 1;
605             /*@switchbreak@*/ break;
606
607 #if defined(GETOPT_RCFILE)
608         case GETOPT_RCFILE:
609             fprintf(stderr, _("The --rcfile option has been eliminated.\n"));
610             fprintf(stderr, _("Use \"--macros <file:...>\" instead.\n"));
611             exit(EXIT_FAILURE);
612             /*@notreached@*/ break;
613 #endif
614
615         default:
616             fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
617             exit(EXIT_FAILURE);
618         }
619     }
620
621     if (quiet)
622         rpmSetVerbosity(RPMMESS_QUIET);
623
624     if (showVersion) printVersion();
625
626     if (arg < -1) {
627         fprintf(stderr, "%s: %s\n", 
628                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
629                 poptStrerror(arg));
630         exit(EXIT_FAILURE);
631     }
632
633 #ifdef  IAM_RPMBT
634     switch (ba->buildMode) {
635     case 'b':   bigMode = MODE_BUILD;           break;
636     case 't':   bigMode = MODE_TARBUILD;        break;
637     case 'B':   bigMode = MODE_REBUILD;         break;
638     case 'C':   bigMode = MODE_RECOMPILE;       break;
639     }
640
641     if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
642         bigMode = MODE_BUILD;
643
644     if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
645         bigMode = MODE_BUILD;
646
647     if (ba->buildRootOverride && bigMode != MODE_BUILD &&
648         bigMode != MODE_REBUILD && bigMode != MODE_TARBUILD) {
649         argerror("--buildroot may only be used during package builds");
650     }
651 #endif  /* IAM_RPMBT */
652     
653 #ifdef  IAM_RPMDB
654   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
655     if (da->init) {
656         if (bigMode != MODE_UNKNOWN) 
657             argerror(_("only one major mode may be specified"));
658         else
659             bigMode = MODE_INITDB;
660     } else
661     if (da->rebuild) {
662         if (bigMode != MODE_UNKNOWN) 
663             argerror(_("only one major mode may be specified"));
664         else
665             bigMode = MODE_REBUILDDB;
666     } else
667     if (da->verify) {
668         if (bigMode != MODE_UNKNOWN) 
669             argerror(_("only one major mode may be specified"));
670         else
671             bigMode = MODE_VERIFYDB;
672     }
673   }
674 #endif  /* IAM_RPMDB */
675
676 #ifdef  IAM_RPMQV
677   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
678     switch (qva->qva_mode) {
679     case 'q':   bigMode = MODE_QUERY;           break;
680     case 'V':   bigMode = MODE_VERIFY;          break;
681     case 'Q':   bigMode = MODE_QUERYTAGS;       break;
682     }
683
684     if (qva->qva_sourceCount) {
685         if (qva->qva_sourceCount > 2)
686             argerror(_("one type of query/verify may be performed at a "
687                         "time"));
688     }
689     if (qva->qva_flags && (bigMode & ~MODES_QV)) 
690         argerror(_("unexpected query flags"));
691
692     if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
693         argerror(_("unexpected query format"));
694
695     if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
696         argerror(_("unexpected query source"));
697   }
698 #endif  /* IAM_RPMQV */
699
700 #ifdef  IAM_RPMEIU
701   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
702     {   int iflags = (ia->installInterfaceFlags &
703                 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
704         int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
705
706         if (iflags & eflags)
707             argerror(_("only one major mode may be specified"));
708         else if (iflags)
709             bigMode = MODE_INSTALL;
710         else if (eflags)
711             bigMode = MODE_ERASE;
712     }
713 #endif  /* IAM_RPMQV */
714
715 #ifdef  IAM_RPMK
716   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
717         switch (ka->qva_mode) {
718         case RPMSIGN_NONE:
719             ka->sign = 0;
720             break;
721         case RPMSIGN_IMPORT_PUBKEY:
722         case RPMSIGN_CHK_SIGNATURE:
723             bigMode = MODE_CHECKSIG;
724             ka->sign = 0;
725             break;
726         case RPMSIGN_ADD_SIGNATURE:
727         case RPMSIGN_NEW_SIGNATURE:
728             bigMode = MODE_RESIGN;
729             ka->sign = 1;
730             break;
731         }
732   }
733 #endif  /* IAM_RPMK */
734
735     /* XXX TODO: never happens. */
736     if (gotDbpath && (bigMode & ~MODES_FOR_DBPATH))
737         argerror(_("--dbpath given for operation that does not use a "
738                         "database"));
739
740 #if defined(IAM_RPMEIU)
741     if (!( bigMode == MODE_INSTALL ) &&
742 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_REPLACEOLDFILES | RPMPROB_FILTER_REPLACENEWFILES | RPMPROB_FILTER_OLDPACKAGE)))
743         argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
744     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
745         argerror(_("files may only be relocated during package installation"));
746
747     if (ia->relocations && ia->prefix)
748         argerror(_("only one of --prefix or --relocate may be used"));
749
750     if (bigMode != MODE_INSTALL && ia->relocations)
751         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
752
753     if (bigMode != MODE_INSTALL && ia->prefix)
754         argerror(_("--prefix may only be used when installing new packages"));
755
756     if (ia->prefix && ia->prefix[0] != '/') 
757         argerror(_("arguments to --prefix must begin with a /"));
758
759     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
760         argerror(_("--hash (-h) may only be specified during package "
761                         "installation"));
762
763     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
764         argerror(_("--percent may only be specified during package "
765                         "installation"));
766
767     if (bigMode != MODE_INSTALL &&
768  (ia->probFilter & (RPMPROB_FILTER_REPLACEOLDFILES|RPMPROB_FILTER_REPLACENEWFILES)))
769         argerror(_("--replacefiles may only be specified during package "
770                         "installation"));
771
772     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
773         argerror(_("--replacepkgs may only be specified during package "
774                         "installation"));
775
776     if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
777         argerror(_("--excludedocs may only be specified during package "
778                    "installation"));
779
780     if (bigMode != MODE_INSTALL && ia->incldocs)
781         argerror(_("--includedocs may only be specified during package "
782                    "installation"));
783
784     if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
785         argerror(_("only one of --excludedocs and --includedocs may be "
786                  "specified"));
787   
788     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
789         argerror(_("--ignorearch may only be specified during package "
790                    "installation"));
791
792     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
793         argerror(_("--ignoreos may only be specified during package "
794                    "installation"));
795
796     if (bigMode != MODE_INSTALL &&
797         (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
798         argerror(_("--ignoresize may only be specified during package "
799                    "installation"));
800
801     if ((ia->eraseInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
802         argerror(_("--allmatches may only be specified during package "
803                    "erasure"));
804
805     if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
806         argerror(_("--allfiles may only be specified during package "
807                    "installation"));
808
809     if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
810         bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
811         argerror(_("--justdb may only be specified during package "
812                    "installation and erasure"));
813
814     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
815         (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
816         argerror(_("script disabling options may only be specified during "
817                    "package installation and erasure"));
818
819     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
820         (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
821         argerror(_("trigger disabling options may only be specified during "
822                    "package installation and erasure"));
823
824     if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
825         argerror(_("--nodeps may only be specified during package "
826                    "building, rebuilding, recompilation, installation,"
827                    "erasure, and verification"));
828
829     if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
830         argerror(_("--test may only be specified during package installation, "
831                  "erasure, and building"));
832 #endif  /* IAM_RPMEIU */
833
834     if (rootdir && rootdir[1] && (bigMode & ~MODES_FOR_ROOT))
835         argerror(_("--root (-r) may only be specified during "
836                  "installation, erasure, querying, and "
837                  "database rebuilds"));
838
839     if (rootdir) {
840         switch (urlIsURL(rootdir)) {
841         default:
842             if (bigMode & MODES_FOR_ROOT)
843                 break;
844             /*@fallthrough@*/
845         case URL_IS_UNKNOWN:
846             if (rootdir[0] != '/')
847                 argerror(_("arguments to --root (-r) must begin with a /"));
848             break;
849         }
850     }
851
852 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
853     if (0
854 #if defined(IAM_RPMBT)
855     || ba->sign 
856 #endif
857 #if defined(IAM_RPMK)
858     || ka->sign
859 #endif
860     )
861     /*@-branchstate@*/
862     {
863         if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
864             bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD)
865         {
866             const char ** av;
867             struct stat sb;
868             int errors = 0;
869
870             if ((av = poptGetArgs(optCon)) == NULL) {
871                 fprintf(stderr, _("no files to sign\n"));
872                 errors++;
873             } else
874             while (*av) {
875                 if (stat(*av, &sb)) {
876                     fprintf(stderr, _("cannot access file %s\n"), *av);
877                     errors++;
878                 }
879                 av++;
880             }
881
882             if (errors) {
883                 ec = errors;
884                 goto exit;
885             }
886
887             if (poptPeekArg(optCon)) {
888                 int sigTag;
889                 switch (sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) {
890                   case 0:
891                     break;
892                   case RPMSIGTAG_PGP:
893                     if ((sigTag == RPMSIGTAG_PGP || sigTag == RPMSIGTAG_PGP5) &&
894                         !rpmDetectPGPVersion(NULL)) {
895                         fprintf(stderr, _("pgp not found: "));
896                         ec = EXIT_FAILURE;
897                         goto exit;
898                     }   /*@fallthrough@*/
899                   case RPMSIGTAG_GPG:
900                     passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
901                     if (passPhrase == NULL) {
902                         fprintf(stderr, _("Pass phrase check failed\n"));
903                         ec = EXIT_FAILURE;
904                         goto exit;
905                     }
906                     fprintf(stderr, _("Pass phrase is good.\n"));
907                     passPhrase = xstrdup(passPhrase);
908                     break;
909                   default:
910                     fprintf(stderr,
911                             _("Invalid %%_signature spec in macro file.\n"));
912                     ec = EXIT_FAILURE;
913                     goto exit;
914                     /*@notreached@*/ break;
915                 }
916             }
917         } else {
918             argerror(_("--sign may only be used during package building"));
919         }
920     } else {
921         /* Make rpmLookupSignatureType() return 0 ("none") from now on */
922         (void) rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
923     }
924     /*@=branchstate@*/
925 #endif  /* IAM_RPMBT || IAM_RPMK */
926
927     if (pipeOutput) {
928         (void) pipe(p);
929
930         if (!(pipeChild = fork())) {
931             (void) close(p[1]);
932             (void) dup2(p[0], STDIN_FILENO);
933             (void) close(p[0]);
934             (void) execl("/bin/sh", "/bin/sh", "-c", pipeOutput, NULL);
935             fprintf(stderr, _("exec failed\n"));
936         }
937
938         (void) close(p[0]);
939         (void) dup2(p[1], STDOUT_FILENO);
940         (void) close(p[1]);
941     }
942         
943     ts = rpmtsCreate();
944     (void) rpmtsSetRootDir(ts, rootdir);
945     switch (bigMode) {
946 #ifdef  IAM_RPMDB
947     case MODE_INITDB:
948         (void) rpmdbInit(rootdir, 0644);
949         break;
950
951     case MODE_REBUILDDB:
952         ec = rpmdbRebuild(rootdir);
953         break;
954     case MODE_VERIFYDB:
955         ec = rpmdbVerify(rootdir);
956         break;
957 #endif  /* IAM_RPMDB */
958
959 #ifdef  IAM_RPMBT
960     case MODE_REBUILD:
961     case MODE_RECOMPILE:
962     {   const char * pkg;
963
964         while (!rpmIsVerbose())
965             rpmIncreaseVerbosity();
966
967         if (!poptPeekArg(optCon))
968             argerror(_("no packages files given for rebuild"));
969
970         ba->buildAmount = RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL;
971         if (bigMode == MODE_REBUILD) {
972             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
973             ba->buildAmount |= RPMBUILD_RMSOURCE;
974             ba->buildAmount |= RPMBUILD_RMSPEC;
975             ba->buildAmount |= RPMBUILD_CLEAN;
976             ba->buildAmount |= RPMBUILD_RMBUILD;
977         }
978
979         while ((pkg = poptGetArg(optCon))) {
980             const char * specFile = NULL;
981
982             ba->cookie = NULL;
983             ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
984             if (ec == 0) {
985                 ba->rootdir = rootdir;
986                 ba->passPhrase = passPhrase;
987                 ec = build(ts, specFile, ba, rcfile);
988             }
989             ba->cookie = _free(ba->cookie);
990             specFile = _free(specFile);
991
992             if (ec)
993                 /*@loopbreak@*/ break;
994         }
995
996     }   break;
997
998     case MODE_BUILD:
999     case MODE_TARBUILD:
1000     {   const char * pkg;
1001         while (!rpmIsVerbose())
1002             rpmIncreaseVerbosity();
1003        
1004         switch (ba->buildChar) {
1005         case 'a':
1006             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
1007             /*@fallthrough@*/
1008         case 'b':
1009             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
1010             ba->buildAmount |= RPMBUILD_CLEAN;
1011             /*@fallthrough@*/
1012         case 'i':
1013             ba->buildAmount |= RPMBUILD_INSTALL;
1014             if ((ba->buildChar == 'i') && ba->shortCircuit)
1015                 /*@innerbreak@*/ break;
1016             /*@fallthrough@*/
1017         case 'c':
1018             ba->buildAmount |= RPMBUILD_BUILD;
1019             if ((ba->buildChar == 'c') && ba->shortCircuit)
1020                 /*@innerbreak@*/ break;
1021             /*@fallthrough@*/
1022         case 'p':
1023             ba->buildAmount |= RPMBUILD_PREP;
1024             /*@innerbreak@*/ break;
1025             
1026         case 'l':
1027             ba->buildAmount |= RPMBUILD_FILECHECK;
1028             /*@innerbreak@*/ break;
1029         case 's':
1030             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
1031             /*@innerbreak@*/ break;
1032         }
1033
1034         if (!poptPeekArg(optCon)) {
1035             if (bigMode == MODE_BUILD)
1036                 argerror(_("no spec files given for build"));
1037             else
1038                 argerror(_("no tar files given for build"));
1039         }
1040
1041         while ((pkg = poptGetArg(optCon))) {
1042             ba->rootdir = rootdir;
1043             ba->passPhrase = passPhrase;
1044             ba->cookie = NULL;
1045             ec = build(ts, pkg, ba, rcfile);
1046             if (ec)
1047                 /*@loopbreak@*/ break;
1048             rpmFreeMacros(NULL);
1049             (void) rpmReadConfigFiles(rcfile, NULL);
1050         }
1051     }   break;
1052 #endif  /* IAM_RPMBT */
1053
1054 #ifdef  IAM_RPMEIU
1055     case MODE_ERASE:
1056         if (ia->noDeps) ia->eraseInterfaceFlags |= UNINSTALL_NODEPS;
1057
1058         if (!poptPeekArg(optCon)) {
1059             if (ia->rbtid == 0)
1060                 argerror(_("no packages given for erase"));
1061 ia->transFlags |= RPMTRANS_FLAG_NOMD5;
1062 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
1063             ec += rpmRollback(ts, ia, NULL);
1064         } else {
1065             ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon));
1066         }
1067         break;
1068
1069     case MODE_INSTALL:
1070
1071         /* RPMTRANS_FLAG_BUILD_PROBS */
1072         /* RPMTRANS_FLAG_KEEPOBSOLETE */
1073
1074         if (!ia->incldocs) {
1075             if (ia->transFlags & RPMTRANS_FLAG_NODOCS)
1076                 ;
1077             else if (rpmExpandNumeric("%{_excludedocs}"))
1078                 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
1079         }
1080
1081         if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
1082
1083         /* we've already ensured !(!ia->prefix && !ia->relocations) */
1084         /*@-branchstate@*/
1085         if (ia->prefix) {
1086             ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
1087             ia->relocations[0].oldPath = NULL;   /* special case magic */
1088             ia->relocations[0].newPath = ia->prefix;
1089             ia->relocations[1].oldPath = NULL;
1090             ia->relocations[1].newPath = NULL;
1091         } else if (ia->relocations) {
1092             ia->relocations = xrealloc(ia->relocations, 
1093                         sizeof(*ia->relocations) * (ia->numRelocations + 1));
1094             ia->relocations[ia->numRelocations].oldPath = NULL;
1095             ia->relocations[ia->numRelocations].newPath = NULL;
1096         }
1097         /*@=branchstate@*/
1098
1099         if (!poptPeekArg(optCon)) {
1100             if (ia->rbtid == 0)
1101                 argerror(_("no packages given for install"));
1102 ia->transFlags |= RPMTRANS_FLAG_NOMD5;
1103 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
1104 /*@i@*/     ec += rpmRollback(ts, ia, NULL);
1105         } else {
1106             /*@-compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */
1107             ec += rpmInstall(ts, ia, (const char **)poptGetArgs(optCon));
1108             /*@=compmempass@*/
1109         }
1110         break;
1111
1112 #endif  /* IAM_RPMEIU */
1113
1114 #ifdef  IAM_RPMQV
1115     case MODE_QUERY:
1116         if (qva->qva_source != RPMQV_ALL && !poptPeekArg(optCon))
1117             argerror(_("no arguments given for query"));
1118         ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon));
1119         /* XXX don't overflow single byte exit status */
1120         if (ec > 255) ec = 255;
1121         break;
1122
1123     case MODE_VERIFY:
1124     {   rpmVerifyFlags verifyFlags = VERIFY_ALL;
1125
1126         verifyFlags &= ~qva->qva_flags;
1127         qva->qva_flags = (rpmQueryFlags) verifyFlags;
1128
1129         if (qva->qva_source != RPMQV_ALL && !poptPeekArg(optCon))
1130             argerror(_("no arguments given for verify"));
1131         ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon));
1132         /* XXX don't overflow single byte exit status */
1133         if (ec > 255) ec = 255;
1134     }   break;
1135
1136     case MODE_QUERYTAGS:
1137         if (argc != 2)
1138             argerror(_("unexpected arguments to --querytags "));
1139
1140         rpmDisplayQueryTags(stdout);
1141         break;
1142 #endif  /* IAM_RPMQV */
1143
1144 #ifdef IAM_RPMK
1145     case MODE_CHECKSIG:
1146     {   rpmVerifyFlags verifyFlags =
1147                 (VERIFY_MD5|VERIFY_DIGEST|VERIFY_SIGNATURE);
1148
1149         verifyFlags &= ~ka->qva_flags;
1150         ka->qva_flags = (rpmQueryFlags) verifyFlags;
1151     }   /*@fallthrough@*/
1152     case MODE_RESIGN:
1153         if (!poptPeekArg(optCon))
1154             argerror(_("no arguments given"));
1155         ka->passPhrase = passPhrase;
1156         ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon));
1157         /* XXX don't overflow single byte exit status */
1158         if (ec > 255) ec = 255;
1159         break;
1160 #endif  /* IAM_RPMK */
1161         
1162 #if !defined(IAM_RPMQV)
1163     case MODE_QUERY:
1164     case MODE_VERIFY:
1165     case MODE_QUERYTAGS:
1166 #endif
1167 #if !defined(IAM_RPMK)
1168     case MODE_CHECKSIG:
1169     case MODE_RESIGN:
1170 #endif
1171 #if !defined(IAM_RPMDB)
1172     case MODE_INITDB:
1173     case MODE_REBUILDDB:
1174     case MODE_VERIFYDB:
1175 #endif
1176 #if !defined(IAM_RPMBT)
1177     case MODE_BUILD:
1178     case MODE_REBUILD:
1179     case MODE_RECOMPILE:
1180     case MODE_TARBUILD:
1181 #endif
1182 #if !defined(IAM_RPMEIU)
1183     case MODE_INSTALL:
1184     case MODE_ERASE:
1185 #endif
1186     case MODE_UNKNOWN:
1187         if (!showVersion && !help && !noUsageMsg) printUsage();
1188         break;
1189     }
1190
1191 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
1192 exit:
1193 #endif  /* IAM_RPMBT || IAM_RPMK */
1194
1195     ts = rpmtsFree(ts);
1196
1197     optCon = poptFreeContext(optCon);
1198     rpmFreeMacros(NULL);
1199 /*@i@*/ rpmFreeMacros(rpmCLIMacroContext);
1200     rpmFreeRpmrc();
1201
1202     if (pipeChild) {
1203         (void) fclose(stdout);
1204         (void) waitpid(pipeChild, &status, 0);
1205     }
1206
1207     /* keeps memory leak checkers quiet */
1208     freeNames();
1209     freeFilesystems();
1210 /*@i@*/ urlFreeCache();
1211     rpmlogClose();
1212     dbiTags = _free(dbiTags);
1213
1214 #ifdef  IAM_RPMQV
1215     qva->qva_queryFormat = _free(qva->qva_queryFormat);
1216 #endif
1217
1218 #ifdef  IAM_RPMBT
1219     ba->buildRootOverride = _free(ba->buildRootOverride);
1220     ba->targets = _free(ba->targets);
1221 #endif
1222
1223 #ifdef  IAM_RPMEIU
1224     if (ia->relocations != NULL)
1225     for (i = 0; i < ia->numRelocations; i++)
1226         ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
1227     ia->relocations = _free(ia->relocations);
1228 #endif
1229
1230 #if HAVE_MCHECK_H && HAVE_MTRACE
1231     /*@-noeffect@*/
1232     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
1233     /*@=noeffect@*/
1234 #endif
1235     /*@-globstate@*/
1236     return ec;
1237     /*@=globstate@*/
1238 }
1239 /*@=mods@*/