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