- tsort prefers presentation order.
[platform/upstream/rpm.git] / rpm.c
1 #include "system.h"
2
3 #include <rpmbuild.h>
4 #include <rpmurl.h>
5
6 #include "build.h"
7 #include "install.h"
8 #include "signature.h"
9 #include "debug.h"
10
11 #define GETOPT_ADDSIGN          1005
12 #define GETOPT_RESIGN           1006
13 #define GETOPT_DBPATH           1010
14 #define GETOPT_REBUILDDB        1013
15 #define GETOPT_INSTALL          1014
16 #define GETOPT_RELOCATE         1016
17 #define GETOPT_SHOWRC           1018
18 #define GETOPT_EXCLUDEPATH      1019
19 #define GETOPT_DEFINEMACRO      1020
20 #define GETOPT_EVALMACRO        1021
21 #define GETOPT_RCFILE           1022
22
23 enum modes {
24     MODE_UNKNOWN        = 0,
25     MODE_QUERY          = (1 <<  0),
26     MODE_INSTALL        = (1 <<  1),
27     MODE_UNINSTALL      = (1 <<  2),
28     MODE_VERIFY         = (1 <<  3),
29     MODE_BUILD          = (1 <<  4),
30     MODE_REBUILD        = (1 <<  5),
31     MODE_CHECKSIG       = (1 <<  6),
32     MODE_RESIGN         = (1 <<  7),
33     MODE_RECOMPILE      = (1 <<  8),
34     MODE_QUERYTAGS      = (1 <<  9),
35     MODE_INITDB         = (1 << 10),
36     MODE_TARBUILD       = (1 << 11),
37     MODE_REBUILDDB      = (1 << 12)
38 };
39
40 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
41 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE)
42 #define MODES_IE (MODE_INSTALL | MODE_UNINSTALL)
43 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB)
44 #define MODES_K  (MODE_CHECKSIG | MODES_RESIGN)
45
46 #define MODES_FOR_DBPATH        (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
47 #define MODES_FOR_NODEPS        (MODES_BT | MODES_IE | MODE_VERIFY)
48 #define MODES_FOR_TEST          (MODES_BT | MODES_IE)
49 #define MODES_FOR_ROOT          (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
50
51 /* the flags for the various options */
52 static int allFiles;
53 static int allMatches;
54 static int badReloc;
55 static int excldocs;
56 static int force;
57 extern int _ftp_debug;
58 static int showHash;
59 static int help;
60 static int ignoreArch;
61 static int ignoreOs;
62 static int ignoreSize;
63 static int incldocs;
64 static int initdb;
65 static int justdb;
66 static int noDeps;
67 static int noGpg;
68 extern int noLibio;
69 static int noMd5;
70 static int noOrder;
71 static int noPgp;
72 static int noScripts;
73 static int noTriggers;
74 static int noUsageMsg;
75 static int oldPackage;
76 static char * pipeOutput;
77 static char * prefix;
78 static int quiet;
79 static char * rcfile;
80 static int replaceFiles;
81 static int replacePackages;
82 static char * rootdir;
83 extern int _rpmio_debug;
84 static int showPercents;
85 static int showrc;
86 static int signIt;
87 static int test;
88 extern int _url_debug;
89 extern int _noDirTokens;
90 extern int _useDbiMajor;
91
92 static int showVersion;
93 extern const char * rpmNAME;
94 extern const char * rpmEVR;
95 extern int rpmFLAGS;
96
97 extern MacroContext rpmCLIMacroContext;
98
99 extern struct rpmBuildArguments         rpmBTArgs;
100
101 /* the structure describing the options we take and the defaults */
102 static struct poptOption optionsTable[] = {
103  { "addsign", '\0', 0, 0, GETOPT_ADDSIGN,       NULL, NULL},
104  { "allfiles", '\0', 0, &allFiles, 0,           NULL, NULL},
105  { "allmatches", '\0', 0, &allMatches, 0,       NULL, NULL},
106  { "badreloc", '\0', 0, &badReloc, 0,           NULL, NULL},
107  { "checksig", 'K', 0, 0, 'K',                  NULL, NULL},
108  { "define", '\0', POPT_ARG_STRING, 0, GETOPT_DEFINEMACRO,NULL, NULL},
109  { "dirtokens", '\0', POPT_ARG_VAL, &_noDirTokens, 0,   NULL, NULL},
110  { "erase", 'e', 0, 0, 'e',                     NULL, NULL},
111  { "eval", '\0', POPT_ARG_STRING, 0, GETOPT_EVALMACRO, NULL, NULL},
112  { "excludedocs", '\0', 0, &excldocs, 0,        NULL, NULL},
113  { "excludepath", '\0', POPT_ARG_STRING, 0, GETOPT_EXCLUDEPATH, NULL, NULL},
114  { "force", '\0', 0, &force, 0,                 NULL, NULL},
115  { "freshen", 'F', 0, 0, 'F',                   NULL, NULL},
116  { "ftpdebug", '\0', POPT_ARG_VAL, &_ftp_debug, -1,             NULL, NULL},
117  { "hash", 'h', 0, &showHash, 0,                NULL, NULL},
118  { "help", '\0', 0, &help, 0,                   NULL, NULL},
119  {  NULL, 'i', 0, 0, 'i',                       NULL, NULL},
120  { "ignorearch", '\0', 0, &ignoreArch, 0,       NULL, NULL},
121  { "ignoreos", '\0', 0, &ignoreOs, 0,           NULL, NULL},
122  { "ignoresize", '\0', 0, &ignoreSize, 0,       NULL, NULL},
123  { "includedocs", '\0', 0, &incldocs, 0,        NULL, NULL},
124  { "initdb", '\0', 0, &initdb, 0,               NULL, NULL},
125 /* info and install both using 'i' is dumb */
126  { "install", '\0', 0, 0, GETOPT_INSTALL,       NULL, NULL},
127  { "justdb", '\0', 0, &justdb, 0,               NULL, NULL},
128  { "macros", '\0', POPT_ARG_STRING, &macrofiles, 0,     NULL, NULL},
129  { "nodeps", '\0', 0, &noDeps, 0,               NULL, NULL},
130  { "nodirtokens", '\0', POPT_ARG_VAL, &_noDirTokens, 1, NULL, NULL},
131  { "nogpg", '\0', 0, &noGpg, 0,                 NULL, NULL},
132 #if HAVE_LIBIO_H && defined(_IO_BAD_SEEN)
133  { "nolibio", '\0', POPT_ARG_VAL, &noLibio, 1,          NULL, NULL},
134 #endif
135  { "nomd5", '\0', 0, &noMd5, 0,                 NULL, NULL},
136  { "noorder", '\0', 0, &noOrder, 0,             NULL, NULL},
137  { "nopgp", '\0', 0, &noPgp, 0,                 NULL, NULL},
138  { "noscripts", '\0', 0, &noScripts, 0,         NULL, NULL},
139  { "notriggers", '\0', 0, &noTriggers, 0,       NULL, NULL},
140  { "oldpackage", '\0', 0, &oldPackage, 0,       NULL, NULL},
141  { "percent", '\0', 0, &showPercents, 0,        NULL, NULL},
142  { "pipe", '\0', POPT_ARG_STRING, &pipeOutput, 0,       NULL, NULL},
143  { "prefix", '\0', POPT_ARG_STRING, &prefix, 0, NULL, NULL},
144  { "quiet", '\0', 0, &quiet, 0,                 NULL, NULL},
145 #ifndef DYING
146  { "rcfile", '\0', POPT_ARG_STRING, &rcfile, 0, NULL, NULL},
147 #else
148  { "rcfile", '\0', 0, 0, GETOPT_RCFILE,         NULL, NULL},
149 #endif
150  { "rebuilddb", '\0', 0, 0, GETOPT_REBUILDDB,   NULL, NULL},
151  { "relocate", '\0', POPT_ARG_STRING, 0, GETOPT_RELOCATE,       NULL, NULL},
152  { "replacefiles", '\0', 0, &replaceFiles, 0,   NULL, NULL},
153  { "replacepkgs", '\0', 0, &replacePackages, 0, NULL, NULL},
154  { "resign", '\0', 0, 0, GETOPT_RESIGN,         NULL, NULL},
155  { "root", 'r', POPT_ARG_STRING, &rootdir, 0,   NULL, NULL},
156  { "rpmiodebug", '\0', POPT_ARG_VAL, &_rpmio_debug, -1,         NULL, NULL},
157  { "showrc", '\0', 0, &showrc, GETOPT_SHOWRC,   NULL, NULL},
158  { "sign", '\0', 0, &signIt, 0,                 NULL, NULL},
159  { "test", '\0', 0, &test, 0,                   NULL, NULL},
160  { "upgrade", 'U', 0, 0, 'U',                   NULL, NULL},
161  { "urldebug", '\0', POPT_ARG_VAL, &_url_debug, -1,             NULL, NULL},
162  { "uninstall", 'u', 0, 0, 'u',                 NULL, NULL},
163  { "verbose", 'v', 0, 0, 'v',                   NULL, NULL},
164  { "version", '\0', 0, &showVersion, 0,         NULL, NULL},
165
166  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, 
167                 rpmQVSourcePoptTable, 0,        (void *) &rpmQVArgs, NULL },
168  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, 
169                 rpmQueryPoptTable, 0,           (void *) &rpmQVArgs, NULL },
170  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, 
171                 rpmVerifyPoptTable, 0,          (void *) &rpmQVArgs, NULL },
172
173  { NULL, '\0', POPT_ARG_INCLUDE_TABLE,
174                 rpmBuildPoptTable, 0,           (void *) &rpmBTArgs, NULL },
175
176  { 0, 0, 0, 0, 0,       NULL, NULL }
177 };
178
179 #ifdef __MINT__
180 /* MiNT cannot dynamically increase the stack.  */
181 long _stksize = 64 * 1024L;
182 #endif
183
184 static void argerror(const char * desc) {
185     fprintf(stderr, _("rpm: %s\n"), desc);
186     exit(EXIT_FAILURE);
187 }
188
189 static void printHelp(void);
190 static void printVersion(void);
191 static void printBanner(void);
192 static void printUsage(void);
193 static void printHelpLine(char * prefix, char * help);
194
195 static void printVersion(void) {
196     fprintf(stdout, _("RPM version %s\n"), rpmEVR);
197 }
198
199 static void printBanner(void) {
200     puts(_("Copyright (C) 1998-2000 - Red Hat, Inc."));
201     puts(_("This program may be freely redistributed under the terms of the GNU GPL"));
202 }
203
204 static void printUsage(void) {
205     printVersion();
206     printBanner();
207     puts("");
208
209     puts(_("Usage: rpm {--help}"));
210     puts(_("       rpm {--version}"));
211     puts(_("       rpm {--initdb}   [--dbpath <dir>]"));
212     puts(_("       rpm {--install -i} [-v] [--hash -h] [--percent] [--force] [--test]"));
213     puts(_("                        [--replacepkgs] [--replacefiles] [--root <dir>]"));
214     puts(_("                        [--excludedocs] [--includedocs] [--noscripts]"));
215     puts(_("                        [--rcfile <file>] [--ignorearch] [--dbpath <dir>]"));
216     puts(_("                        [--prefix <dir>] [--ignoreos] [--nodeps] [--allfiles]"));
217     puts(_("                        [--ftpproxy <host>] [--ftpport <port>]"));
218     puts(_("                        [--httpproxy <host>] [--httpport <port>]"));
219     puts(_("                        [--justdb] [--noorder] [--relocate oldpath=newpath]"));
220     puts(_("                        [--badreloc] [--notriggers] [--excludepath <path>]"));
221     puts(_("                        [--ignoresize] file1.rpm ... fileN.rpm"));
222     puts(_("       rpm {--upgrade -U} [-v] [--hash -h] [--percent] [--force] [--test]"));
223     puts(_("                        [--oldpackage] [--root <dir>] [--noscripts]"));
224     puts(_("                        [--excludedocs] [--includedocs] [--rcfile <file>]"));
225     puts(_("                        [--ignorearch]  [--dbpath <dir>] [--prefix <dir>] "));
226     puts(_("                        [--ftpproxy <host>] [--ftpport <port>]"));
227     puts(_("                        [--httpproxy <host>] [--httpport <port>] "));
228     puts(_("                        [--ignoreos] [--nodeps] [--allfiles] [--justdb]"));
229     puts(_("                        [--noorder] [--relocate oldpath=newpath]"));
230     puts(_("                        [--badreloc] [--excludepath <path>] [--ignoresize]"));
231     puts(_("                        file1.rpm ... fileN.rpm"));
232     puts(_("       rpm {--query -q} [-afpg] [-i] [-l] [-s] [-d] [-c] [-v] [-R]"));
233     puts(_("                        [--scripts] [--root <dir>] [--rcfile <file>]"));
234     puts(_("                        [--whatprovides] [--whatrequires] [--requires]"));
235     puts(_("                        [--triggeredby]"));
236     puts(_("                        [--ftpproxy <host>] [--ftpport <port>]"));
237     puts(_("                        [--httpproxy <host>] [--httpport <port>]"));
238     puts(_("                        [--provides] [--triggers] [--dump]"));
239     puts(_("                        [--changelog] [--dbpath <dir>] [targets]"));
240     puts(_("       rpm {--verify -V -y} [-afpg] [--root <dir>] [--rcfile <file>]"));
241     puts(_("                        [--dbpath <dir>] [--nodeps] [--nofiles] [--noscripts]"));
242     puts(_("                        [--nomd5] [targets]"));
243     puts(_("       rpm {--setperms} [-afpg] [target]"));
244     puts(_("       rpm {--setugids} [-afpg] [target]"));
245     puts(_("       rpm {--freshen -F} file1.rpm ... fileN.rpm"));
246     puts(_("       rpm {--erase -e} [--root <dir>] [--noscripts] [--rcfile <file>]"));
247     puts(_("                        [--dbpath <dir>] [--nodeps] [--allmatches]"));
248     puts(_("                        [--justdb] [--notriggers] package1 ... packageN"));
249     puts(_("       rpm {--resign} [--rcfile <file>] package1 package2 ... packageN"));
250     puts(_("       rpm {--addsign} [--rcfile <file>] package1 package2 ... packageN"));
251     puts(_("       rpm {--checksig -K} [--nopgp] [--nogpg] [--nomd5] [--rcfile <file>]"));
252     puts(_("                           package1 ... packageN"));
253     puts(_("       rpm {--rebuilddb} [--rcfile <file>] [--dbpath <dir>]"));
254     puts(_("       rpm {--querytags}"));
255 }
256
257 static void printHelpLine(char * prefix, char * help) {
258     int indentLength = strlen(prefix) + 3;
259     int lineLength = 79 - indentLength;
260     int helpLength = strlen(help);
261     char * ch;
262     char format[64];
263
264     fprintf(stdout, "%s - ", prefix);
265
266     while (helpLength > lineLength) {
267         ch = help + lineLength - 1;
268         while (ch > help && !isspace(*ch)) ch--;
269         if (ch == help) break;          /* give up */
270         while (ch > (help + 1) && isspace(*ch)) ch--;
271         ch++;
272
273         sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
274         fprintf(stdout, format, help, " ");
275         help = ch;
276         while (isspace(*help) && *help) help++;
277         helpLength = strlen(help);
278     }
279
280     if (helpLength) puts(help);
281 }
282
283 static void printHelp(void) {
284     printVersion();
285     printBanner();
286     puts("");
287
288     puts(         _("Usage:"));
289     printHelpLine(  "   --help                 ", 
290                   _("print this message"));
291     printHelpLine(  "   --version              ",
292                   _("print the version of rpm being used"));
293
294     puts("");
295     puts(         _("   All modes support the following arguments:"));
296     printHelpLine(_("    --define '<name> <body>'"),
297                   _("define macro <name> with value <body>"));
298     printHelpLine(_("    --eval '<name>+'      "),
299                   _("print the expansion of macro <name> to stdout"));
300     printHelpLine(_("    --pipe <cmd>          "),
301                   _("send stdout to <cmd>"));
302     printHelpLine(_("    --rcfile <file>       "),
303                   _("use <file> instead of /etc/rpmrc and $HOME/.rpmrc"));
304     printHelpLine(  "    --showrc              ",
305                   _("display final rpmrc and macro configuration"));
306     printHelpLine(  "     -v                   ",
307                   _("be a little more verbose"));
308     printHelpLine(  "     -vv                  ",
309                   _("be incredibly verbose (for debugging)"));
310
311     puts("");
312     puts(         _("   Install, upgrade and query (with -p) allow URL's to be used in place"));
313     puts(         _("   of file names as well as the following options:"));
314     printHelpLine(_("      --ftpproxy <host>   "),
315                   _("hostname or IP of ftp proxy"));
316     printHelpLine(_("      --ftpport <port>    "),
317                   _("port number of ftp server (or proxy)"));
318     printHelpLine(_("      --httpproxy <host>  "),
319                   _("hostname or IP of http proxy"));
320     printHelpLine(_("      --httpport <port>   "),
321                   _("port number of http server (or proxy)"));
322
323     puts("");
324     printHelpLine(  "   -q, --query            ",
325                   _("query mode"));
326     printHelpLine(_("      --dbpath <dir>      "),
327                   _("use <dir> as the directory for the database"));
328     printHelpLine(_("      --queryformat <qfmt>"),
329                   _("use <qfmt> as the header format (implies --info)"));
330     printHelpLine(_("      --root <dir>        "),
331                   _("use <dir> as the top level directory"));
332     puts(         _("      Package specification options:"));
333     printHelpLine(  "        -a, --all         ",
334                   _("query all packages"));
335     printHelpLine(_("        -f <file>+        "),
336                   _("query package owning <file>"));
337     printHelpLine(_("        -p <packagefile>+ "),
338                   _("query (uninstalled) package <packagefile>"));
339     printHelpLine(_("        --triggeredby <pkg>"),
340                   _("query packages triggered by <pkg>"));
341     printHelpLine(_("        --whatprovides <cap>"),
342                   _("query packages which provide <cap> capability"));
343     printHelpLine(_("        --whatrequires <cap>"),
344                   _("query packages which require <cap> capability"));
345     puts(         _("      Information selection options:"));
346     printHelpLine(  "        -i, --info        ",
347                   _("display package information"));
348     printHelpLine(  "        --changelog       ",
349                   _("display the package's change log"));
350     printHelpLine(  "        -l                ",
351                   _("display package file list"));
352     printHelpLine(  "        -s                ",
353                   _("show file states (implies -l)"));
354     printHelpLine(  "        -d                ",
355                   _("list only documentation files (implies -l)"));
356     printHelpLine(  "        -c                ",
357                   _("list only configuration files (implies -l)"));
358     printHelpLine(  "        --dump            ",
359                   _("show all verifiable information for each file (must be used with -l, -c, or -d)"));
360     printHelpLine(  "        --provides        ",
361                   _("list capabilities package provides"));
362     printHelpLine(  "        -R, --requires    ",
363                   _("list package dependencies"));
364     printHelpLine(  "        --scripts         ",
365                   _("print the various [un]install scripts"));
366     printHelpLine(  "        --triggers        ",
367                   _("show the trigger scripts contained in the package"));
368
369     puts("");
370     printHelpLine(  "    -V, -y, --verify      ",
371                   _("verify a package installation using the same same package specification options as -q"));
372     printHelpLine(_("      --dbpath <dir>      "),
373                   _("use <dir> as the directory for the database"));
374     printHelpLine(_("      --root <dir>        "),
375                   _("use <dir> as the top level directory"));
376     printHelpLine(  "      --nodeps            ",
377                   _("do not verify package dependencies"));
378     printHelpLine(  "      --nomd5             ",
379                   _("do not verify file md5 checksums"));
380     printHelpLine(  "      --nofiles           ",
381                   _("do not verify file attributes"));
382     printHelpLine(  "    --querytags           ",
383                   _("list the tags that can be used in a query format"));
384
385     puts("");
386     puts(         _("    --install <packagefile>"));
387     printHelpLine(_("    -i <packagefile>      "),
388                   _("install package"));
389     printHelpLine(_("      --excludepath <path>"),
390                   _("skip files in path <path>"));
391     printHelpLine(_("      --relocate <oldpath>=<newpath>"),
392                   _("relocate files from <oldpath> to <newpath>"));
393     printHelpLine(  "      --badreloc          ",
394                   _("relocate files in non-relocateable package"));
395     printHelpLine(_("      --prefix <dir>      "),
396                   _("relocate the package to <dir>, if relocatable"));
397     printHelpLine(_("      --dbpath <dir>      "),
398                   _("use <dir> as the directory for the database"));
399     printHelpLine(  "      --excludedocs       ",
400                   _("do not install documentation"));
401     printHelpLine(  "      --force             ",
402                   _("short hand for --replacepkgs --replacefiles"));
403     printHelpLine(  "      -h, --hash          ",
404                   _("print hash marks as package installs (good with -v)"));
405     printHelpLine(  "      --allfiles          ",
406                   _("install all files, even configurations which might "
407                     "otherwise be skipped"));
408     printHelpLine(  "      --ignorearch        ",
409                   _("don't verify package architecture"));
410     printHelpLine(  "      --ignoresize        ",
411                   _("don't check disk space before installing"));
412     printHelpLine(  "      --ignoreos          ",
413                   _("don't verify package operating system"));
414     printHelpLine(  "      --includedocs       ",
415                   _("install documentation"));
416     printHelpLine(  "      --justdb            ",
417                   _("update the database, but do not modify the filesystem"));
418     printHelpLine(  "      --nodeps            ",
419                   _("do not verify package dependencies"));
420     printHelpLine(  "      --noorder           ",
421                   _("do not reorder package installation to satisfy dependencies"));
422     printHelpLine(  "      --noscripts         ",
423                   _("don't execute any installation scripts"));
424     printHelpLine(  "      --notriggers        ",
425                   _("don't execute any scripts triggered by this package"));
426     printHelpLine(  "      --percent           ",
427                   _("print percentages as package installs"));
428     printHelpLine(  "      --replacefiles      ",
429                   _("install even if the package replaces installed files"));
430     printHelpLine(  "      --replacepkgs       ",
431                   _("reinstall if the package is already present"));
432     printHelpLine(_("      --root <dir>        "),
433                   _("use <dir> as the top level directory"));
434     printHelpLine(  "      --test              ",
435                   _("don't install, but tell if it would work or not"));
436
437     puts("");
438     puts(         _("    --upgrade <packagefile>"));
439     printHelpLine(_("    -U <packagefile>      "),
440                   _("upgrade package (same options as --install, plus)"));
441     printHelpLine(  "      --oldpackage        ",
442                   _("upgrade to an old version of the package (--force on upgrades does this automatically)"));
443     puts("");
444     puts(         _("    --erase <package>"));
445     printHelpLine(  "    -e <package>          ",
446                   _("erase (uninstall) package"));
447     printHelpLine(  "      --allmatches        ",
448                   _("remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)"));
449     printHelpLine(_("      --dbpath <dir>      "),
450                   _("use <dir> as the directory for the database"));
451     printHelpLine(  "      --justdb            ",
452                   _("update the database, but do not modify the filesystem"));
453     printHelpLine(  "      --nodeps            ",
454                   _("do not verify package dependencies"));
455     printHelpLine(  "      --noorder           ",
456                   _("do not reorder package installation to satisfy dependencies"));
457     printHelpLine(  "      --noscripts         ",
458                   _("do not execute any package specific scripts"));
459     printHelpLine(  "      --notriggers        ",
460                   _("don't execute any scripts triggered by this package"));
461     printHelpLine(_("      --root <dir>        "),
462                   _("use <dir> as the top level directory"));
463     puts("");
464     puts(         _("    -b<stage> <spec>      "));
465     printHelpLine(_("    -t<stage> <tarball>   "),
466                   _("build package, where <stage> is one of:"));
467     printHelpLine(  "          p               ",
468                   _("prep (unpack sources and apply patches)"));
469     printHelpLine(  "          l               ",
470                   _("list check (do some cursory checks on %files)"));
471     printHelpLine(  "          c               ",
472                   _("compile (prep and compile)"));
473     printHelpLine(  "          i               ",
474                   _("install (prep, compile, install)"));
475     printHelpLine(  "          b               ",
476                   _("binary package (prep, compile, install, package)"));
477     printHelpLine(  "          a               ",
478                   _("bin/src package (prep, compile, install, package)"));
479     printHelpLine(  "      --short-circuit     ",
480                   _("skip straight to specified stage (only for c,i)"));
481     printHelpLine(  "      --clean             ",
482                   _("remove build tree when done"));
483     printHelpLine(  "      --rmsource          ",
484                   _("remove sources when done"));
485     printHelpLine(  "      --rmspec            ",
486                   _("remove spec file when done"));
487     printHelpLine(  "      --sign              ",
488                   _("generate PGP/GPG signature"));
489     printHelpLine(_("      --buildroot <dir>   "),
490                   _("use <dir> as the build root"));
491     printHelpLine(_("      --target=<platform>+"),
492                   _("build the packages for the build targets platform1...platformN."));
493     printHelpLine(  "      --nobuild           ",
494                   _("do not execute any stages"));
495     printHelpLine(_("      --timecheck <secs>  "),
496                   _("set the time check to <secs> seconds (0 disables)"));
497     puts("");
498     printHelpLine(_("    --rebuild <src_pkg>   "),
499                   _("install source package, build binary package and remove spec file, sources, patches, and icons."));
500     printHelpLine(_("    --recompile <src_pkg> "),
501                   _("like --rebuild, but don't build any package"));
502
503     puts("");
504     printHelpLine(_("    --resign <pkg>+       "),
505                   _("sign a package (discard current signature)"));
506     printHelpLine(_("    --addsign <pkg>+      "),
507                   _("add a signature to a package"));
508     puts(         _("    --checksig <pkg>+"));
509     printHelpLine(_("    -K <pkg>+             "),
510                   _("verify package signature"));
511     printHelpLine(  "      --nopgp             ",
512                   _("skip any PGP signatures"));
513     printHelpLine(  "      --nogpg             ",
514                   _("skip any GPG signatures"));
515     printHelpLine(  "      --nomd5             ",
516                   _("skip any MD5 signatures"));
517
518     puts("");
519     printHelpLine(  "    --initdb              ",
520                   _("make sure a valid database exists"));
521     printHelpLine(  "    --rebuilddb           ",
522                   _("rebuild database from existing database"));
523     printHelpLine(_("      --dbpath <dir>      "),
524                   _("use <dir> as the directory for the database"));
525     printHelpLine(  "      --root <dir>        ",
526                   _("use <dir> as the top level directory"));
527
528     puts("");
529     printHelpLine(  "    --setperms            ",
530                   _("set the file permissions to those in the package database"
531                     " using the same package specification options as -q"));
532     printHelpLine(  "    --setugids            ",
533                   _("set the file owner and group to those in the package "
534                     "database using the same package specification options as "
535                     "-q"));
536 }
537
538 int main(int argc, const char ** argv)
539 {
540     enum modes bigMode = MODE_UNKNOWN;
541     QVA_t *qva = &rpmQVArgs;
542     int arg;
543     int installFlags = 0, uninstallFlags = 0, interfaceFlags = 0;
544     int verifyFlags;
545     int checksigFlags = 0;
546     rpmResignFlags addSign = RESIGN_NEW_SIGNATURE;
547     char * passPhrase = "";
548     const char * optArg;
549     pid_t pipeChild = 0;
550     const char * pkg;
551     char * errString = NULL;
552     poptContext optCon;
553     int ec = 0;
554     int status;
555     int p[2];
556     rpmRelocation * relocations = NULL;
557     int numRelocations = 0;
558     int sigTag;
559     int upgrade = 0;
560     int freshen = 0;
561     int probFilter = 0;
562         
563 #if HAVE_MCHECK_H && HAVE_MTRACE
564     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
565 #endif
566     setprogname(argv[0]);       /* Retrofit glibc __progname */
567
568     /* set the defaults for the various command line options */
569     allFiles = 0;
570     allMatches = 0;
571     badReloc = 0;
572     excldocs = 0;
573     force = 0;
574     _ftp_debug = 0;
575     showHash = 0;
576     help = 0;
577     ignoreArch = 0;
578     ignoreOs = 0;
579     ignoreSize = 0;
580     incldocs = 0;
581     initdb = 0;
582     justdb = 0;
583     noDeps = 0;
584     noGpg = 0;
585 #if HAVE_LIBIO_H && defined(_IO_BAD_SEEN)
586     noLibio = 0;
587 #else
588     noLibio = 1;
589 #endif
590     noMd5 = 0;
591     noOrder = 0;
592     noPgp = 0;
593     noScripts = 0;
594     noTriggers = 0;
595     noUsageMsg = 0;
596     oldPackage = 0;
597     showPercents = 0;
598     pipeOutput = NULL;
599     prefix = NULL;
600     quiet = 0;
601     _rpmio_debug = 0;
602     replaceFiles = 0;
603     replacePackages = 0;
604     rootdir = "/";
605     showrc = 0;
606     signIt = 0;
607     showVersion = 0;
608     specedit = 0;
609     test = 0;
610     _url_debug = 0;
611
612     /* XXX Eliminate query linkage loop */
613     parseSpecVec = parseSpec;
614     freeSpecVec = freeSpec;
615
616     /* set up the correct locale */
617     setlocale(LC_ALL, "" );
618
619 #ifdef  __LCLINT__
620 #define LOCALEDIR       "/usr/share/locale"
621 #endif
622     bindtextdomain(PACKAGE, LOCALEDIR);
623     textdomain(PACKAGE);
624
625     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
626
627     /* Make a first pass through the arguments, looking for --rcfile */
628     /* We need to handle that before dealing with the rest of the arguments. */
629     optCon = poptGetContext("rpm", argc, argv, optionsTable, 0);
630     poptReadConfigFile(optCon, LIBRPMALIAS_FILENAME);
631     poptReadDefaultConfig(optCon, 1);
632     poptSetExecPath(optCon, RPMCONFIGDIR, 1);
633
634     /* reading rcfile early makes it easy to override */
635     /* XXX only --rcfile (and --showrc) need this pre-parse */
636
637     while ((arg = poptGetNextOpt(optCon)) > 0) {
638         switch(arg) {
639         case 'v':
640             rpmIncreaseVerbosity();     /* XXX silly use by showrc */
641             break;
642         default:
643             break;
644       }
645     }
646
647     if (rpmReadConfigFiles(rcfile, NULL))  
648         exit(EXIT_FAILURE);
649
650     if (showrc) {
651         rpmShowRC(stdout);
652         exit(EXIT_SUCCESS);
653     }
654
655     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
656
657     poptResetContext(optCon);
658
659     if (qva->qva_queryFormat) free((void *)qva->qva_queryFormat);
660     memset(qva, 0, sizeof(*qva));
661     qva->qva_source = RPMQV_PACKAGE;
662     qva->qva_mode = ' ';
663     qva->qva_char = ' ';
664
665     while ((arg = poptGetNextOpt(optCon)) > 0) {
666         optArg = poptGetOptArg(optCon);
667
668         switch (arg) {
669           case 'K':
670             if (bigMode != MODE_UNKNOWN && bigMode != MODE_CHECKSIG)
671                 argerror(_("only one major mode may be specified"));
672             bigMode = MODE_CHECKSIG;
673             break;
674             
675           case 'u':
676             if (bigMode != MODE_UNKNOWN && bigMode != MODE_UNINSTALL)
677                 argerror(_("only one major mode may be specified"));
678             bigMode = MODE_UNINSTALL;
679             rpmMessage(RPMMESS_ERROR, _("-u and --uninstall are deprecated and no"
680                     " longer work.\n"));
681             rpmMessage(RPMMESS_ERROR, _("Use -e or --erase instead.\n"));
682             exit(EXIT_FAILURE);
683         
684           case 'e':
685             if (bigMode != MODE_UNKNOWN && bigMode != MODE_UNINSTALL)
686                 argerror(_("only one major mode may be specified"));
687             bigMode = MODE_UNINSTALL;
688             break;
689         
690           case 'v':
691             rpmIncreaseVerbosity();
692             break;
693
694           case 'i':
695             if (bigMode == MODE_QUERY) {
696                 const char * infoCommand[] = { "--info", NULL };
697                 poptStuffArgs(optCon, infoCommand);
698             } else if (bigMode == MODE_INSTALL)
699                 /*@-ifempty@*/ ;
700             else if (bigMode == MODE_UNKNOWN) {
701                 const char * installCommand[] = { "--install", NULL };
702                 poptStuffArgs(optCon, installCommand);
703             }
704             break;
705
706           case GETOPT_INSTALL:
707             if (bigMode != MODE_UNKNOWN && bigMode != MODE_INSTALL)
708                 argerror(_("only one major mode may be specified"));
709             bigMode = MODE_INSTALL;
710             break;
711
712           case 'U':
713             if (bigMode != MODE_UNKNOWN && bigMode != MODE_INSTALL)
714                 argerror(_("only one major mode may be specified"));
715             bigMode = MODE_INSTALL;
716             upgrade = 1;
717             break;
718
719           case 'F':
720             if (bigMode != MODE_UNKNOWN && bigMode != MODE_INSTALL)
721                 argerror(_("only one major mode may be specified"));
722             bigMode = MODE_INSTALL;
723             upgrade = 1;  /* Freshen implies upgrade */
724             freshen = 1;
725             break;
726
727           case GETOPT_RESIGN:
728             if (bigMode != MODE_UNKNOWN && bigMode != MODE_RESIGN)
729                 argerror(_("only one major mode may be specified"));
730             bigMode = MODE_RESIGN;
731             addSign = RESIGN_NEW_SIGNATURE;
732             signIt = 1;
733             break;
734
735           case GETOPT_ADDSIGN:
736             if (bigMode != MODE_UNKNOWN && bigMode != MODE_RESIGN)
737                 argerror(_("only one major mode may be specified"));
738             bigMode = MODE_RESIGN;
739             addSign = RESIGN_ADD_SIGNATURE;
740             signIt = 1;
741             break;
742
743           case GETOPT_DEFINEMACRO:
744             rpmDefineMacro(NULL, optArg, RMIL_CMDLINE);
745             rpmDefineMacro(&rpmCLIMacroContext, optArg, RMIL_CMDLINE);
746             noUsageMsg = 1;
747             break;
748
749           case GETOPT_EVALMACRO:
750           { const char *val = rpmExpand(optArg, NULL);
751             fprintf(stdout, "%s\n", val);
752             free((void *)val);
753             noUsageMsg = 1;
754           } break;
755
756           case GETOPT_REBUILDDB:
757             if (bigMode != MODE_UNKNOWN && bigMode != MODE_REBUILDDB)
758                 argerror(_("only one major mode may be specified"));
759             bigMode = MODE_REBUILDDB;
760             break;
761
762           case GETOPT_RELOCATE:
763             if (*optArg != '/') 
764                 argerror(_("relocations must begin with a /"));
765             if (!(errString = strchr(optArg, '=')))
766                 argerror(_("relocations must contain a ="));
767             *errString++ = '\0';
768             if (*errString != '/') 
769                 argerror(_("relocations must have a / following the ="));
770             relocations = xrealloc(relocations, 
771                                   sizeof(*relocations) * (numRelocations + 1));
772             relocations[numRelocations].oldPath = optArg;
773             relocations[numRelocations++].newPath = errString;
774             break;
775
776           case GETOPT_EXCLUDEPATH:
777             if (*optArg != '/') 
778                 argerror(_("exclude paths must begin with a /"));
779
780             relocations = xrealloc(relocations, 
781                                   sizeof(*relocations) * (numRelocations + 1));
782             relocations[numRelocations].oldPath = optArg;
783             relocations[numRelocations++].newPath = NULL;
784             break;
785
786           case GETOPT_RCFILE:
787             fprintf(stderr, _("The --rcfile option has been eliminated.\n"));
788             fprintf(stderr, _("Use --macros with a colon separated list of macro files to read.\n"));
789             exit(EXIT_FAILURE);
790             /*@notreached@*/ break;
791
792           default:
793             fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
794             exit(EXIT_FAILURE);
795         }
796     }
797
798     if (quiet)
799         rpmSetVerbosity(RPMMESS_QUIET);
800
801     if (showVersion) printVersion();
802     if (help) printHelp();
803
804     if (arg < -1) {
805         fprintf(stderr, "%s: %s\n", 
806                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
807                 poptStrerror(arg));
808         exit(EXIT_FAILURE);
809     }
810
811     if (bigMode == MODE_UNKNOWN && qva->qva_mode != ' ') {
812         switch (qva->qva_mode) {
813         case 'q':       bigMode = MODE_QUERY;           break;
814         case 'V':       bigMode = MODE_VERIFY;          break;
815         case 'Q':       bigMode = MODE_QUERYTAGS;       break;
816         }
817     }
818
819     if (initdb) {
820         if (bigMode != MODE_UNKNOWN) 
821             argerror(_("only one major mode may be specified"));
822         else
823             bigMode = MODE_INITDB;
824     }
825
826     if (qva->qva_sourceCount) {
827         if (qva->qva_sourceCount > 1)
828             argerror(_("one type of query/verify may be performed at a "
829                         "time"));
830     }
831
832     if (qva->qva_flags && (bigMode & ~MODES_QV)) 
833         argerror(_("unexpected query flags"));
834
835     if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
836         argerror(_("unexpected query format"));
837
838     if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
839         argerror(_("unexpected query source"));
840
841     if (!(bigMode == MODE_INSTALL) && force)
842         argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
843
844     if (bigMode != MODE_INSTALL && badReloc)
845         argerror(_("files may only be relocated during package installation"));
846
847     if (relocations && prefix)
848         argerror(_("only one of --prefix or --relocate may be used"));
849
850     if (bigMode != MODE_INSTALL && relocations)
851         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
852
853     if (bigMode != MODE_INSTALL && prefix)
854         argerror(_("--prefix may only be used when installing new packages"));
855
856     if (prefix && prefix[0] != '/') 
857         argerror(_("arguments to --prefix must begin with a /"));
858
859     if (bigMode != MODE_INSTALL && showHash)
860         argerror(_("--hash (-h) may only be specified during package "
861                         "installation"));
862
863     if (bigMode != MODE_INSTALL && showPercents)
864         argerror(_("--percent may only be specified during package "
865                         "installation"));
866
867     if (bigMode != MODE_INSTALL && replaceFiles)
868         argerror(_("--replacefiles may only be specified during package "
869                         "installation"));
870
871     if (bigMode != MODE_INSTALL && replacePackages)
872         argerror(_("--replacepkgs may only be specified during package "
873                         "installation"));
874
875     if (bigMode != MODE_INSTALL && excldocs)
876         argerror(_("--excludedocs may only be specified during package "
877                    "installation"));
878
879     if (bigMode != MODE_INSTALL && incldocs)
880         argerror(_("--includedocs may only be specified during package "
881                    "installation"));
882
883     if (excldocs && incldocs)
884         argerror(_("only one of --excludedocs and --includedocs may be "
885                  "specified"));
886   
887     if (bigMode != MODE_INSTALL && ignoreArch)
888         argerror(_("--ignorearch may only be specified during package "
889                    "installation"));
890
891     if (bigMode != MODE_INSTALL && ignoreOs)
892         argerror(_("--ignoreos may only be specified during package "
893                    "installation"));
894
895     if (bigMode != MODE_INSTALL && ignoreSize)
896         argerror(_("--ignoresize may only be specified during package "
897                    "installation"));
898
899     if (allMatches && bigMode != MODE_UNINSTALL)
900         argerror(_("--allmatches may only be specified during package "
901                    "erasure"));
902
903     if (allFiles && bigMode != MODE_INSTALL)
904         argerror(_("--allfiles may only be specified during package "
905                    "installation"));
906
907     if (justdb && bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL)
908         argerror(_("--justdb may only be specified during package "
909                    "installation and erasure"));
910
911     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && 
912         bigMode != MODE_VERIFY && noScripts)
913         argerror(_("--noscripts may only be specified during package "
914                    "installation, erasure, and verification"));
915
916     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && noTriggers)
917         argerror(_("--notriggers may only be specified during package "
918                    "installation, erasure, and verification"));
919
920     if (noDeps & (bigMode & ~MODES_FOR_NODEPS))
921         argerror(_("--nodeps may only be specified during package "
922                    "building, rebuilding, recompilation, installation,"
923                    "erasure, and verification"));
924
925     if (test && (bigMode & ~MODES_FOR_TEST))
926         argerror(_("--test may only be specified during package installation, "
927                  "erasure, and building"));
928
929     if (rootdir[1] && (bigMode & ~MODES_FOR_ROOT))
930         argerror(_("--root (-r) may only be specified during "
931                  "installation, erasure, querying, and "
932                  "database rebuilds"));
933
934     if (rootdir) {
935         switch (urlIsURL(rootdir)) {
936         default:
937             if (bigMode & MODES_FOR_ROOT)
938                 break;
939             /*@fallthrough@*/
940         case URL_IS_UNKNOWN:
941             if (rootdir[0] != '/')
942                 argerror(_("arguments to --root (-r) must begin with a /"));
943             break;
944         }
945     }
946
947     if (oldPackage && !upgrade)
948         argerror(_("--oldpackage may only be used during upgrades"));
949
950     if (noPgp && bigMode != MODE_CHECKSIG)
951         argerror(_("--nopgp may only be used during signature checking"));
952
953     if (noGpg && bigMode != MODE_CHECKSIG)
954         argerror(_("--nogpg may only be used during signature checking"));
955
956     if (noMd5 && bigMode != MODE_CHECKSIG && bigMode != MODE_VERIFY)
957         argerror(_("--nomd5 may only be used during signature checking and "
958                    "package verification"));
959
960     if (signIt) {
961         if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
962             bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD) {
963             const char ** argv;
964             struct stat sb;
965             int errors = 0;
966
967             if ((argv = poptGetArgs(optCon)) == NULL) {
968                 fprintf(stderr, _("no files to sign\n"));
969                 errors++;
970             } else
971             while (*argv) {
972                 if (stat(*argv, &sb)) {
973                     fprintf(stderr, _("cannot access file %s\n"), *argv);
974                     errors++;
975                 }
976                 argv++;
977             }
978
979             if (errors) return errors;
980
981             if (poptPeekArg(optCon)) {
982                 switch (sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) {
983                   case 0:
984                     break;
985                   case RPMSIGTAG_PGP:
986                     if ((sigTag == RPMSIGTAG_PGP || sigTag == RPMSIGTAG_PGP5) &&
987                         !rpmDetectPGPVersion(NULL)) {
988                         fprintf(stderr, _("pgp not found: "));
989                         exit(EXIT_FAILURE);
990                     }   /*@fallthrough@*/
991                   case RPMSIGTAG_GPG:
992                     passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
993                     if (passPhrase == NULL) {
994                         fprintf(stderr, _("Pass phrase check failed\n"));
995                         exit(EXIT_FAILURE);
996                     }
997                     fprintf(stderr, _("Pass phrase is good.\n"));
998                     passPhrase = xstrdup(passPhrase);
999                     break;
1000                   default:
1001                     fprintf(stderr,
1002                             _("Invalid %%_signature spec in macro file.\n"));
1003                     exit(EXIT_FAILURE);
1004                     /*@notreached@*/ break;
1005                 }
1006             }
1007         } else {
1008             argerror(_("--sign may only be used during package building"));
1009         }
1010     } else {
1011         /* Make rpmLookupSignatureType() return 0 ("none") from now on */
1012         rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
1013     }
1014
1015     if (pipeOutput) {
1016         pipe(p);
1017
1018         if (!(pipeChild = fork())) {
1019             close(p[1]);
1020             dup2(p[0], STDIN_FILENO);
1021             close(p[0]);
1022             execl("/bin/sh", "/bin/sh", "-c", pipeOutput, NULL);
1023             fprintf(stderr, _("exec failed\n"));
1024         }
1025
1026         close(p[0]);
1027         dup2(p[1], STDOUT_FILENO);
1028         close(p[1]);
1029     }
1030         
1031     switch (bigMode) {
1032       case MODE_UNKNOWN:
1033         if (!showVersion && !help && !noUsageMsg) printUsage();
1034         break;
1035
1036       case MODE_REBUILDDB:
1037         ec = rpmdbRebuild(rootdir);
1038         break;
1039
1040       case MODE_QUERYTAGS:
1041         if (argc != 2)
1042             argerror(_("unexpected arguments to --querytags "));
1043
1044         rpmDisplayQueryTags(stdout);
1045         break;
1046
1047       case MODE_INITDB:
1048         rpmdbInit(rootdir, 0644);
1049         break;
1050
1051       case MODE_CHECKSIG:
1052         if (!poptPeekArg(optCon))
1053             argerror(_("no packages given for signature check"));
1054         if (!noPgp) checksigFlags |= CHECKSIG_PGP;
1055         if (!noGpg) checksigFlags |= CHECKSIG_GPG;
1056         if (!noMd5) checksigFlags |= CHECKSIG_MD5;
1057         ec = rpmCheckSig(checksigFlags, (const char **)poptGetArgs(optCon));
1058         /* XXX don't overflow single byte exit status */
1059         if (ec > 255) ec = 255;
1060         break;
1061
1062       case MODE_RESIGN:
1063         if (!poptPeekArg(optCon))
1064             argerror(_("no packages given for signing"));
1065         ec = rpmReSign(addSign, passPhrase, (const char **)poptGetArgs(optCon));
1066         /* XXX don't overflow single byte exit status */
1067         if (ec > 255) ec = 255;
1068         break;
1069         
1070       case MODE_REBUILD:
1071       case MODE_RECOMPILE:
1072         break;
1073
1074       case MODE_BUILD:
1075       case MODE_TARBUILD:
1076         break;
1077
1078       case MODE_UNINSTALL:
1079         if (!poptPeekArg(optCon))
1080             argerror(_("no packages given for uninstall"));
1081
1082         if (noScripts) uninstallFlags |= RPMTRANS_FLAG_NOSCRIPTS;
1083         if (noTriggers) uninstallFlags |= RPMTRANS_FLAG_NOTRIGGERS;
1084         if (test) uninstallFlags |= RPMTRANS_FLAG_TEST;
1085         if (justdb) uninstallFlags |= RPMTRANS_FLAG_JUSTDB;
1086         if (noDeps) interfaceFlags |= UNINSTALL_NODEPS;
1087         if (allMatches) interfaceFlags |= UNINSTALL_ALLMATCHES;
1088
1089         ec = rpmErase(rootdir, (const char **)poptGetArgs(optCon), 
1090                          uninstallFlags, interfaceFlags);
1091         break;
1092
1093       case MODE_INSTALL:
1094         if (force) {
1095             probFilter |= RPMPROB_FILTER_REPLACEPKG | 
1096                           RPMPROB_FILTER_REPLACEOLDFILES |
1097                           RPMPROB_FILTER_REPLACENEWFILES |
1098                           RPMPROB_FILTER_OLDPACKAGE;
1099         }
1100         if (replaceFiles) probFilter |= RPMPROB_FILTER_REPLACEOLDFILES |
1101                                         RPMPROB_FILTER_REPLACENEWFILES;
1102         if (badReloc) probFilter |= RPMPROB_FILTER_FORCERELOCATE;
1103         if (replacePackages) probFilter |= RPMPROB_FILTER_REPLACEPKG;
1104         if (oldPackage) probFilter |= RPMPROB_FILTER_OLDPACKAGE;
1105         if (ignoreArch) probFilter |= RPMPROB_FILTER_IGNOREARCH; 
1106         if (ignoreOs) probFilter |= RPMPROB_FILTER_IGNOREOS;
1107         if (ignoreSize) probFilter |= RPMPROB_FILTER_DISKSPACE;
1108
1109         if (test) installFlags |= RPMTRANS_FLAG_TEST;
1110         /* RPMTRANS_FLAG_BUILD_PROBS */
1111         if (noScripts) installFlags |= RPMTRANS_FLAG_NOSCRIPTS;
1112         if (justdb) installFlags |= RPMTRANS_FLAG_JUSTDB;
1113         if (noTriggers) installFlags |= RPMTRANS_FLAG_NOTRIGGERS;
1114         if (!incldocs) {
1115             if (excldocs)
1116                 installFlags |= RPMTRANS_FLAG_NODOCS;
1117             else if (rpmExpandNumeric("%{_excludedocs}"))
1118                 installFlags |= RPMTRANS_FLAG_NODOCS;
1119         }
1120         if (allFiles) installFlags |= RPMTRANS_FLAG_ALLFILES;
1121         /* RPMTRANS_FLAG_KEEPOBSOLETE */
1122
1123         if (showPercents) interfaceFlags |= INSTALL_PERCENT;
1124         if (showHash) interfaceFlags |= INSTALL_HASH;
1125         if (noDeps) interfaceFlags |= INSTALL_NODEPS;
1126         if (noOrder) interfaceFlags |= INSTALL_NOORDER;
1127         if (upgrade) interfaceFlags |= INSTALL_UPGRADE;
1128         if (freshen) interfaceFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN);
1129
1130         if (!poptPeekArg(optCon))
1131             argerror(_("no packages given for install"));
1132
1133         /* we've already ensured !(!prefix && !relocations) */
1134         if (prefix) {
1135             relocations = alloca(2 * sizeof(*relocations));
1136             relocations[0].oldPath = NULL;   /* special case magic */
1137             relocations[0].newPath = prefix;
1138             relocations[1].oldPath = relocations[1].newPath = NULL;
1139         } else if (relocations) {
1140             relocations = xrealloc(relocations, 
1141                                   sizeof(*relocations) * (numRelocations + 1));
1142             relocations[numRelocations].oldPath = NULL;
1143             relocations[numRelocations].newPath = NULL;
1144         }
1145
1146         ec += rpmInstall(rootdir, (const char **)poptGetArgs(optCon), 
1147                         installFlags, interfaceFlags, probFilter, relocations);
1148         break;
1149
1150       case MODE_QUERY:
1151         qva->qva_prefix = rootdir;
1152         if (qva->qva_source == RPMQV_ALL) {
1153             if (poptPeekArg(optCon))
1154                 argerror(_("extra arguments given for query of all packages"));
1155
1156             ec = rpmQuery(qva, RPMQV_ALL, NULL);
1157         } else {
1158             if (!poptPeekArg(optCon))
1159                 argerror(_("no arguments given for query"));
1160             while ((pkg = poptGetArg(optCon)))
1161                 ec += rpmQuery(qva, qva->qva_source, pkg);
1162         }
1163         break;
1164
1165       case MODE_VERIFY:
1166         verifyFlags = (VERIFY_FILES|VERIFY_DEPS|VERIFY_SCRIPT|VERIFY_MD5);
1167         verifyFlags &= ~qva->qva_flags;
1168         if (noDeps)     verifyFlags &= ~VERIFY_DEPS;
1169         if (noScripts)  verifyFlags &= ~VERIFY_SCRIPT;
1170         if (noMd5)      verifyFlags &= ~VERIFY_MD5;
1171
1172         qva->qva_prefix = rootdir;
1173         qva->qva_flags = verifyFlags;
1174         if (qva->qva_source == RPMQV_ALL) {
1175             if (poptPeekArg(optCon))
1176                 argerror(_("extra arguments given for verify of all packages"));
1177             ec = rpmVerify(qva, RPMQV_ALL, NULL);
1178         } else {
1179             if (!poptPeekArg(optCon))
1180                 argerror(_("no arguments given for verify"));
1181             while ((pkg = poptGetArg(optCon)))
1182                 ec += rpmVerify(qva, qva->qva_source, pkg);
1183         }
1184         break;
1185     }
1186
1187     poptFreeContext(optCon);
1188     rpmFreeMacros(NULL);
1189     rpmFreeMacros(&rpmCLIMacroContext);
1190     rpmFreeRpmrc();
1191
1192     if (pipeChild) {
1193         fclose(stdout);
1194         (void)waitpid(pipeChild, &status, 0);
1195     }
1196
1197     /* keeps memory leak checkers quiet */
1198     freeNames();
1199     freeFilesystems();
1200     urlFreeCache();
1201     if (qva->qva_queryFormat) free((void *)qva->qva_queryFormat);
1202
1203 #if HAVE_MCHECK_H && HAVE_MTRACE
1204     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
1205 #endif
1206     return ec;
1207 }