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