- add -I/usr/include/nptl, Conflicts: kernel <= 2.4.19.
[platform/upstream/rpm.git] / rpmqv.c
1 #include "system.h"
2
3 #define _AUTOHELP
4
5 #if defined(IAM_RPM) || defined(__LCLINT__)
6 #define IAM_RPMBT
7 #define IAM_RPMDB
8 #define IAM_RPMEIU
9 #define IAM_RPMQV
10 #define IAM_RPMK
11 #endif
12
13 #include <rpmcli.h>
14 #include <rpmbuild.h>
15
16 #include "rpmdb.h"
17 #include "rpmps.h"
18 #include "rpmts.h"
19
20 #ifdef  IAM_RPMBT
21 #include "build.h"
22 #define GETOPT_REBUILD          1003
23 #define GETOPT_RECOMPILE        1004
24 #endif
25
26 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
27 #include "signature.h"
28 #endif
29
30 #include "debug.h"
31
32 enum modes {
33
34     MODE_QUERY          = (1 <<  0),
35     MODE_VERIFY         = (1 <<  3),
36 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
37
38     MODE_INSTALL        = (1 <<  1),
39     MODE_ERASE          = (1 <<  2),
40 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
41
42     MODE_BUILD          = (1 <<  4),
43     MODE_REBUILD        = (1 <<  5),
44     MODE_RECOMPILE      = (1 <<  8),
45     MODE_TARBUILD       = (1 << 11),
46 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE)
47
48     MODE_CHECKSIG       = (1 <<  6),
49     MODE_RESIGN         = (1 <<  7),
50 #define MODES_K  (MODE_CHECKSIG | MODE_RESIGN)
51
52     MODE_INITDB         = (1 << 10),
53     MODE_REBUILDDB      = (1 << 12),
54     MODE_VERIFYDB       = (1 << 13),
55 #define MODES_DB (MODE_INITDB | MODE_REBUILDDB | MODE_VERIFYDB)
56
57
58     MODE_UNKNOWN        = 0
59 };
60
61 #define MODES_FOR_DBPATH        (MODES_BT | MODES_IE | MODES_QV | MODES_DB)
62 #define MODES_FOR_NODEPS        (MODES_BT | MODES_IE | MODE_VERIFY)
63 #define MODES_FOR_TEST          (MODES_BT | MODES_IE)
64 #define MODES_FOR_ROOT          (MODES_BT | MODES_IE | MODES_QV | MODES_DB | MODES_K)
65
66 /* the structure describing the options we take and the defaults */
67 /*@unchecked@*/
68 static struct poptOption optionsTable[] = {
69
70 #ifdef  IAM_RPMQV
71  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
72         N_("Query options (with -q or --query):"),
73         NULL },
74  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
75         N_("Verify options (with -V or --verify):"),
76         NULL },
77 #endif  /* IAM_RPMQV */
78
79 #ifdef  IAM_RPMK
80  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmSignPoptTable, 0,
81         N_("Signature options:"),
82         NULL },
83 #endif  /* IAM_RPMK */
84
85 #ifdef  IAM_RPMDB
86  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmDatabasePoptTable, 0,
87         N_("Database options:"),
88         NULL },
89 #endif  /* IAM_RPMDB */
90
91 #ifdef  IAM_RPMBT
92  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
93         N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
94         NULL },
95 #endif  /* IAM_RPMBT */
96
97 #ifdef  IAM_RPMEIU
98  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
99         N_("Install/Upgrade/Erase options:"),
100         NULL },
101 #endif  /* IAM_RPMEIU */
102
103  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
104         N_("Common options for all rpm modes:"),
105         NULL },
106
107    POPT_AUTOALIAS
108    POPT_AUTOHELP
109    POPT_TABLEEND
110 };
111
112 #ifdef __MINT__
113 /* MiNT cannot dynamically increase the stack.  */
114 long _stksize = 64 * 1024L;
115 #endif
116
117 /*@exits@*/ static void argerror(const char * desc)
118         /*@globals __assert_program_name, fileSystem @*/
119         /*@modifies fileSystem @*/
120 {
121     fprintf(stderr, _("%s: %s\n"), __progname, desc);
122     exit(EXIT_FAILURE);
123 }
124
125 static void printVersion(FILE * fp)
126         /*@globals rpmEVR, fileSystem @*/
127         /*@modifies *fp, fileSystem @*/
128 {
129     fprintf(fp, _("RPM version %s\n"), rpmEVR);
130 }
131
132 static void printBanner(FILE * fp)
133         /*@globals fileSystem @*/
134         /*@modifies *fp, fileSystem @*/
135 {
136     fprintf(fp, _("Copyright (C) 1998-2002 - Red Hat, Inc.\n"));
137     fprintf(fp, _("This program may be freely redistributed under the terms of the GNU GPL\n"));
138 }
139
140 static void printUsage(poptContext con, FILE * fp, int flags)
141         /*@globals rpmEVR, fileSystem, internalState @*/
142         /*@modifies *fp, fileSystem, internalState @*/
143 {
144     printVersion(fp);
145     printBanner(fp);
146     fprintf(fp, "\n");
147
148     if (rpmIsVerbose())
149         poptPrintHelp(con, fp, flags);
150     else
151         poptPrintUsage(con, fp, flags);
152 }
153
154 /*@-bounds@*/ /* LCL: segfault */
155 /*@-mods@*/ /* FIX: shrug */
156 #if !defined(__GLIBC__) && !defined(__LCLINT__)
157 int main(int argc, const char ** argv, /*@unused@*/ char ** envp)
158 #else
159 int main(int argc, const char ** argv)
160 #endif
161         /*@globals __assert_program_name, rpmEVR, RPMVERSION,
162                 rpmGlobalMacroContext, rpmCLIMacroContext,
163                 fileSystem, internalState@*/
164         /*@modifies __assert_program_name,
165                 fileSystem, internalState@*/
166 {
167     rpmts ts = NULL;
168     enum modes bigMode = MODE_UNKNOWN;
169
170 #if defined(IAM_RPMQV)
171     QVA_t qva = &rpmQVKArgs;
172 #endif
173
174 #ifdef  IAM_RPMBT
175     BTA_t ba = &rpmBTArgs;
176 #endif
177
178 #ifdef  IAM_RPMEIU
179    struct rpmInstallArguments_s * ia = &rpmIArgs;
180 #endif
181
182 #if defined(IAM_RPMDB)
183    struct rpmDatabaseArguments_s * da = &rpmDBArgs;
184 #endif
185
186 #if defined(IAM_RPMK)
187    QVA_t ka = &rpmQVKArgs;
188 #endif
189
190 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
191     char * passPhrase = "";
192 #endif
193
194     int arg;
195
196     const char * optArg;
197     pid_t pipeChild = 0;
198     poptContext optCon;
199     int ec = 0;
200     int status;
201     int p[2];
202 #ifdef  IAM_RPMEIU
203     int i;
204 #endif
205         
206 #if HAVE_MCHECK_H && HAVE_MTRACE
207     /*@-noeffect@*/
208     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
209     /*@=noeffect@*/
210 #endif
211     setprogname(argv[0]);       /* Retrofit glibc __progname */
212
213 #if !defined(__GLIBC__) && !defined(__LCLINT__)
214     environ = envp;
215 #endif  
216
217     /* XXX glibc churn sanity */
218     if (__progname == NULL) {
219         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
220         else __progname = argv[0];
221     }
222
223     /* Set the major mode based on argv[0] */
224     /*@-nullpass@*/
225 #ifdef  IAM_RPMBT
226     if (!strcmp(__progname, "rpmb"))    bigMode = MODE_BUILD;
227     if (!strcmp(__progname, "lt-rpmb")) bigMode = MODE_BUILD;
228     if (!strcmp(__progname, "rpmt"))    bigMode = MODE_TARBUILD;
229     if (!strcmp(__progname, "rpmbuild"))        bigMode = MODE_BUILD;
230 #endif
231 #ifdef  IAM_RPMQV
232     if (!strcmp(__progname, "rpmq"))    bigMode = MODE_QUERY;
233     if (!strcmp(__progname, "lt-rpmq")) bigMode = MODE_QUERY;
234     if (!strcmp(__progname, "rpmv"))    bigMode = MODE_VERIFY;
235     if (!strcmp(__progname, "rpmquery"))        bigMode = MODE_QUERY;
236     if (!strcmp(__progname, "rpmverify"))       bigMode = MODE_VERIFY;
237 #endif
238 #ifdef  RPMEIU
239     if (!strcmp(__progname, "rpme"))    bigMode = MODE_ERASE;
240     if (!strcmp(__progname, "rpmi"))    bigMode = MODE_INSTALL;
241     if (!strcmp(__progname, "lt-rpmi")) bigMode = MODE_INSTALL;
242     if (!strcmp(__progname, "rpmu"))    bigMode = MODE_INSTALL;
243 #endif
244     /*@=nullpass@*/
245
246 #if defined(IAM_RPMQV)
247     /* Jumpstart option from argv[0] if necessary. */
248     switch (bigMode) {
249     case MODE_QUERY:    qva->qva_mode = 'q';    break;
250     case MODE_VERIFY:   qva->qva_mode = 'V';    break;
251     case MODE_CHECKSIG: qva->qva_mode = 'K';    break;
252     case MODE_RESIGN:   qva->qva_mode = 'R';    break;
253     case MODE_INSTALL:
254     case MODE_ERASE:
255     case MODE_BUILD:
256     case MODE_REBUILD:
257     case MODE_RECOMPILE:
258     case MODE_TARBUILD:
259     case MODE_INITDB:
260     case MODE_REBUILDDB:
261     case MODE_VERIFYDB:
262     case MODE_UNKNOWN:
263     default:
264         break;
265     }
266
267     /* XXX Eliminate query linkage loop */
268     /*@-type@*/ /* FIX: casts? */
269     parseSpecVec = parseSpec;
270     freeSpecVec = freeSpec;
271     /*@=type@*/
272 #endif
273
274 #if defined(ENABLE_NLS)
275     /* set up the correct locale */
276     (void) setlocale(LC_ALL, "" );
277
278 #ifdef  __LCLINT__
279 #define LOCALEDIR       "/usr/share/locale"
280 #endif
281     bindtextdomain(PACKAGE, LOCALEDIR);
282     textdomain(PACKAGE);
283 #endif
284
285     rpmSetVerbosity(RPMMESS_NORMAL);    /* XXX silly use by showrc */
286
287     /* Make a first pass through the arguments, looking for --rcfile */
288     /* We need to handle that before dealing with the rest of the arguments. */
289     /*@-nullpass -temptrans@*/
290     optCon = poptGetContext(__progname, argc, argv, optionsTable, 0);
291     /*@=nullpass =temptrans@*/
292     (void) poptReadConfigFile(optCon, LIBRPMALIAS_FILENAME);
293     (void) poptReadDefaultConfig(optCon, 1);
294     poptSetExecPath(optCon, RPMCONFIGDIR, 1);
295
296     while ((arg = poptGetNextOpt(optCon)) > 0) {
297         optArg = poptGetOptArg(optCon);
298
299         switch (arg) {
300         default:
301             fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
302             exit(EXIT_FAILURE);
303         }
304     }
305
306     if (arg < -1) {
307         fprintf(stderr, "%s: %s\n", 
308                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
309                 poptStrerror(arg));
310         exit(EXIT_FAILURE);
311     }
312
313     rpmcliConfigured();
314
315 #ifdef  IAM_RPMBT
316     switch (ba->buildMode) {
317     case 'b':   bigMode = MODE_BUILD;           break;
318     case 't':   bigMode = MODE_TARBUILD;        break;
319     case 'B':   bigMode = MODE_REBUILD;         break;
320     case 'C':   bigMode = MODE_RECOMPILE;       break;
321     }
322
323     if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
324         bigMode = MODE_BUILD;
325
326     if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
327         bigMode = MODE_BUILD;
328
329     if (ba->buildRootOverride && bigMode != MODE_BUILD &&
330         bigMode != MODE_REBUILD && bigMode != MODE_TARBUILD) {
331         argerror("--buildroot may only be used during package builds");
332     }
333 #endif  /* IAM_RPMBT */
334     
335 #ifdef  IAM_RPMDB
336   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_DB)) {
337     if (da->init) {
338         if (bigMode != MODE_UNKNOWN) 
339             argerror(_("only one major mode may be specified"));
340         else
341             bigMode = MODE_INITDB;
342     } else
343     if (da->rebuild) {
344         if (bigMode != MODE_UNKNOWN) 
345             argerror(_("only one major mode may be specified"));
346         else
347             bigMode = MODE_REBUILDDB;
348     } else
349     if (da->verify) {
350         if (bigMode != MODE_UNKNOWN) 
351             argerror(_("only one major mode may be specified"));
352         else
353             bigMode = MODE_VERIFYDB;
354     }
355   }
356 #endif  /* IAM_RPMDB */
357
358 #ifdef  IAM_RPMQV
359   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
360     switch (qva->qva_mode) {
361     case 'q':   bigMode = MODE_QUERY;           break;
362     case 'V':   bigMode = MODE_VERIFY;          break;
363     }
364
365     if (qva->qva_sourceCount) {
366         if (qva->qva_sourceCount > 2)
367             argerror(_("one type of query/verify may be performed at a "
368                         "time"));
369     }
370     if (qva->qva_flags && (bigMode & ~MODES_QV)) 
371         argerror(_("unexpected query flags"));
372
373     if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
374         argerror(_("unexpected query format"));
375
376     if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
377         argerror(_("unexpected query source"));
378   }
379 #endif  /* IAM_RPMQV */
380
381 #ifdef  IAM_RPMEIU
382   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
383     {   int iflags = (ia->installInterfaceFlags &
384                 (INSTALL_UPGRADE|INSTALL_FRESHEN|INSTALL_INSTALL));
385         int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
386
387         if (iflags & eflags)
388             argerror(_("only one major mode may be specified"));
389         else if (iflags)
390             bigMode = MODE_INSTALL;
391         else if (eflags)
392             bigMode = MODE_ERASE;
393     }
394 #endif  /* IAM_RPMEIU */
395
396 #ifdef  IAM_RPMK
397   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_K)) {
398         switch (ka->qva_mode) {
399         case RPMSIGN_NONE:
400             ka->sign = 0;
401             break;
402         case RPMSIGN_IMPORT_PUBKEY:
403         case RPMSIGN_CHK_SIGNATURE:
404             bigMode = MODE_CHECKSIG;
405             ka->sign = 0;
406             break;
407         case RPMSIGN_ADD_SIGNATURE:
408         case RPMSIGN_NEW_SIGNATURE:
409             bigMode = MODE_RESIGN;
410             ka->sign = 1;
411             break;
412         }
413   }
414 #endif  /* IAM_RPMK */
415
416 #if defined(IAM_RPMEIU)
417     if (!( bigMode == MODE_INSTALL ) &&
418 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_REPLACEOLDFILES | RPMPROB_FILTER_REPLACENEWFILES | RPMPROB_FILTER_OLDPACKAGE)))
419         argerror(_("only installation, upgrading, rmsource and rmspec may be forced"));
420     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
421         argerror(_("files may only be relocated during package installation"));
422
423     if (ia->relocations && ia->prefix)
424         argerror(_("cannot use --prefix with --relocate or --excludepath"));
425
426     if (bigMode != MODE_INSTALL && ia->relocations)
427         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
428
429     if (bigMode != MODE_INSTALL && ia->prefix)
430         argerror(_("--prefix may only be used when installing new packages"));
431
432     if (ia->prefix && ia->prefix[0] != '/') 
433         argerror(_("arguments to --prefix must begin with a /"));
434
435     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_HASH))
436         argerror(_("--hash (-h) may only be specified during package "
437                         "installation"));
438
439     if (bigMode != MODE_INSTALL && (ia->installInterfaceFlags & INSTALL_PERCENT))
440         argerror(_("--percent may only be specified during package "
441                         "installation"));
442
443     if (bigMode != MODE_INSTALL &&
444  (ia->probFilter & (RPMPROB_FILTER_REPLACEOLDFILES|RPMPROB_FILTER_REPLACENEWFILES)))
445         argerror(_("--replacefiles may only be specified during package "
446                         "installation"));
447
448     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
449         argerror(_("--replacepkgs may only be specified during package "
450                         "installation"));
451
452     if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
453         argerror(_("--excludedocs may only be specified during package "
454                    "installation"));
455
456     if (bigMode != MODE_INSTALL && ia->incldocs)
457         argerror(_("--includedocs may only be specified during package "
458                    "installation"));
459
460     if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
461         argerror(_("only one of --excludedocs and --includedocs may be "
462                  "specified"));
463   
464     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
465         argerror(_("--ignorearch may only be specified during package "
466                    "installation"));
467
468     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
469         argerror(_("--ignoreos may only be specified during package "
470                    "installation"));
471
472     if (bigMode != MODE_INSTALL &&
473         (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
474         argerror(_("--ignoresize may only be specified during package "
475                    "installation"));
476
477     if ((ia->eraseInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
478         argerror(_("--allmatches may only be specified during package "
479                    "erasure"));
480
481     if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
482         argerror(_("--allfiles may only be specified during package "
483                    "installation"));
484
485     if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
486         bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
487         argerror(_("--justdb may only be specified during package "
488                    "installation and erasure"));
489
490     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
491         (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
492         argerror(_("script disabling options may only be specified during "
493                    "package installation and erasure"));
494
495     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
496         (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
497         argerror(_("trigger disabling options may only be specified during "
498                    "package installation and erasure"));
499
500     if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
501         argerror(_("--nodeps may only be specified during package "
502                    "building, rebuilding, recompilation, installation,"
503                    "erasure, and verification"));
504
505     if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
506         argerror(_("--test may only be specified during package installation, "
507                  "erasure, and building"));
508 #endif  /* IAM_RPMEIU */
509
510     if (rpmcliRootDir && rpmcliRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
511         argerror(_("--root (-r) may only be specified during "
512                  "installation, erasure, querying, and "
513                  "database rebuilds"));
514
515     if (rpmcliRootDir) {
516         switch (urlIsURL(rpmcliRootDir)) {
517         default:
518             if (bigMode & MODES_FOR_ROOT)
519                 break;
520             /*@fallthrough@*/
521         case URL_IS_UNKNOWN:
522             if (rpmcliRootDir[0] != '/')
523                 argerror(_("arguments to --root (-r) must begin with a /"));
524             break;
525         }
526     }
527
528 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
529     if (0
530 #if defined(IAM_RPMBT)
531     || ba->sign 
532 #endif
533 #if defined(IAM_RPMK)
534     || ka->sign
535 #endif
536     )
537     /*@-branchstate@*/
538     {
539         if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
540             bigMode == MODE_RESIGN || bigMode == MODE_TARBUILD)
541         {
542             const char ** av;
543             struct stat sb;
544             int errors = 0;
545
546             if ((av = poptGetArgs(optCon)) == NULL) {
547                 fprintf(stderr, _("no files to sign\n"));
548                 errors++;
549             } else
550             while (*av) {
551                 if (stat(*av, &sb)) {
552                     fprintf(stderr, _("cannot access file %s\n"), *av);
553                     errors++;
554                 }
555                 av++;
556             }
557
558             if (errors) {
559                 ec = errors;
560                 goto exit;
561             }
562
563             if (poptPeekArg(optCon)) {
564                 int sigTag;
565                 switch (sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY)) {
566                   case 0:
567                     break;
568                   case RPMSIGTAG_PGP:
569                     if ((sigTag == RPMSIGTAG_PGP || sigTag == RPMSIGTAG_PGP5) &&
570                         !rpmDetectPGPVersion(NULL)) {
571                         fprintf(stderr, _("pgp not found: "));
572                         ec = EXIT_FAILURE;
573                         goto exit;
574                     }   /*@fallthrough@*/
575                   case RPMSIGTAG_GPG:
576                     passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
577                     if (passPhrase == NULL) {
578                         fprintf(stderr, _("Pass phrase check failed\n"));
579                         ec = EXIT_FAILURE;
580                         goto exit;
581                     }
582                     fprintf(stderr, _("Pass phrase is good.\n"));
583                     passPhrase = xstrdup(passPhrase);
584                     break;
585                   default:
586                     fprintf(stderr,
587                             _("Invalid %%_signature spec in macro file.\n"));
588                     ec = EXIT_FAILURE;
589                     goto exit;
590                     /*@notreached@*/ break;
591                 }
592             }
593         } else {
594             argerror(_("--sign may only be used during package building"));
595         }
596     } else {
597         /* Make rpmLookupSignatureType() return 0 ("none") from now on */
598         (void) rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
599     }
600     /*@=branchstate@*/
601 #endif  /* IAM_RPMBT || IAM_RPMK */
602
603     if (rpmcliPipeOutput) {
604         (void) pipe(p);
605
606         if (!(pipeChild = fork())) {
607             (void) close(p[1]);
608             (void) dup2(p[0], STDIN_FILENO);
609             (void) close(p[0]);
610             (void) execl("/bin/sh", "/bin/sh", "-c", rpmcliPipeOutput, NULL);
611             fprintf(stderr, _("exec failed\n"));
612         }
613
614         (void) close(p[0]);
615         (void) dup2(p[1], STDOUT_FILENO);
616         (void) close(p[1]);
617     }
618         
619     ts = rpmtsCreate();
620     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
621     switch (bigMode) {
622 #ifdef  IAM_RPMDB
623     case MODE_INITDB:
624         (void) rpmtsInitDB(ts, 0644);
625         break;
626
627     case MODE_REBUILDDB:
628     {   rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
629         rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
630         ec = rpmtsRebuildDB(ts);
631         vsflags = rpmtsSetVSFlags(ts, ovsflags);
632     }   break;
633     case MODE_VERIFYDB:
634         ec = rpmtsVerifyDB(ts);
635         break;
636 #endif  /* IAM_RPMDB */
637
638 #ifdef  IAM_RPMBT
639     case MODE_REBUILD:
640     case MODE_RECOMPILE:
641     {   const char * pkg;
642
643         while (!rpmIsVerbose())
644             rpmIncreaseVerbosity();
645
646         if (!poptPeekArg(optCon))
647             argerror(_("no packages files given for rebuild"));
648
649         ba->buildAmount = RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL;
650         if (bigMode == MODE_REBUILD) {
651             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
652             ba->buildAmount |= RPMBUILD_RMSOURCE;
653             ba->buildAmount |= RPMBUILD_RMSPEC;
654             ba->buildAmount |= RPMBUILD_CLEAN;
655             ba->buildAmount |= RPMBUILD_RMBUILD;
656         }
657
658         while ((pkg = poptGetArg(optCon))) {
659             const char * specFile = NULL;
660
661             ba->cookie = NULL;
662             ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
663             if (ec == 0) {
664                 ba->rootdir = rpmcliRootDir;
665                 ba->passPhrase = passPhrase;
666                 ec = build(ts, specFile, ba, rpmcliRcfile);
667             }
668             ba->cookie = _free(ba->cookie);
669             specFile = _free(specFile);
670
671             if (ec)
672                 /*@loopbreak@*/ break;
673         }
674
675     }   break;
676
677     case MODE_BUILD:
678     case MODE_TARBUILD:
679     {   const char * pkg;
680         while (!rpmIsVerbose())
681             rpmIncreaseVerbosity();
682        
683         switch (ba->buildChar) {
684         case 'a':
685             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
686             /*@fallthrough@*/
687         case 'b':
688             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
689             ba->buildAmount |= RPMBUILD_CLEAN;
690             /*@fallthrough@*/
691         case 'i':
692             ba->buildAmount |= RPMBUILD_INSTALL;
693             if ((ba->buildChar == 'i') && ba->shortCircuit)
694                 /*@innerbreak@*/ break;
695             /*@fallthrough@*/
696         case 'c':
697             ba->buildAmount |= RPMBUILD_BUILD;
698             if ((ba->buildChar == 'c') && ba->shortCircuit)
699                 /*@innerbreak@*/ break;
700             /*@fallthrough@*/
701         case 'p':
702             ba->buildAmount |= RPMBUILD_PREP;
703             /*@innerbreak@*/ break;
704             
705         case 'l':
706             ba->buildAmount |= RPMBUILD_FILECHECK;
707             /*@innerbreak@*/ break;
708         case 's':
709             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
710             /*@innerbreak@*/ break;
711         }
712
713         if (!poptPeekArg(optCon)) {
714             if (bigMode == MODE_BUILD)
715                 argerror(_("no spec files given for build"));
716             else
717                 argerror(_("no tar files given for build"));
718         }
719
720         while ((pkg = poptGetArg(optCon))) {
721             ba->rootdir = rpmcliRootDir;
722             ba->passPhrase = passPhrase;
723             ba->cookie = NULL;
724             ec = build(ts, pkg, ba, rpmcliRcfile);
725             if (ec)
726                 /*@loopbreak@*/ break;
727             rpmFreeMacros(NULL);
728             (void) rpmReadConfigFiles(rpmcliRcfile, NULL);
729         }
730     }   break;
731 #endif  /* IAM_RPMBT */
732
733 #ifdef  IAM_RPMEIU
734     case MODE_ERASE:
735         if (ia->noDeps) ia->eraseInterfaceFlags |= UNINSTALL_NODEPS;
736
737         if (!poptPeekArg(optCon)) {
738             if (ia->rbtid == 0)
739                 argerror(_("no packages given for erase"));
740 ia->transFlags |= RPMTRANS_FLAG_NOMD5;
741 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
742             ec += rpmRollback(ts, ia, NULL);
743         } else {
744             ec += rpmErase(ts, ia, (const char **) poptGetArgs(optCon));
745         }
746         break;
747
748     case MODE_INSTALL:
749
750         /* RPMTRANS_FLAG_KEEPOBSOLETE */
751
752         if (!ia->incldocs) {
753             if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
754                 ;
755             } else if (rpmExpandNumeric("%{_excludedocs}"))
756                 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
757         }
758
759         if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
760
761         /* we've already ensured !(!ia->prefix && !ia->relocations) */
762         /*@-branchstate@*/
763         if (ia->prefix) {
764             ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
765             ia->relocations[0].oldPath = NULL;   /* special case magic */
766             ia->relocations[0].newPath = ia->prefix;
767             ia->relocations[1].oldPath = NULL;
768             ia->relocations[1].newPath = NULL;
769         } else if (ia->relocations) {
770             ia->relocations = xrealloc(ia->relocations, 
771                         sizeof(*ia->relocations) * (ia->numRelocations + 1));
772             ia->relocations[ia->numRelocations].oldPath = NULL;
773             ia->relocations[ia->numRelocations].newPath = NULL;
774         }
775         /*@=branchstate@*/
776
777         if (!poptPeekArg(optCon)) {
778             if (ia->rbtid == 0)
779                 argerror(_("no packages given for install"));
780 ia->transFlags |= RPMTRANS_FLAG_NOMD5;
781 ia->probFilter |= RPMPROB_FILTER_OLDPACKAGE;
782 /*@i@*/     ec += rpmRollback(ts, ia, NULL);
783         } else {
784             /*@-compdef -compmempass@*/ /* FIX: ia->relocations[0].newPath undefined */
785             ec += rpmInstall(ts, ia, (const char **)poptGetArgs(optCon));
786             /*@=compdef =compmempass@*/
787         }
788         break;
789
790 #endif  /* IAM_RPMEIU */
791
792 #ifdef  IAM_RPMQV
793     case MODE_QUERY:
794         if (qva->qva_source != RPMQV_ALL && !poptPeekArg(optCon))
795             argerror(_("no arguments given for query"));
796         ec = rpmcliQuery(ts, qva, (const char **) poptGetArgs(optCon));
797         /* XXX don't overflow single byte exit status */
798         if (ec > 255) ec = 255;
799         break;
800
801     case MODE_VERIFY:
802     {   rpmVerifyFlags verifyFlags = VERIFY_ALL;
803
804         verifyFlags &= ~qva->qva_flags;
805         qva->qva_flags = (rpmQueryFlags) verifyFlags;
806
807         if (qva->qva_source != RPMQV_ALL && !poptPeekArg(optCon))
808             argerror(_("no arguments given for verify"));
809         ec = rpmcliVerify(ts, qva, (const char **) poptGetArgs(optCon));
810         /* XXX don't overflow single byte exit status */
811         if (ec > 255) ec = 255;
812     }   break;
813 #endif  /* IAM_RPMQV */
814
815 #ifdef IAM_RPMK
816     case MODE_CHECKSIG:
817     {   rpmVerifyFlags verifyFlags =
818                 (VERIFY_MD5|VERIFY_DIGEST|VERIFY_SIGNATURE);
819
820         verifyFlags &= ~ka->qva_flags;
821         ka->qva_flags = (rpmQueryFlags) verifyFlags;
822     }   /*@fallthrough@*/
823     case MODE_RESIGN:
824         if (!poptPeekArg(optCon))
825             argerror(_("no arguments given"));
826         ka->passPhrase = passPhrase;
827         ec = rpmcliSign(ts, ka, (const char **)poptGetArgs(optCon));
828         /* XXX don't overflow single byte exit status */
829         if (ec > 255) ec = 255;
830         break;
831 #endif  /* IAM_RPMK */
832         
833 #if !defined(IAM_RPMQV)
834     case MODE_QUERY:
835     case MODE_VERIFY:
836 #endif
837 #if !defined(IAM_RPMK)
838     case MODE_CHECKSIG:
839     case MODE_RESIGN:
840 #endif
841 #if !defined(IAM_RPMDB)
842     case MODE_INITDB:
843     case MODE_REBUILDDB:
844     case MODE_VERIFYDB:
845 #endif
846 #if !defined(IAM_RPMBT)
847     case MODE_BUILD:
848     case MODE_REBUILD:
849     case MODE_RECOMPILE:
850     case MODE_TARBUILD:
851 #endif
852 #if !defined(IAM_RPMEIU)
853     case MODE_INSTALL:
854     case MODE_ERASE:
855 #endif
856     case MODE_UNKNOWN:
857         if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose())
858             printUsage(optCon, stdout, 0);
859         break;
860     }
861
862 #if defined(IAM_RPMBT) || defined(IAM_RPMK)
863 exit:
864 #endif  /* IAM_RPMBT || IAM_RPMK */
865
866     ts = rpmtsFree(ts);
867
868     optCon = poptFreeContext(optCon);
869     rpmFreeMacros(NULL);
870 /*@i@*/ rpmFreeMacros(rpmCLIMacroContext);
871     rpmFreeRpmrc();
872
873     if (pipeChild) {
874         (void) fclose(stdout);
875         (void) waitpid(pipeChild, &status, 0);
876     }
877
878     /* keeps memory leak checkers quiet */
879     freeFilesystems();
880 /*@i@*/ urlFreeCache();
881     rpmlogClose();
882     dbiTags = _free(dbiTags);
883
884 #ifdef  IAM_RPMQV
885     qva->qva_queryFormat = _free(qva->qva_queryFormat);
886 #endif
887
888 #ifdef  IAM_RPMBT
889     freeNames();
890     ba->buildRootOverride = _free(ba->buildRootOverride);
891     ba->targets = _free(ba->targets);
892 #endif
893
894 #ifdef  IAM_RPMEIU
895     if (ia->relocations != NULL)
896     for (i = 0; i < ia->numRelocations; i++)
897         ia->relocations[i].oldPath = _free(ia->relocations[i].oldPath);
898     ia->relocations = _free(ia->relocations);
899 #endif
900
901 #if HAVE_MCHECK_H && HAVE_MTRACE
902     /*@-noeffect@*/
903     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
904     /*@=noeffect@*/
905 #endif
906     /*@-globstate@*/
907     return ec;
908     /*@=globstate@*/
909 }
910 /*@=mods@*/
911 /*@=bounds@*/