- tsort prefers presentation order.
[platform/upstream/rpm.git] / rpmqv.c
1 #include "system.h"
2
3 #define _AUTOHELP
4
5 #if defined(IAM_RPM)
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 <rpmbuild.h>
14 #include <rpmurl.h>
15
16 #ifdef  IAM_RPMBT
17 #include "build.h"
18 #define GETOPT_REBUILD          1003
19 #define GETOPT_RECOMPILE        1004
20 #endif
21
22 #ifdef  IAM_RPMDB
23 #define GETOPT_REBUILDDB        1013
24 static int initdb = 0;
25 #endif
26
27 #ifdef  IAM_RPMEIU
28 #include "install.h"
29 #define GETOPT_INSTALL          1014
30 #define GETOPT_RELOCATE         1016
31 #define GETOPT_EXCLUDEPATH      1019
32 static int allFiles = 0;
33 static int allMatches = 0;
34 static int badReloc = 0;
35 static int excldocs = 0;
36 static int ignoreArch = 0;
37 static int ignoreOs = 0;
38 static int ignoreSize = 0;
39 static int incldocs = 0;
40 static int justdb = 0;
41 static int noOrder = 0;
42 static int oldPackage = 0;
43 static char * prefix = NULL;
44 static int replaceFiles = 0;
45 static int replacePackages = 0;
46 static int showHash = 0;
47 static int showPercents = 0;
48 static int noTriggers = 0;
49 #endif  /* IAM_RPMEIU */
50
51 #ifdef  IAM_RPMK
52 #define GETOPT_ADDSIGN          1005
53 #define GETOPT_RESIGN           1006
54 static int noGpg = 0;
55 static int noPgp = 0;
56 #endif  /* IAM_RPMK */
57
58 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
59 #include "signature.h"
60 #endif
61
62 #include "debug.h"
63
64 #define GETOPT_DBPATH           1010
65 #define GETOPT_SHOWRC           1018
66 #define GETOPT_DEFINEMACRO      1020
67 #define GETOPT_EVALMACRO        1021
68 #define GETOPT_RCFILE           1022
69
70 enum modes {
71
72     MODE_QUERY          = (1 <<  0),
73     MODE_VERIFY         = (1 <<  3),
74     MODE_QUERYTAGS      = (1 <<  9),
75 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
76
77     MODE_INSTALL        = (1 <<  1),
78     MODE_UNINSTALL      = (1 <<  2),
79 #define MODES_IE (MODE_INSTALL | MODE_UNINSTALL)
80
81     MODE_BUILD          = (1 <<  4),
82     MODE_REBUILD        = (1 <<  5),
83     MODE_RECOMPILE      = (1 <<  8),
84     MODE_TARBUILD       = (1 << 11),
85 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE)
86
87     MODE_CHECKSIG       = (1 <<  6),
88     MODE_RESIGN         = (1 <<  7),
89 #define MODES_K  (MODE_CHECKSIG | MODES_RESIGN)
90
91     MODE_INITDB         = (1 << 10),
92     MODE_REBUILDDB      = (1 << 12),
93 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB)
94
95     MODE_UNKNOWN        = 0
96 };
97
98 #define MODES_FOR_DBPATH        (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
99 #define MODES_FOR_NODEPS        (MODES_BT | MODES_IE | MODE_VERIFY)
100 #define MODES_FOR_TEST          (MODES_BT | MODES_IE)
101 #define MODES_FOR_ROOT          (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
102
103 extern int _ftp_debug;
104 extern int noLibio;
105 extern int _rpmio_debug;
106 extern int _url_debug;
107 extern int _noDirTokens;
108
109 extern const char * rpmNAME;
110 extern const char * rpmEVR;
111 extern int rpmFLAGS;
112
113 extern MacroContext rpmCLIMacroContext;
114
115 /* options for all executables */
116
117 static int help = 0;
118 static int noUsageMsg = 0;
119 static char * pipeOutput = NULL;
120 static int quiet = 0;
121 static char * rcfile = NULL;
122 static char * rootdir = "/";
123 static int showrc = 0;
124 static int showVersion = 0;
125
126 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
127 static int signIt = 0;
128 #endif  /* IAM_RPMBT || IAM_RPMK */
129
130 #if defined(IAM_RPMQV) || defined(IAM_RPMK)
131 static int noMd5 = 0;
132 #endif
133
134 #if defined(IAM_RPMEIU)
135 static int noDeps = 0;
136 #endif
137
138 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU)
139 static int noScripts = 0;
140 #endif
141
142 #if defined(IAM_RPMEIU)
143 static int force = 0;
144 static int test = 0;
145 #endif
146
147 static struct poptOption rpmAllPoptTable[] = {
148  { "version", '\0', 0, &showVersion, 0,
149         N_("print the version of rpm being used"),
150         NULL },
151  { "quiet", '\0', 0, &quiet, 0,
152         N_("provide less detailed output"), NULL},
153  { "verbose", 'v', 0, 0, 'v',
154         N_("provide more detailed output"), NULL},
155  { "define", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, GETOPT_DEFINEMACRO,
156         N_("define macro <name> with value <body>"),
157         N_("'<name> <body>'") },
158  { "eval", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, GETOPT_EVALMACRO,
159         N_("print macro expansion of <expr>+"),
160         N_("<expr>+") },
161  { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &pipeOutput, 0,
162         N_("send stdout to <cmd>"),
163         N_("<cmd>") },
164  { "root", 'r', POPT_ARG_STRING, &rootdir, 0,
165         N_("use <dir> as the top level directory"),
166         N_("<dir>") },
167  { "macros", '\0', POPT_ARG_STRING, &macrofiles, 0,
168         N_("read <file:...> instead of default macro file(s)"),
169         N_("<file:...>") },
170 #ifndef DYING
171  { "rcfile", '\0', POPT_ARG_STRING, &rcfile, 0,
172         N_("read <file:...> instead of default rpmrc file(s)"),
173         N_("<file:...>") },
174 #else
175  { "rcfile", '\0', 0, 0, GETOPT_RCFILE, 
176         N_("read <file:...> instead of default rpmrc file(s)"),
177         N_("<file:...>") },
178 #endif
179  { "showrc", '\0', 0, &showrc, GETOPT_SHOWRC,
180         N_("display final rpmrc and macro configuration"),
181         NULL },
182
183 #if HAVE_LIBIO_H && defined(_IO_BAD_SEEN)
184  { "nolibio", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noLibio, 1,
185         N_("disable use of libio(3) API"), NULL},
186 #endif
187  { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
188         N_("debug protocol data stream"), NULL},
189  { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
190         N_("debug rpmio I/O"), NULL},
191  { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
192         N_("debug URL cache handling"), NULL},
193
194    POPT_TABLEEND
195 };
196
197 #ifdef  IAM_RPMDB
198 static struct poptOption rpmDatabasePoptTable[] = {
199  { "initdb", '\0', 0, &initdb, 0,
200         N_("initialize database"), NULL},
201  { "rebuilddb", '\0', 0, 0, GETOPT_REBUILDDB,
202         N_("rebuild database inverted lists from installed package headers"),
203         NULL},
204  { "nodirtokens", '\0', POPT_ARG_VAL, &_noDirTokens, 1,
205         N_("generate headers compatible with (legacy) rpm[23] packaging"),
206         NULL},
207  { "dirtokens", '\0', POPT_ARG_VAL, &_noDirTokens, 0,
208         N_("generate headers compatible with rpm4 packaging"),
209         NULL},
210
211    POPT_TABLEEND
212 };
213 #endif  /* IAM_RPMDB */
214
215 #ifdef  IAM_RPMK
216 static struct poptOption rpmSignPoptTable[] = {
217  { "addsign", '\0', 0, 0, GETOPT_ADDSIGN,
218         N_("add a signature to a package"),
219         NULL },
220  { "resign", '\0', 0, 0, GETOPT_RESIGN,
221         N_("sign a package (discard current signature)"),
222         NULL },
223  { "sign", '\0', 0, &signIt, 0,
224         N_("generate PGP/GPG signature"),
225         NULL },
226  { "checksig", 'K', 0, 0, 'K',
227         N_("verify package signature"),
228         NULL },
229  { "nogpg", '\0', 0, &noGpg, 0,
230         N_("skip any PGP signatures"),
231         NULL },
232  { "nopgp", '\0', 0, &noPgp, 0,
233         N_("skip any GPG signatures"),
234         NULL },
235  { "nomd5", '\0', 0, &noMd5, 0,
236         N_("do not verify file md5 checksums"),
237         NULL },
238
239    POPT_TABLEEND
240 };
241 #endif  /* IAM_RPMK */
242
243 #ifdef  IAM_RPMEIU
244 static struct poptOption rpmInstallPoptTable[] = {
245  { "allfiles", '\0', 0, &allFiles, 0,
246   N_("install all files, even configurations which might otherwise be skipped"),
247         NULL},
248  { "allmatches", '\0', 0, &allMatches, 0,
249         N_("remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)"),
250         NULL},
251  { "badreloc", '\0', 0, &badReloc, 0,
252         N_("relocate files in non-relocateable package"),
253         NULL},
254  { "erase", 'e', 0, 0, 'e',
255         N_("erase (uninstall) package"),
256         N_("<package>") },
257  { "excludedocs", '\0', 0, &excldocs, 0,
258         N_("do not install documentation"),
259         NULL},
260  { "excludepath", '\0', POPT_ARG_STRING, 0, GETOPT_EXCLUDEPATH,
261         N_("skip files with leading component <path> "),
262         NULL},
263  { "force", '\0', 0, &force, 0,
264         N_("short hand for --replacepkgs --replacefiles"),
265         NULL},
266  { "freshen", 'F', 0, 0, 'F',
267         N_("upgrade package if already installed"),
268         N_("<packagefile>+") },
269  { "hash", 'h', 0, &showHash, 0,
270         N_("print hash marks as package installs (good with -v)"),
271         NULL},
272  { "ignorearch", '\0', 0, &ignoreArch, 0,
273         N_("don't verify package architecture"),
274         NULL},
275  { "ignoreos", '\0', 0, &ignoreOs, 0,
276         N_("don't verify package operating system"),
277         NULL},
278  { "ignoresize", '\0', 0, &ignoreSize, 0,
279         N_("don't check disk space before installing"),
280         NULL},
281  { "includedocs", '\0', 0, &incldocs, 0,
282         N_("install documentation"),
283         NULL},
284  { "install", '\0', 0, 0, GETOPT_INSTALL,
285         N_("install package"),
286         N_("<packagefile>+") },
287  { "justdb", '\0', 0, &justdb, 0,
288         N_("update the database, but do not modify the filesystem"),
289         NULL},
290  { "nodeps", '\0', 0, &noDeps, 0,
291         N_("do not verify package dependencies"),
292         NULL },
293  { "noorder", '\0', 0, &noOrder, 0,
294         N_("do not reorder package installation to satisfy dependencies"),
295         NULL},
296  { "noscripts", '\0', 0, &noScripts, 0,
297         N_("do not execute scripts (if any)"),
298         NULL },
299  { "notriggers", '\0', 0, &noTriggers, 0,
300         N_("don't execute any scriptlets triggered by this package"),
301         NULL},
302  { "oldpackage", '\0', 0, &oldPackage, 0,
303         N_("upgrade to an old version of the package (--force on upgrades does this automatically)"),
304         NULL},
305  { "percent", '\0', 0, &showPercents, 0,
306         N_("print percentages as package installs"),
307         NULL},
308  { "prefix", '\0', POPT_ARG_STRING, &prefix, 0,
309         N_("relocate the package to <dir>, if relocatable"),
310         N_("<dir>") },
311  { "relocate", '\0', POPT_ARG_STRING, 0, GETOPT_RELOCATE,
312         N_("relocate files from <oldpath> to <newpath>"),
313         N_("<oldpath>=<newpath>") },
314  { "replacefiles", '\0', 0, &replaceFiles, 0,
315         N_("install even if the package replaces installed files"),
316         NULL},
317  { "replacepkgs", '\0', 0, &replacePackages, 0,
318         N_("reinstall if the package is already present"),
319         NULL},
320  { "test", '\0', 0, &test, 0,
321         N_("don't install, but tell if it would work or not"),
322         NULL},
323  { "upgrade", 'U', 0, 0, 'U',
324         N_("upgrade package"),
325         N_("<packagefile>+") },
326  { "uninstall", 'u', POPT_ARGFLAG_DOC_HIDDEN, 0, 'u',
327         NULL,
328         NULL},
329
330    POPT_TABLEEND
331 };
332 #endif  /* IAM_RPMEIU */
333
334 /* the structure describing the options we take and the defaults */
335 static struct poptOption optionsTable[] = {
336 #if !defined(_AUTOHELP)
337  { "help", '\0', 0, &help, 0,                   NULL, NULL},
338 #endif
339
340  /* XXX colliding options */
341 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU) || defined(IAM_RPMBT)
342  {  NULL, 'i', POPT_ARGFLAG_DOC_HIDDEN, 0, 'i',                 NULL, NULL},
343 #endif
344
345 #ifdef  IAM_RPMQV
346  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
347         N_("Query options (with -q or --query):"),
348         NULL },
349  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
350         N_("Verify options (with -V or --verify):"),
351         NULL },
352 #endif  /* IAM_RPMQV */
353
354 #ifdef  IAM_RPMK
355  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0,
356         N_("Signature options:"),
357         NULL },
358 #endif  /* IAM_RPMK */
359
360 #ifdef  IAM_RPMDB
361  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0,
362         N_("Database options:"),
363         NULL },
364 #endif  /* IAM_RPMDB */
365
366 #ifdef  IAM_RPMBT
367  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
368         N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
369         NULL },
370 #endif  /* IAM_RPMBT */
371
372  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmAllPoptTable, 0,
373         N_("Common options for all rpm modes:"),
374         NULL },
375
376    POPT_AUTOHELP
377    POPT_TABLEEND
378 };
379
380 #ifdef __MINT__
381 /* MiNT cannot dynamically increase the stack.  */
382 long _stksize = 64 * 1024L;
383 #endif
384
385 static void argerror(const char * desc) {
386     fprintf(stderr, _("rpm: %s\n"), desc);
387     exit(EXIT_FAILURE);
388 }
389
390 static void printHelp(void);
391 static void printVersion(void);
392 static void printBanner(void);
393 static void printUsage(void);
394 static void printHelpLine(char * prefix, char * help);
395
396 static void printVersion(void) {
397     fprintf(stdout, _("RPM version %s\n"), rpmEVR);
398 }
399
400 static void printBanner(void) {
401     puts(_("Copyright (C) 1998-2000 - Red Hat, Inc."));
402     puts(_("This program may be freely redistributed under the terms of the GNU GPL"));
403 }
404
405 static void printUsage(void) {
406     FILE * fp;
407     printVersion();
408     printBanner();
409     puts("");
410
411     fp = stdout;
412
413     fprintf(fp, _("Usage: %s {--help}\n"), __progname);
414     fprintf(fp,  ("       %s {--version}\n"), __progname);
415
416 #ifdef  IAM_RPMDB
417     fprintf(fp, _("       %s {--initdb}   [--dbpath <dir>]\n"), __progname);
418     fprintf(fp, _("       %s {--rebuilddb} [--macros <file:...>] [--dbpath <dir>]\n"), __progname);
419 #endif
420
421 #ifdef  IAM_RPMEIU
422     fprintf(fp, _("       %s {--install -i} [-v] [--hash -h] [--percent] [--force] [--test]\n"), __progname);
423     puts(_("                        [--replacepkgs] [--replacefiles] [--root <dir>]"));
424     puts(_("                        [--excludedocs] [--includedocs] [--noscripts]"));
425     puts(_("                        [--macros <file:...>] [--ignorearch] [--dbpath <dir>]"));
426     puts(_("                        [--prefix <dir>] [--ignoreos] [--nodeps] [--allfiles]"));
427     puts(_("                        [--ftpproxy <host>] [--ftpport <port>]"));
428     puts(_("                        [--httpproxy <host>] [--httpport <port>]"));
429     puts(_("                        [--justdb] [--noorder] [--relocate oldpath=newpath]"));
430     puts(_("                        [--badreloc] [--notriggers] [--excludepath <path>]"));
431     puts(_("                        [--ignoresize] file1.rpm ... fileN.rpm"));
432     fprintf(fp,  ("       %s {--upgrade -U} [-v] [--hash -h] [--percent] [--force] [--test]\n"), __progname);
433     puts(_("                        [--oldpackage] [--root <dir>] [--noscripts]"));
434     puts(_("                        [--excludedocs] [--includedocs] [--macros <file:...>]"));
435     puts(_("                        [--ignorearch]  [--dbpath <dir>] [--prefix <dir>] "));
436     puts(_("                        [--ftpproxy <host>] [--ftpport <port>]"));
437     puts(_("                        [--httpproxy <host>] [--httpport <port>]"));
438     puts(_("                        [--ignoreos] [--nodeps] [--allfiles] [--justdb]"));
439     puts(_("                        [--noorder] [--relocate oldpath=newpath]"));
440     puts(_("                        [--badreloc] [--excludepath <path>] [--ignoresize]"));
441     puts(_("                        file1.rpm ... fileN.rpm"));
442     fprintf(fp, _("       %s {--erase -e} [--root <dir>] [--noscripts] [--macros <file:...>]\n"), __progname);
443     puts(_("                        [--dbpath <dir>] [--nodeps] [--allmatches]"));
444     puts(_("                        [--justdb] [--notriggers] package1 ... packageN"));
445 #endif  /* IAM_RPMEIU */
446
447 #ifdef  IAM_RPMQV
448     fprintf(fp,  ("       %s {--query -q} [-afpg] [-i] [-l] [-s] [-d] [-c] [-v] [-R]\n"), __progname);
449     puts(_("                        [--scripts] [--root <dir>] [--macros <file:...>]"));
450     puts(_("                        [--whatprovides] [--whatrequires] [--requires]"));
451     puts(_("                        [--triggeredby]"));
452     puts(_("                        [--ftpproxy <host>] [--ftpport <port>]"));
453     puts(_("                        [--httpproxy <host>] [--httpport <port>]"));
454     puts(_("                        [--provides] [--triggers] [--dump]"));
455     puts(_("                        [--changelog] [--dbpath <dir>] [targets]"));
456     fprintf(fp, _("       %s {--verify -V -y} [-afpg] [--root <dir>] [--macros <file:...>]\n"), __progname);
457     puts(_("                        [--dbpath <dir>] [--nodeps] [--nofiles] [--noscripts]"));
458     puts(_("                        [--nomd5] [targets]"));
459     fprintf(fp,  ("       %s {--querytags}\n"), __progname);
460     fprintf(fp, _("       %s {--setperms} [-afpg] [target]\n"), __progname);
461     fprintf(fp, _("       %s {--setugids} [-afpg] [target]\n"), __progname);
462 #endif  /* IAM_RPMQV */
463
464 #ifdef  IAM_RPMK
465     fprintf(fp, _("       %s {--resign} [--macros <file:...>] package1 package2 ... packageN\n"), __progname);
466     fprintf(fp, _("       %s {--addsign} [--macros <file:...>] package1 package2 ... packageN"), __progname);
467     fprintf(fp, _("       %s {--checksig -K} [--nopgp] [--nogpg] [--nomd5] [--macros <file:...>]\n"), __progname);
468     puts(_("                           package1 ... packageN"));
469 #endif  /* IAM_RPMK */
470
471 }
472
473 static void printHelpLine(char * prefix, char * help) {
474     int indentLength = strlen(prefix) + 3;
475     int lineLength = 79 - indentLength;
476     int helpLength = strlen(help);
477     char * ch;
478     char format[10];
479
480     fprintf(stdout, "%s - ", prefix);
481
482     while (helpLength > lineLength) {
483         ch = help + lineLength - 1;
484         while (ch > help && !isspace(*ch)) ch--;
485         if (ch == help) break;          /* give up */
486         while (ch > (help + 1) && isspace(*ch)) ch--;
487         ch++;
488
489         sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
490         fprintf(stdout, format, help, " ");
491         help = ch;
492         while (isspace(*help) && *help) help++;
493         helpLength = strlen(help);
494     }
495
496     if (helpLength) puts(help);
497 }
498
499 static void printHelp(void) {
500     printVersion();
501     printBanner();
502     puts("");
503
504     puts(         _("Usage:"));
505     printHelpLine(  "   --help                 ", 
506                   _("print this message"));
507     printHelpLine(  "   --version              ",
508                   _("print the version of rpm being used"));
509
510     puts("");
511     puts(         _("  All modes support the following options:"));
512     printHelpLine(_("   --define '<name> <body>'"),
513                   _("define macro <name> with value <body>"));
514     printHelpLine(_("   --eval '<expr>+'       "),
515                   _("print the expansion of macro <expr> to stdout"));
516     printHelpLine(_("   --pipe <cmd>           "),
517                   _("send stdout to <cmd>"));
518     printHelpLine(_("   --macros <file:...>    "),
519                   _("use <file:...> instead of default list of macro files"));
520     printHelpLine(  "   --showrc               ",
521                   _("display final rpmrc and macro configuration"));
522 #if defined(IAM_RPMBT) || defined(IAM_RPMDB) || defined(IAM_RPMEIU) || defined(IAM_RPMQV)
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 #endif  /* IAM_RPMBT || IAM_RPMDB || IAM_RPMEIU || IAM_RPMQV */
528     printHelpLine(  "   -v                     ",
529                   _("be a little more verbose"));
530     printHelpLine(  "   -vv                    ",
531                   _("be incredibly verbose (for debugging)"));
532
533 #if defined(IAM_RPMEIU) || defined(IAM_RPMQV)
534     puts("");
535     puts(         _("  Install, upgrade and query (with -p) modes allow URL's to be used in place"));
536     puts(         _("  of file names as well as the following options:"));
537     printHelpLine(_("     --ftpproxy <host>    "),
538                   _("hostname or IP of ftp proxy"));
539     printHelpLine(_("     --ftpport <port>     "),
540                   _("port number of ftp server (or proxy)"));
541     printHelpLine(_("     --httpproxy <host>   "),
542                   _("hostname or IP of http proxy"));
543     printHelpLine(_("     --httpport <port>    "),
544                   _("port number of http server (or proxy)"));
545 #endif  /* IAM_RPMEIU || IAM_RPMQV */
546
547 #ifdef IAM_RPMQV
548     puts("");
549     puts(         _("  Package specification options:"));
550     printHelpLine(  "     -a, --all            ",
551                   _("query/verify all packages"));
552     printHelpLine(_("     -f <file>+           "),
553                   _("query/verify package owning <file>"));
554     printHelpLine(_("     -p <packagefile>+    "),
555                   _("query/verify (uninstalled) package <packagefile>"));
556     printHelpLine(_("     --triggeredby <pkg>  "),
557                   _("query/verify packages triggered by <pkg>"));
558     printHelpLine(_("     --whatprovides <cap> "),
559                   _("query/verify packages which provide <cap> capability"));
560     printHelpLine(_("     --whatrequires <cap> "),
561                   _("query/verify packages which require <cap> capability"));
562     puts("");
563     printHelpLine(  "  -q, --query             ",
564                   _("query mode"));
565     printHelpLine(_("     --queryformat <qfmt> "),
566                   _("use <qfmt> as the header format (implies --info)"));
567     puts("");
568     puts(         _("    Information selection options:"));
569     printHelpLine(  "       -i, --info         ",
570                   _("display package information"));
571     printHelpLine(  "       --changelog        ",
572                   _("display the package's change log"));
573     printHelpLine(  "       -l                 ",
574                   _("display package file list"));
575     printHelpLine(  "       -s                 ",
576                   _("show file states (implies -l)"));
577     printHelpLine(  "       -d                 ",
578                   _("list only documentation files (implies -l)"));
579     printHelpLine(  "       -c                 ",
580                   _("list only configuration files (implies -l)"));
581     printHelpLine(  "       --dump             ",
582                   _("show all verifiable information for each file (must be used with -l, -c, or -d)"));
583     printHelpLine(  "       --provides         ",
584                   _("list capabilities provided by package"));
585     printHelpLine(  "       -R, --requires     ",
586                   _("list capabilities required by package"));
587     printHelpLine(  "       --scripts          ",
588                   _("print the various [un]install scriptlets"));
589     printHelpLine(  "       --triggers         ",
590                   _("show the trigger scriptlets contained in the package"));
591     puts("");
592     printHelpLine(  "   -V, -y, --verify       ",
593                   _("verify a package installation using the same same package specification options as -q"));
594     printHelpLine(  "     --nodeps             ",
595                   _("do not verify package dependencies"));
596     printHelpLine(  "     --nofiles            ",
597                   _("do not verify file attributes"));
598     printHelpLine(  "     --nomd5              ",
599                   _("do not verify file md5 checksums"));
600     printHelpLine(  "     --noscripts          ",
601                   _("do not execute scripts (if any)"));
602     puts("");
603     printHelpLine(  "   --querytags            ",
604                   _("list the tags that can be used in a query format"));
605     printHelpLine(  "   --setperms             ",
606                   _("set the file permissions to those in the package database"
607                     " using the same package specification options as -q"));
608     printHelpLine(  "   --setugids             ",
609                   _("set the file owner and group to those in the package "
610                     "database using the same package specification options as "
611                     "-q"));
612 #endif  /* IAM_RPMQV */
613
614 #ifdef  IAM_RPMEIU
615     puts("");
616     puts(         _("   --install <packagefile>"));
617     printHelpLine(_("   -i <packagefile>       "),
618                   _("install package"));
619     printHelpLine(  "     --allfiles           ",
620                   _("install all files, even configurations which might "
621                     "otherwise be skipped"));
622     printHelpLine(  "     --badreloc           ",
623                   _("relocate files in non-relocateable package"));
624     printHelpLine(  "     --excludedocs        ",
625                   _("do not install documentation"));
626     printHelpLine(_("     --excludepath <path> "),
627                   _("skip files with leading component <path> "));
628     printHelpLine(  "     --force              ",
629                   _("short hand for --replacepkgs --replacefiles"));
630     printHelpLine(  "     -h, --hash           ",
631                   _("print hash marks as package installs (good with -v)"));
632     printHelpLine(  "     --ignorearch         ",
633                   _("don't verify package architecture"));
634     printHelpLine(  "     --ignoresize         ",
635                   _("don't check disk space before installing"));
636     printHelpLine(  "     --ignoreos           ",
637                   _("don't verify package operating system"));
638     printHelpLine(  "     --includedocs        ",
639                   _("install documentation"));
640     printHelpLine(  "     --justdb             ",
641                   _("update the database, but do not modify the filesystem"));
642     printHelpLine(  "     --nodeps             ",
643                   _("do not verify package dependencies"));
644     printHelpLine(  "     --noorder            ",
645                   _("do not reorder package installation to satisfy dependencies"));
646     printHelpLine(  "     --noscripts          ",
647                   _("don't execute any installation scriptlets"));
648     printHelpLine(  "     --notriggers         ",
649                   _("don't execute any scriptlets triggered by this package"));
650     printHelpLine(  "     --percent            ",
651                   _("print percentages as package installs"));
652     printHelpLine(_("     --prefix <dir>       "),
653                   _("relocate the package to <dir>, if relocatable"));
654     printHelpLine(_("     --relocate <oldpath>=<newpath>"),
655                   _("relocate files from <oldpath> to <newpath>"));
656     printHelpLine(  "     --replacefiles       ",
657                   _("install even if the package replaces installed files"));
658     printHelpLine(  "     --replacepkgs        ",
659                   _("reinstall if the package is already present"));
660     printHelpLine(  "     --test               ",
661                   _("don't install, but tell if it would work or not"));
662     puts("");
663     puts(         _("   --upgrade <packagefile>"));
664     printHelpLine(_("   -U <packagefile>       "),
665                   _("upgrade package (same options as --install, plus)"));
666     printHelpLine(  "     --oldpackage         ",
667                   _("upgrade to an old version of the package (--force on upgrades does this automatically)"));
668     puts("");
669     puts(         _("   --erase <package>"));
670     printHelpLine(  "   -e <package>           ",
671                   _("erase (uninstall) package"));
672     printHelpLine(  "     --allmatches         ",
673                   _("remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)"));
674     printHelpLine(  "     --justdb             ",
675                   _("update the database, but do not modify the filesystem"));
676     printHelpLine(  "     --nodeps             ",
677                   _("do not verify package dependencies"));
678     printHelpLine(  "     --noorder            ",
679                   _("do not reorder package installation to satisfy dependencies"));
680     printHelpLine(  "     --noscripts          ",
681                   _("do not execute any package specific scripts"));
682     printHelpLine(  "     --notriggers         ",
683                   _("don't execute any scripts triggered by this package"));
684 #endif  /* IAM_RPMEIU */
685
686 #ifdef IAM_RPMK
687     puts("");
688     printHelpLine(_("   --resign <pkg>+        "),
689                   _("sign a package (discard current signature)"));
690     printHelpLine(_("   --addsign <pkg>+       "),
691                   _("add a signature to a package"));
692
693     puts(         _("   --checksig <pkg>+"));
694     printHelpLine(_("   -K <pkg>+             "),
695                   _("verify package signature"));
696     printHelpLine(  "     --nopgp              ",
697                   _("skip any PGP signatures"));
698     printHelpLine(  "     --nogpg              ",
699                   _("skip any GPG signatures"));
700     printHelpLine(  "     --nomd5              ",
701                   _("skip any MD5 signatures"));
702 #endif  /* IAM_RPMK */
703
704 #ifdef  IAM_RPMDB
705     puts("");
706     printHelpLine(  "   --initdb               ",
707                   _("initalize database (unnecessary, legacy use)"));
708     printHelpLine(  "   --rebuilddb            ",
709                   _("rebuild database indices from existing database headers"));
710 #endif
711
712 }
713
714 int main(int argc, const char ** argv)
715 {
716     enum modes bigMode = MODE_UNKNOWN;
717
718 #ifdef  IAM_RPMQV
719     QVA_t *qva = &rpmQVArgs;
720 #endif
721
722 #ifdef  IAM_RPMBT
723     struct rpmBuildArguments *ba = &rpmBTArgs;
724 #endif
725
726 #ifdef  IAM_RPMEIU
727     rpmRelocation * relocations = NULL;
728     int numRelocations = 0;
729     int installFlags = 0, uninstallFlags = 0, interfaceFlags = 0;
730     int probFilter = 0;
731     int upgrade = 0;
732     int freshen = 0;
733 #endif
734
735 #if defined(IAM_RPMK)
736     rpmResignFlags addSign = RESIGN_NEW_SIGNATURE;
737     rpmCheckSigFlags checksigFlags = CHECKSIG_NONE;
738 #endif
739
740 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
741     char * passPhrase = "";
742 #endif
743
744     int arg;
745     int gotDbpath = 0;
746
747     const char * optArg;
748     pid_t pipeChild = 0;
749     poptContext optCon;
750     int ec = 0;
751     int status;
752     int p[2];
753         
754 #if HAVE_MCHECK_H && HAVE_MTRACE
755     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
756 #endif
757     setprogname(argv[0]);       /* Retrofit glibc __progname */
758
759     /* XXX glibc churn sanity */
760     if (__progname == NULL) {
761         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
762         else __progname = argv[0];
763     }
764
765     /* Set the major mode based on argv[0] */
766 #ifdef  IAM_RPMBT
767     if (!strcmp(__progname, "rpmb"))    bigMode = MODE_BUILD;
768     if (!strcmp(__progname, "rpmt"))    bigMode = MODE_TARBUILD;
769     if (!strcmp(__progname, "rpmbuild"))        bigMode = MODE_BUILD;
770 #endif
771 #ifdef  IAM_RPMQV
772     if (!strcmp(__progname, "rpmq"))    bigMode = MODE_QUERY;
773     if (!strcmp(__progname, "rpmv"))    bigMode = MODE_VERIFY;
774     if (!strcmp(__progname, "rpmquery"))        bigMode = MODE_QUERY;
775     if (!strcmp(__progname, "rpmverify"))       bigMode = MODE_VERIFY;
776 #endif
777 #ifdef  RPMEIU
778     if (!strcmp(__progname, "rpme"))    bigMode = MODE_UNINSTALL;
779     if (!strcmp(__progname, "rpmi"))    bigMode = MODE_INSTALL;
780     if (!strcmp(__progname, "rpmu"))    bigMode = MODE_INSTALL;
781 #endif
782
783     /* set the defaults for the various command line options */
784     _ftp_debug = 0;
785
786 #if HAVE_LIBIO_H && defined(_IO_BAD_SEEN)
787     noLibio = 0;
788 #else
789     noLibio = 1;
790 #endif
791     _rpmio_debug = 0;
792     _url_debug = 0;
793
794     /* XXX Eliminate query linkage loop */
795     specedit = 0;
796     parseSpecVec = parseSpec;
797     freeSpecVec = freeSpec;
798
799     /* set up the correct locale */
800     setlocale(LC_ALL, "" );
801
802 #ifdef  __LCLINT__
803 #define LOCALEDIR       "/usr/share/locale"
804 #endif
805     bindtextdomain(PACKAGE, LOCALEDIR);
806     textdomain(PACKAGE);
807
808     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
809
810     /* Make a first pass through the arguments, looking for --rcfile */
811     /* We need to handle that before dealing with the rest of the arguments. */
812     optCon = poptGetContext(__progname, argc, argv, optionsTable, 0);
813     poptReadConfigFile(optCon, LIBRPMALIAS_FILENAME);
814     poptReadDefaultConfig(optCon, 1);
815     poptSetExecPath(optCon, RPMCONFIGDIR, 1);
816
817     /* reading rcfile early makes it easy to override */
818     /* XXX only --rcfile (and --showrc) need this pre-parse */
819
820     while ((arg = poptGetNextOpt(optCon)) > 0) {
821         switch(arg) {
822         case 'v':
823             rpmIncreaseVerbosity();     /* XXX silly use by showrc */
824             break;
825         default:
826             break;
827       }
828     }
829
830     if (rpmReadConfigFiles(rcfile, NULL))  
831         exit(EXIT_FAILURE);
832
833     if (showrc) {
834         rpmShowRC(stdout);
835         exit(EXIT_SUCCESS);
836     }
837
838     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
839
840     poptResetContext(optCon);
841
842 #ifdef  IAM_RPMQV
843     if (qva->qva_queryFormat) free((void *)qva->qva_queryFormat);
844     memset(qva, 0, sizeof(*qva));
845     qva->qva_source = RPMQV_PACKAGE;
846     qva->qva_mode = ' ';
847     qva->qva_char = ' ';
848 #endif
849
850 #ifdef  IAM_RPMBT
851     if (ba->buildRootOverride) free((void *)ba->buildRootOverride);
852     if (ba->targets) free(ba->targets);
853     memset(ba, 0, sizeof(*ba));
854     ba->buildMode = ' ';
855     ba->buildChar = ' ';
856 #endif
857
858     while ((arg = poptGetNextOpt(optCon)) > 0) {
859         optArg = poptGetOptArg(optCon);
860
861         switch (arg) {
862             
863           case 'v':
864             rpmIncreaseVerbosity();
865             break;
866
867 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU) || defined(IAM_RPMBT)
868           case 'i':
869 #ifdef  IAM_RPMQV
870             if (bigMode == MODE_QUERY) {
871                 const char * infoCommand[] = { "--info", NULL };
872                 poptStuffArgs(optCon, infoCommand);
873             }
874 #endif
875 #ifdef  IAM_RPMEIU
876             if (bigMode == MODE_INSTALL)
877                 /*@-ifempty@*/ ;
878             if (bigMode == MODE_UNKNOWN) {
879                 const char * installCommand[] = { "--install", NULL };
880                 poptStuffArgs(optCon, installCommand);
881             }
882 #endif
883             break;
884 #endif  /* IAM_RPMQV || IAM_RPMEIU || IAM_RPMBT */
885
886 #ifdef  IAM_RPMEIU
887           case 'u':
888             if (bigMode != MODE_UNKNOWN && bigMode != MODE_UNINSTALL)
889                 argerror(_("only one major mode may be specified"));
890             bigMode = MODE_UNINSTALL;
891             rpmMessage(RPMMESS_ERROR, _("-u and --uninstall are deprecated and no"
892                     " longer work.\n"));
893             rpmMessage(RPMMESS_ERROR, _("Use -e or --erase instead.\n"));
894             exit(EXIT_FAILURE);
895         
896           case 'e':
897             if (bigMode != MODE_UNKNOWN && bigMode != MODE_UNINSTALL)
898                 argerror(_("only one major mode may be specified"));
899             bigMode = MODE_UNINSTALL;
900             break;
901         
902           case GETOPT_INSTALL:
903             if (bigMode != MODE_UNKNOWN && bigMode != MODE_INSTALL)
904                 argerror(_("only one major mode may be specified"));
905             bigMode = MODE_INSTALL;
906             break;
907
908           case 'U':
909             if (bigMode != MODE_UNKNOWN && bigMode != MODE_INSTALL)
910                 argerror(_("only one major mode may be specified"));
911             bigMode = MODE_INSTALL;
912             upgrade = 1;
913             break;
914
915           case 'F':
916             if (bigMode != MODE_UNKNOWN && bigMode != MODE_INSTALL)
917                 argerror(_("only one major mode may be specified"));
918             bigMode = MODE_INSTALL;
919             upgrade = 1;  /* Freshen implies upgrade */
920             freshen = 1;
921             break;
922
923           case GETOPT_EXCLUDEPATH:
924             if (*optArg != '/') 
925                 argerror(_("exclude paths must begin with a /"));
926
927             relocations = xrealloc(relocations, 
928                                   sizeof(*relocations) * (numRelocations + 1));
929             relocations[numRelocations].oldPath = optArg;
930             relocations[numRelocations++].newPath = NULL;
931             break;
932
933           case GETOPT_RELOCATE:
934           { char * errString = NULL;
935             if (*optArg != '/') 
936                 argerror(_("relocations must begin with a /"));
937             if (!(errString = strchr(optArg, '=')))
938                 argerror(_("relocations must contain a ="));
939             *errString++ = '\0';
940             if (*errString != '/') 
941                 argerror(_("relocations must have a / following the ="));
942             relocations = xrealloc(relocations, 
943                                   sizeof(*relocations) * (numRelocations + 1));
944             relocations[numRelocations].oldPath = optArg;
945             relocations[numRelocations++].newPath = errString;
946           } break;
947 #endif  /* IAM_RPMEIU */
948
949 #ifdef  IAM_RPMDB
950           case GETOPT_REBUILDDB:
951             if (bigMode != MODE_UNKNOWN && bigMode != MODE_REBUILDDB)
952                 argerror(_("only one major mode may be specified"));
953             bigMode = MODE_REBUILDDB;
954             break;
955 #endif
956
957 #ifdef  IAM_RPMK
958           case 'K':
959             if (bigMode != MODE_UNKNOWN && bigMode != MODE_CHECKSIG)
960                 argerror(_("only one major mode may be specified"));
961             bigMode = MODE_CHECKSIG;
962             break;
963
964           case GETOPT_RESIGN:
965             if (bigMode != MODE_UNKNOWN && bigMode != MODE_RESIGN)
966                 argerror(_("only one major mode may be specified"));
967             bigMode = MODE_RESIGN;
968             addSign = RESIGN_NEW_SIGNATURE;
969             signIt = 1;
970             break;
971
972           case GETOPT_ADDSIGN:
973             if (bigMode != MODE_UNKNOWN && bigMode != MODE_RESIGN)
974                 argerror(_("only one major mode may be specified"));
975             bigMode = MODE_RESIGN;
976             addSign = RESIGN_ADD_SIGNATURE;
977             signIt = 1;
978             break;
979 #endif  /* IAM_RPMK */
980
981           case GETOPT_DEFINEMACRO:
982             rpmDefineMacro(NULL, optArg, RMIL_CMDLINE);
983             rpmDefineMacro(&rpmCLIMacroContext, optArg, RMIL_CMDLINE);
984             noUsageMsg = 1;
985             break;
986
987           case GETOPT_EVALMACRO:
988           { const char *val = rpmExpand(optArg, NULL);
989             fprintf(stdout, "%s\n", val);
990             free((void *)val);
991             noUsageMsg = 1;
992           } break;
993
994           case GETOPT_RCFILE:
995             fprintf(stderr, _("The --rcfile option has been eliminated.\n"));
996             fprintf(stderr, _("Use \"--macros <file:...>\" instead.\n"));
997             exit(EXIT_FAILURE);
998             /*@notreached@*/ break;
999
1000           default:
1001             fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
1002             exit(EXIT_FAILURE);
1003         }
1004     }
1005
1006     if (quiet)
1007         rpmSetVerbosity(RPMMESS_QUIET);
1008
1009     if (showVersion) printVersion();
1010     if (help) printHelp();
1011
1012     if (arg < -1) {
1013         fprintf(stderr, "%s: %s\n", 
1014                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
1015                 poptStrerror(arg));
1016         exit(EXIT_FAILURE);
1017     }
1018
1019 #ifdef  IAM_RPMBT
1020     switch (ba->buildMode) {
1021     case 'b':   bigMode = MODE_BUILD;           break;
1022     case 't':   bigMode = MODE_TARBUILD;        break;
1023     case 'B':   bigMode = MODE_REBUILD;         break;
1024     case 'C':   bigMode = MODE_RECOMPILE;       break;
1025     }
1026
1027     if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
1028         bigMode = MODE_BUILD;
1029
1030     if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
1031         bigMode = MODE_BUILD;
1032
1033     if (ba->buildRootOverride && bigMode != MODE_BUILD &&
1034         bigMode != MODE_REBUILD && bigMode != MODE_TARBUILD) {
1035         argerror("--buildroot may only be used during package builds");
1036     }
1037 #endif  /* IAM_RPMBT */
1038     
1039 #ifdef  IAM_RPMDB
1040     if (initdb) {
1041         if (bigMode != MODE_UNKNOWN) 
1042             argerror(_("only one major mode may be specified"));
1043         else
1044             bigMode = MODE_INITDB;
1045     }
1046 #endif  /* IAM_RPMDB */
1047
1048 #ifdef  IAM_RPMQV
1049     switch (qva->qva_mode) {
1050     case 'q':   bigMode = MODE_QUERY;           break;
1051     case 'V':   bigMode = MODE_VERIFY;          break;
1052     case 'Q':   bigMode = MODE_QUERYTAGS;       break;
1053     }
1054
1055     if (qva->qva_sourceCount) {
1056         if (qva->qva_sourceCount > 2)
1057             argerror(_("one type of query/verify may be performed at a "
1058                         "time"));
1059     }
1060     if (qva->qva_flags && (bigMode & ~MODES_QV)) 
1061         argerror(_("unexpected query flags"));
1062
1063     if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
1064         argerror(_("unexpected query format"));
1065
1066     if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
1067         argerror(_("unexpected query source"));
1068 #endif
1069
1070     if (gotDbpath && (bigMode & ~MODES_FOR_DBPATH))
1071         argerror(_("--dbpath given for operation that does not use a "
1072                         "database"));
1073
1074 #if defined(IAM_RPMEIU)
1075
1076     if (!( bigMode == MODE_INSTALL ) && force)
1077         argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
1078 #endif  /* IAM_RPMEIU */
1079
1080 #ifdef  IAM_RPMEIU
1081     if (bigMode != MODE_INSTALL && badReloc)
1082         argerror(_("files may only be relocated during package installation"));
1083
1084     if (relocations && prefix)
1085         argerror(_("only one of --prefix or --relocate may be used"));
1086
1087     if (bigMode != MODE_INSTALL && relocations)
1088         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
1089
1090     if (bigMode != MODE_INSTALL && prefix)
1091         argerror(_("--prefix may only be used when installing new packages"));
1092
1093     if (prefix && prefix[0] != '/') 
1094         argerror(_("arguments to --prefix must begin with a /"));
1095
1096     if (bigMode != MODE_INSTALL && showHash)
1097         argerror(_("--hash (-h) may only be specified during package "
1098                         "installation"));
1099
1100     if (bigMode != MODE_INSTALL && showPercents)
1101         argerror(_("--percent may only be specified during package "
1102                         "installation"));
1103
1104     if (bigMode != MODE_INSTALL && replaceFiles)
1105         argerror(_("--replacefiles may only be specified during package "
1106                         "installation"));
1107
1108     if (bigMode != MODE_INSTALL && replacePackages)
1109         argerror(_("--replacepkgs may only be specified during package "
1110                         "installation"));
1111
1112     if (bigMode != MODE_INSTALL && excldocs)
1113         argerror(_("--excludedocs may only be specified during package "
1114                    "installation"));
1115
1116     if (bigMode != MODE_INSTALL && incldocs)
1117         argerror(_("--includedocs may only be specified during package "
1118                    "installation"));
1119
1120     if (excldocs && incldocs)
1121         argerror(_("only one of --excludedocs and --includedocs may be "
1122                  "specified"));
1123   
1124     if (bigMode != MODE_INSTALL && ignoreArch)
1125         argerror(_("--ignorearch may only be specified during package "
1126                    "installation"));
1127
1128     if (bigMode != MODE_INSTALL && ignoreOs)
1129         argerror(_("--ignoreos may only be specified during package "
1130                    "installation"));
1131
1132     if (bigMode != MODE_INSTALL && ignoreSize)
1133         argerror(_("--ignoresize may only be specified during package "
1134                    "installation"));
1135
1136     if (allMatches && bigMode != MODE_UNINSTALL)
1137         argerror(_("--allmatches may only be specified during package "
1138                    "erasure"));
1139
1140     if (allFiles && bigMode != MODE_INSTALL)
1141         argerror(_("--allfiles may only be specified during package "
1142                    "installation"));
1143
1144     if (justdb && bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL)
1145         argerror(_("--justdb may only be specified during package "
1146                    "installation and erasure"));
1147 #endif  /* IAM_RPMEIU */
1148
1149 #if defined(IAM_RPMQV) || defined(IAM_RPMEIU)
1150     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && 
1151         bigMode != MODE_VERIFY && noScripts)
1152         argerror(_("--noscripts may only be specified during package "
1153                    "installation, erasure, and verification"));
1154 #endif  /* IAM_RPMQV || IAM_RPMEIU */
1155
1156 #if defined(IAM_RPMEIU)
1157     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && noTriggers)
1158         argerror(_("--notriggers may only be specified during package "
1159                    "installation and erasure"));
1160
1161     if (noDeps & (bigMode & ~MODES_FOR_NODEPS))
1162         argerror(_("--nodeps may only be specified during package "
1163                    "building, rebuilding, recompilation, installation,"
1164                    "erasure, and verification"));
1165
1166     if (test && (bigMode & ~MODES_FOR_TEST))
1167         argerror(_("--test may only be specified during package installation, "
1168                  "erasure, and building"));
1169 #endif  /* IAM_RPMEIU */
1170
1171     if (rootdir[1] && (bigMode & ~MODES_FOR_ROOT))
1172         argerror(_("--root (-r) may only be specified during "
1173                  "installation, erasure, querying, and "
1174                  "database rebuilds"));
1175
1176     if (rootdir) {
1177         switch (urlIsURL(rootdir)) {
1178         default:
1179             if (bigMode & MODES_FOR_ROOT)
1180                 break;
1181             /*@fallthrough@*/
1182         case URL_IS_UNKNOWN:
1183             if (rootdir[0] != '/')
1184                 argerror(_("arguments to --root (-r) must begin with a /"));
1185             break;
1186         }
1187     }
1188
1189 #ifdef  IAM_RPMEIU
1190     if (oldPackage && !upgrade)
1191         argerror(_("--oldpackage may only be used during upgrades"));
1192 #endif
1193
1194 #ifdef  IAM_RPMK
1195     if (noPgp && bigMode != MODE_CHECKSIG)
1196         argerror(_("--nopgp may only be used during signature checking"));
1197
1198     if (noGpg && bigMode != MODE_CHECKSIG)
1199         argerror(_("--nogpg may only be used during signature checking"));
1200 #endif
1201
1202 #if defined(IAM_RPMK) || defined(IAM_RPMQV)
1203     if (noMd5 && bigMode != MODE_CHECKSIG && bigMode != MODE_VERIFY)
1204         argerror(_("--nomd5 may only be used during signature checking and "
1205                    "package verification"));
1206 #endif
1207
1208 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
1209 #if defined(IAM_RPMBT)
1210     signIt = ba->sign;
1211 #endif
1212     if (signIt) {
1213         if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
1214             bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD) {
1215             const char ** argv;
1216             struct stat sb;
1217             int errors = 0;
1218
1219             if ((argv = poptGetArgs(optCon)) == NULL) {
1220                 fprintf(stderr, _("no files to sign\n"));
1221                 errors++;
1222             } else
1223             while (*argv) {
1224                 if (stat(*argv, &sb)) {
1225                     fprintf(stderr, _("cannot access file %s\n"), *argv);
1226                     errors++;
1227                 }
1228                 argv++;
1229             }
1230
1231             if (errors) return errors;
1232
1233             if (poptPeekArg(optCon)) {
1234                 int sigTag;
1235                 switch (sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) {
1236                   case 0:
1237                     break;
1238                   case RPMSIGTAG_PGP:
1239                     if ((sigTag == RPMSIGTAG_PGP || sigTag == RPMSIGTAG_PGP5) &&
1240                         !rpmDetectPGPVersion(NULL)) {
1241                         fprintf(stderr, _("pgp not found: "));
1242                         exit(EXIT_FAILURE);
1243                     }   /*@fallthrough@*/
1244                   case RPMSIGTAG_GPG:
1245                     passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
1246                     if (passPhrase == NULL) {
1247                         fprintf(stderr, _("Pass phrase check failed\n"));
1248                         exit(EXIT_FAILURE);
1249                     }
1250                     fprintf(stderr, _("Pass phrase is good.\n"));
1251                     passPhrase = xstrdup(passPhrase);
1252                     break;
1253                   default:
1254                     fprintf(stderr,
1255                             _("Invalid %%_signature spec in macro file.\n"));
1256                     exit(EXIT_FAILURE);
1257                     /*@notreached@*/ break;
1258                 }
1259             }
1260         } else {
1261             argerror(_("--sign may only be used during package building"));
1262         }
1263     } else {
1264         /* Make rpmLookupSignatureType() return 0 ("none") from now on */
1265         rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
1266     }
1267 #endif  /* IAM_RPMBT || IAM_RPMK */
1268
1269     if (pipeOutput) {
1270         pipe(p);
1271
1272         if (!(pipeChild = fork())) {
1273             close(p[1]);
1274             dup2(p[0], STDIN_FILENO);
1275             close(p[0]);
1276             execl("/bin/sh", "/bin/sh", "-c", pipeOutput, NULL);
1277             fprintf(stderr, _("exec failed\n"));
1278         }
1279
1280         close(p[0]);
1281         dup2(p[1], STDOUT_FILENO);
1282         close(p[1]);
1283     }
1284         
1285     switch (bigMode) {
1286 #ifdef  IAM_RPMDB
1287       case MODE_INITDB:
1288         rpmdbInit(rootdir, 0644);
1289         break;
1290
1291       case MODE_REBUILDDB:
1292         ec = rpmdbRebuild(rootdir);
1293         break;
1294       case MODE_QUERY:
1295       case MODE_VERIFY:
1296       case MODE_QUERYTAGS:
1297       case MODE_INSTALL:
1298       case MODE_UNINSTALL:
1299       case MODE_BUILD:
1300       case MODE_REBUILD:
1301       case MODE_RECOMPILE:
1302       case MODE_TARBUILD:
1303       case MODE_CHECKSIG:
1304       case MODE_RESIGN:
1305         if (!showVersion && !help && !noUsageMsg) printUsage();
1306         break;
1307 #endif  /* IAM_RPMDB */
1308
1309 #ifdef  IAM_RPMBT
1310       case MODE_REBUILD:
1311       case MODE_RECOMPILE:
1312       { const char * pkg;
1313         if (rpmIsNormal())
1314             rpmSetVerbosity(RPMMESS_VERBOSE);
1315
1316         if (!poptPeekArg(optCon))
1317             argerror(_("no packages files given for rebuild"));
1318
1319         ba->buildAmount = RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL;
1320         if (bigMode == MODE_REBUILD) {
1321             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
1322             ba->buildAmount |= RPMBUILD_RMSOURCE;
1323             ba->buildAmount |= RPMBUILD_RMSPEC;
1324             ba->buildAmount |= RPMBUILD_CLEAN;
1325             ba->buildAmount |= RPMBUILD_RMBUILD;
1326         }
1327
1328         while ((pkg = poptGetArg(optCon))) {
1329             const char * specFile = NULL;
1330             char * cookie = NULL;
1331
1332             ec = rpmInstallSource("", pkg, &specFile, &cookie);
1333             if (ec)
1334                 break;
1335
1336             ba->rootdir = rootdir;
1337             ec = build(specFile, ba, passPhrase, cookie, rcfile);
1338             free(cookie);
1339             cookie = NULL;
1340             free((void *)specFile);
1341             specFile = NULL;
1342
1343             if (ec)
1344                 break;
1345         }
1346       } break;
1347
1348       case MODE_BUILD:
1349       case MODE_TARBUILD:
1350       { const char * pkg;
1351         if (rpmIsNormal())
1352             rpmSetVerbosity(RPMMESS_VERBOSE);
1353        
1354         switch (ba->buildChar) {
1355           case 'a':
1356             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
1357             /*@fallthrough@*/
1358           case 'b':
1359             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
1360             ba->buildAmount |= RPMBUILD_CLEAN;
1361             /*@fallthrough@*/
1362           case 'i':
1363             ba->buildAmount |= RPMBUILD_INSTALL;
1364             if ((ba->buildChar == 'i') && ba->shortCircuit)
1365                 break;
1366             /*@fallthrough@*/
1367           case 'c':
1368             ba->buildAmount |= RPMBUILD_BUILD;
1369             if ((ba->buildChar == 'c') && ba->shortCircuit)
1370                 break;
1371             /*@fallthrough@*/
1372           case 'p':
1373             ba->buildAmount |= RPMBUILD_PREP;
1374             break;
1375             
1376           case 'l':
1377             ba->buildAmount |= RPMBUILD_FILECHECK;
1378             break;
1379           case 's':
1380             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
1381             break;
1382         }
1383
1384         if (!poptPeekArg(optCon)) {
1385             if (bigMode == MODE_BUILD)
1386                 argerror(_("no spec files given for build"));
1387             else
1388                 argerror(_("no tar files given for build"));
1389         }
1390
1391         while ((pkg = poptGetArg(optCon))) {
1392             ba->rootdir = rootdir;
1393             ec = build(pkg, ba, passPhrase, NULL, rcfile);
1394             if (ec)
1395                 break;
1396             rpmFreeMacros(NULL);
1397             rpmReadConfigFiles(rcfile, NULL);
1398         }
1399       } break;
1400
1401       case MODE_QUERY:
1402       case MODE_VERIFY:
1403       case MODE_QUERYTAGS:
1404       case MODE_INSTALL:
1405       case MODE_UNINSTALL:
1406       case MODE_CHECKSIG:
1407       case MODE_RESIGN:
1408       case MODE_INITDB:
1409       case MODE_REBUILDDB:
1410         if (!showVersion && !help && !noUsageMsg) printUsage();
1411         break;
1412 #endif  /* IAM_RPMBT */
1413
1414 #ifdef  IAM_RPMEIU
1415       case MODE_UNINSTALL:
1416         if (!poptPeekArg(optCon))
1417             argerror(_("no packages given for uninstall"));
1418
1419         if (noScripts) uninstallFlags |= RPMTRANS_FLAG_NOSCRIPTS;
1420         if (noTriggers) uninstallFlags |= RPMTRANS_FLAG_NOTRIGGERS;
1421         if (test) uninstallFlags |= RPMTRANS_FLAG_TEST;
1422         if (justdb) uninstallFlags |= RPMTRANS_FLAG_JUSTDB;
1423         if (noDeps) interfaceFlags |= UNINSTALL_NODEPS;
1424         if (allMatches) interfaceFlags |= UNINSTALL_ALLMATCHES;
1425
1426         ec = rpmErase(rootdir, (const char **)poptGetArgs(optCon), 
1427                          uninstallFlags, interfaceFlags);
1428         break;
1429
1430       case MODE_INSTALL:
1431         if (force) {
1432             probFilter |= RPMPROB_FILTER_REPLACEPKG | 
1433                           RPMPROB_FILTER_REPLACEOLDFILES |
1434                           RPMPROB_FILTER_REPLACENEWFILES |
1435                           RPMPROB_FILTER_OLDPACKAGE;
1436         }
1437         if (replaceFiles) probFilter |= RPMPROB_FILTER_REPLACEOLDFILES |
1438                                         RPMPROB_FILTER_REPLACENEWFILES;
1439         if (badReloc) probFilter |= RPMPROB_FILTER_FORCERELOCATE;
1440         if (replacePackages) probFilter |= RPMPROB_FILTER_REPLACEPKG;
1441         if (oldPackage) probFilter |= RPMPROB_FILTER_OLDPACKAGE;
1442         if (ignoreArch) probFilter |= RPMPROB_FILTER_IGNOREARCH; 
1443         if (ignoreOs) probFilter |= RPMPROB_FILTER_IGNOREOS;
1444         if (ignoreSize) probFilter |= RPMPROB_FILTER_DISKSPACE;
1445
1446         if (test) installFlags |= RPMTRANS_FLAG_TEST;
1447         /* RPMTRANS_FLAG_BUILD_PROBS */
1448         if (noScripts) installFlags |= RPMTRANS_FLAG_NOSCRIPTS;
1449         if (justdb) installFlags |= RPMTRANS_FLAG_JUSTDB;
1450         if (noTriggers) installFlags |= RPMTRANS_FLAG_NOTRIGGERS;
1451         if (!incldocs) {
1452             if (excldocs)
1453                 installFlags |= RPMTRANS_FLAG_NODOCS;
1454             else if (rpmExpandNumeric("%{_excludedocs}"))
1455                 installFlags |= RPMTRANS_FLAG_NODOCS;
1456         }
1457         if (allFiles) installFlags |= RPMTRANS_FLAG_ALLFILES;
1458         /* RPMTRANS_FLAG_KEEPOBSOLETE */
1459
1460         if (showPercents) interfaceFlags |= INSTALL_PERCENT;
1461         if (showHash) interfaceFlags |= INSTALL_HASH;
1462         if (noDeps) interfaceFlags |= INSTALL_NODEPS;
1463         if (noOrder) interfaceFlags |= INSTALL_NOORDER;
1464         if (upgrade) interfaceFlags |= INSTALL_UPGRADE;
1465         if (freshen) interfaceFlags |= (INSTALL_UPGRADE|INSTALL_FRESHEN);
1466
1467         if (!poptPeekArg(optCon))
1468             argerror(_("no packages given for install"));
1469
1470         /* we've already ensured !(!prefix && !relocations) */
1471         if (prefix) {
1472             relocations = alloca(2 * sizeof(*relocations));
1473             relocations[0].oldPath = NULL;   /* special case magic */
1474             relocations[0].newPath = prefix;
1475             relocations[1].oldPath = relocations[1].newPath = NULL;
1476         } else if (relocations) {
1477             relocations = xrealloc(relocations, 
1478                                   sizeof(*relocations) * (numRelocations + 1));
1479             relocations[numRelocations].oldPath = NULL;
1480             relocations[numRelocations].newPath = NULL;
1481         }
1482
1483         ec += rpmInstall(rootdir, (const char **)poptGetArgs(optCon), 
1484                         installFlags, interfaceFlags, probFilter, relocations);
1485         break;
1486       case MODE_QUERY:
1487       case MODE_VERIFY:
1488       case MODE_QUERYTAGS:
1489       case MODE_BUILD:
1490       case MODE_REBUILD:
1491       case MODE_RECOMPILE:
1492       case MODE_TARBUILD:
1493       case MODE_CHECKSIG:
1494       case MODE_RESIGN:
1495       case MODE_INITDB:
1496       case MODE_REBUILDDB:
1497         if (!showVersion && !help && !noUsageMsg) printUsage();
1498         break;
1499 #endif  /* IAM_RPMEIU */
1500
1501 #ifdef  IAM_RPMQV
1502       case MODE_QUERY:
1503       { const char * pkg;
1504
1505         qva->qva_prefix = rootdir;
1506         if (qva->qva_source == RPMQV_ALL) {
1507             if (poptPeekArg(optCon))
1508                 argerror(_("extra arguments given for query of all packages"));
1509
1510             ec = rpmQuery(qva, RPMQV_ALL, NULL);
1511         } else {
1512             if (!poptPeekArg(optCon))
1513                 argerror(_("no arguments given for query"));
1514             while ((pkg = poptGetArg(optCon)))
1515                 ec += rpmQuery(qva, qva->qva_source, pkg);
1516         }
1517       } break;
1518
1519       case MODE_VERIFY:
1520       { const char * pkg;
1521         int verifyFlags;
1522
1523         verifyFlags = (VERIFY_FILES|VERIFY_DEPS|VERIFY_SCRIPT|VERIFY_MD5);
1524         verifyFlags &= ~qva->qva_flags;
1525 #ifdef DYING
1526         if (noDeps)     verifyFlags &= ~VERIFY_DEPS;
1527         if (noScripts)  verifyFlags &= ~VERIFY_SCRIPT;
1528         if (noMd5)      verifyFlags &= ~VERIFY_MD5;
1529 #endif
1530
1531         qva->qva_prefix = rootdir;
1532         qva->qva_flags = verifyFlags;
1533         if (qva->qva_source == RPMQV_ALL) {
1534             if (poptPeekArg(optCon))
1535                 argerror(_("extra arguments given for verify of all packages"));
1536             ec = rpmVerify(qva, RPMQV_ALL, NULL);
1537         } else {
1538             if (!poptPeekArg(optCon))
1539                 argerror(_("no arguments given for verify"));
1540             while ((pkg = poptGetArg(optCon)))
1541                 ec += rpmVerify(qva, qva->qva_source, pkg);
1542         }
1543       } break;
1544
1545       case MODE_QUERYTAGS:
1546         if (argc != 2)
1547             argerror(_("unexpected arguments to --querytags "));
1548
1549         rpmDisplayQueryTags(stdout);
1550         break;
1551
1552       case MODE_INSTALL:
1553       case MODE_UNINSTALL:
1554       case MODE_BUILD:
1555       case MODE_REBUILD:
1556       case MODE_RECOMPILE:
1557       case MODE_TARBUILD:
1558       case MODE_CHECKSIG:
1559       case MODE_RESIGN:
1560       case MODE_INITDB:
1561       case MODE_REBUILDDB:
1562         if (!showVersion && !help && !noUsageMsg) printUsage();
1563         break;
1564 #endif  /* IAM_RPMQV */
1565
1566 #ifdef IAM_RPMK
1567       case MODE_CHECKSIG:
1568         if (!poptPeekArg(optCon))
1569             argerror(_("no packages given for signature check"));
1570         if (!noPgp) checksigFlags |= CHECKSIG_PGP;
1571         if (!noGpg) checksigFlags |= CHECKSIG_GPG;
1572         if (!noMd5) checksigFlags |= CHECKSIG_MD5;
1573         ec = rpmCheckSig(checksigFlags, (const char **)poptGetArgs(optCon));
1574         /* XXX don't overflow single byte exit status */
1575         if (ec > 255) ec = 255;
1576         break;
1577
1578       case MODE_RESIGN:
1579         if (!poptPeekArg(optCon))
1580             argerror(_("no packages given for signing"));
1581         ec = rpmReSign(addSign, passPhrase, (const char **)poptGetArgs(optCon));
1582         /* XXX don't overflow single byte exit status */
1583         if (ec > 255) ec = 255;
1584         break;
1585       case MODE_QUERY:
1586       case MODE_VERIFY:
1587       case MODE_QUERYTAGS:
1588       case MODE_INSTALL:
1589       case MODE_UNINSTALL:
1590       case MODE_BUILD:
1591       case MODE_REBUILD:
1592       case MODE_RECOMPILE:
1593       case MODE_TARBUILD:
1594       case MODE_INITDB:
1595       case MODE_REBUILDDB:
1596         if (!showVersion && !help && !noUsageMsg) printUsage();
1597         break;
1598 #endif  /* IAM_RPMK */
1599         
1600       case MODE_UNKNOWN:
1601         if (!showVersion && !help && !noUsageMsg) printUsage();
1602         break;
1603
1604     }
1605
1606     poptFreeContext(optCon);
1607     rpmFreeMacros(NULL);
1608     rpmFreeMacros(&rpmCLIMacroContext);
1609     rpmFreeRpmrc();
1610
1611     if (pipeChild) {
1612         fclose(stdout);
1613         (void)waitpid(pipeChild, &status, 0);
1614     }
1615
1616     /* keeps memory leak checkers quiet */
1617     freeNames();
1618     freeFilesystems();
1619     urlFreeCache();
1620
1621 #ifdef  IAM_RPMQV
1622     if (qva->qva_queryFormat) free((void *)qva->qva_queryFormat);
1623 #endif
1624
1625 #ifdef  IAM_RPMBT
1626     if (ba->buildRootOverride) free((void *)ba->buildRootOverride);
1627     if (ba->targets) free(ba->targets);
1628 #endif
1629
1630 #if HAVE_MCHECK_H && HAVE_MTRACE
1631     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
1632 #endif
1633     return ec;
1634 }