Automated merge with file:/home/pmatilai/repos/rpm-whitespace
[platform/upstream/rpm.git] / lib / poptALL.c
1 /** \ingroup rpmcli
2  * \file lib/poptALL.c
3  *  Popt tables for all rpm modes.
4  */
5
6 #include "system.h"
7 const char *__progname;
8
9 #include <rpmcli.h>
10 #include <fts.h>
11
12 #include "debug.h"
13
14 #define POPT_SHOWVERSION        -999
15 #define POPT_SHOWRC             -998
16 #define POPT_QUERYTAGS          -997
17 #define POPT_PREDEFINE          -996
18 #ifdef  NOTYET
19 #define POPT_RCFILE             -995
20 #endif
21
22 /*@unchecked@*/
23 static int _debug = 0;
24
25 /*@-exportheadervar@*/
26 /*@unchecked@*/
27 extern int _rpmds_nopromote;
28
29 /*@unchecked@*/
30 extern int _fps_debug;
31
32 /*@unchecked@*/
33 extern int _fsm_debug;
34
35 /*@unchecked@*/
36 extern int _fsm_threads;
37
38 /*@unchecked@*/
39 extern int _hdr_debug;
40
41 /*@unchecked@*/
42 extern int _print_pkts;
43
44 /*@unchecked@*/
45 extern int _psm_debug;
46
47 /*@unchecked@*/
48 extern int _psm_threads;
49
50 /*@unchecked@*/
51 extern int _rpmal_debug;
52
53 /*@unchecked@*/
54 extern int _rpmdb_debug;
55
56 /*@unchecked@*/
57 extern int _rpmds_debug;
58
59 /* XXX avoid -lrpmbuild linkage. */
60 /*@unchecked@*/
61        int _rpmfc_debug;
62
63 /*@unchecked@*/
64 extern int _rpmfi_debug;
65
66 /*@unchecked@*/
67 extern int _rpmgi_debug;
68
69 /*@unchecked@*/
70 extern int _rpmps_debug;
71
72 /*@unchecked@*/
73 extern int _rpmsq_debug;
74
75 /*@unchecked@*/
76 extern int _rpmte_debug;
77
78 /*@unchecked@*/
79 extern int _rpmts_debug;
80
81 /*@unchecked@*/
82 extern int _rpmts_stats;
83
84 /*@unchecked@*/
85 extern int noLibio;
86 /*@=exportheadervar@*/
87
88 /*@unchecked@*/
89 const char * rpmcliPipeOutput = NULL;
90
91 /*@unchecked@*/
92 const char * rpmcliRcfile = NULL;
93
94 /*@unchecked@*/
95 const char * rpmcliRootDir = "/";
96
97 /*@unchecked@*/
98 rpmQueryFlags rpmcliQueryFlags;
99
100 /*@-exportheadervar@*/
101 /*@unchecked@*/
102 extern int _ftp_debug;
103 /*@unchecked@*/
104 extern int _av_debug;
105 /*@unchecked@*/
106 extern int _dav_debug;
107
108 /*@unchecked@*/
109 extern int noLibio;
110
111 /*@unchecked@*/
112 extern int _rpmio_debug;
113 /*@=exportheadervar@*/
114
115 /*@unchecked@*/
116 static int rpmcliInitialized = -1;
117
118 /**
119  * Display rpm version.
120  */
121 static void printVersion(FILE * fp)
122         /*@globals rpmEVR, fileSystem @*/
123         /*@modifies *fp, fileSystem @*/
124 {
125     fprintf(fp, _("RPM version %s\n"), rpmEVR);
126 }
127
128 /**
129  * Make sure that config files have been read.
130  * @warning Options like --rcfile and --verbose must precede callers option.
131  */
132 /*@mayexit@*/
133 void rpmcliConfigured(void)
134         /*@globals rpmcliInitialized, rpmCLIMacroContext, rpmGlobalMacroContext,
135                 h_errno, fileSystem, internalState @*/
136         /*@modifies rpmcliInitialized, rpmCLIMacroContext, rpmGlobalMacroContext,
137                 fileSystem, internalState @*/
138 {
139
140     if (rpmcliInitialized < 0)
141         rpmcliInitialized = rpmReadConfigFiles(rpmcliRcfile, NULL);
142     if (rpmcliInitialized)
143         exit(EXIT_FAILURE);
144 }
145
146 /**
147  */
148 /*@-bounds@*/
149 static void rpmcliAllArgCallback( /*@unused@*/ poptContext con,
150                 /*@unused@*/ enum poptCallbackReason reason,
151                 const struct poptOption * opt, const char * arg,
152                 /*@unused@*/ const void * data)
153         /*@globals rpmcliQueryFlags, rpmCLIMacroContext, rpmGlobalMacroContext,
154                 h_errno, fileSystem, internalState @*/
155         /*@modifies rpmcliQueryFlags, rpmCLIMacroContext, rpmGlobalMacroContext,
156                 fileSystem, internalState @*/
157 {
158
159     /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
160     /*@-branchstate@*/
161     if (opt->arg == NULL)
162     switch (opt->val) {
163     case 'q':
164         rpmSetVerbosity(RPMMESS_QUIET);
165         break;
166     case 'v':
167         rpmIncreaseVerbosity();
168         break;
169     case POPT_PREDEFINE:
170         (void) rpmDefineMacro(NULL, arg, RMIL_CMDLINE);
171         break;
172     case 'D':
173         /* XXX Predefine macro if not initialized yet. */
174         if (rpmcliInitialized < 0)
175             (void) rpmDefineMacro(NULL, arg, RMIL_CMDLINE);
176         rpmcliConfigured();
177 /*@-type@*/
178         (void) rpmDefineMacro(NULL, arg, RMIL_CMDLINE);
179         (void) rpmDefineMacro(rpmCLIMacroContext, arg, RMIL_CMDLINE);
180 /*@=type@*/
181         break;
182     case 'E':
183         rpmcliConfigured();
184         {   const char *val = rpmExpand(arg, NULL);
185             fprintf(stdout, "%s\n", val);
186             val = _free(val);
187         }
188         break;
189     case POPT_SHOWVERSION:
190         printVersion(stdout);
191         exit(EXIT_SUCCESS);
192         /*@notreached@*/ break;
193     case POPT_SHOWRC:
194         rpmcliConfigured();
195         (void) rpmShowRC(stdout);
196         exit(EXIT_SUCCESS);
197         /*@notreached@*/ break;
198     case POPT_QUERYTAGS:
199         rpmDisplayQueryTags(stdout);
200         exit(EXIT_SUCCESS);
201         /*@notreached@*/ break;
202 #if defined(POPT_RCFILE)
203     case POPT_RCFILE:           /* XXX FIXME: noop for now */
204         break;
205 #endif
206     case RPMCLI_POPT_NODIGEST:
207         rpmcliQueryFlags |= VERIFY_DIGEST;
208         break;
209
210     case RPMCLI_POPT_NOSIGNATURE:
211         rpmcliQueryFlags |= VERIFY_SIGNATURE;
212         break;
213
214     case RPMCLI_POPT_NOHDRCHK:
215         rpmcliQueryFlags |= VERIFY_HDRCHK;
216         break;
217     }
218     /*@=branchstate@*/
219 }
220
221 /*@unchecked@*/
222 int ftsOpts = 0;
223
224 /*@unchecked@*/
225 struct poptOption rpmcliFtsPoptTable[] = {
226  { "comfollow", '\0', POPT_BIT_SET,     &ftsOpts, FTS_COMFOLLOW,
227         N_("FTS_COMFOLLOW: follow command line symlinks"), NULL },
228  { "logical", '\0', POPT_BIT_SET,       &ftsOpts, FTS_LOGICAL,
229         N_("FTS_LOGICAL: logical walk"), NULL },
230  { "nochdir", '\0', POPT_BIT_SET,       &ftsOpts, FTS_NOCHDIR,
231         N_("FTS_NOCHDIR: don't change directories"), NULL },
232  { "nostat", '\0', POPT_BIT_SET,        &ftsOpts, FTS_NOSTAT,
233         N_("FTS_NOSTAT: don't get stat info"), NULL },
234  { "physical", '\0', POPT_BIT_SET,      &ftsOpts, FTS_PHYSICAL,
235         N_("FTS_PHYSICAL: physical walk"), NULL },
236  { "seedot", '\0', POPT_BIT_SET,        &ftsOpts, FTS_SEEDOT,
237         N_("FTS_SEEDOT: return dot and dot-dot"), NULL },
238  { "xdev", '\0', POPT_BIT_SET,          &ftsOpts, FTS_XDEV,
239         N_("FTS_XDEV: don't cross devices"), NULL },
240  { "whiteout", '\0', POPT_BIT_SET,      &ftsOpts, FTS_WHITEOUT,
241         N_("FTS_WHITEOUT: return whiteout information"), NULL },
242    POPT_TABLEEND
243 };
244
245 /*@-bitwisesigned -compmempass @*/
246 /*@unchecked@*/
247 struct poptOption rpmcliAllPoptTable[] = {
248 /*@-type@*/ /* FIX: cast? */
249  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
250         rpmcliAllArgCallback, 0, NULL, NULL },
251 /*@=type@*/
252
253  { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_debug, -1,
254         NULL, NULL },
255
256  { "predefine", 'D', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_PREDEFINE,
257         N_("predefine MACRO with value EXPR"),
258         N_("'MACRO EXPR'") },
259  { "define", 'D', POPT_ARG_STRING, 0, 'D',
260         N_("define MACRO with value EXPR"),
261         N_("'MACRO EXPR'") },
262  { "eval", 'E', POPT_ARG_STRING, 0, 'E',
263         N_("print macro expansion of EXPR"),
264         N_("'EXPR'") },
265  { "macros", '\0', POPT_ARG_STRING, &macrofiles, 0,
266         N_("read <FILE:...> instead of default file(s)"),
267         N_("<FILE:...>") },
268
269  { "nodigest", '\0', 0, 0, RPMCLI_POPT_NODIGEST,
270         N_("don't verify package digest(s)"), NULL },
271  { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_NOHDRCHK,
272         N_("don't verify database header(s) when retrieved"), NULL },
273 #if HAVE_LIBIO_H && defined(_G_IO_IO_FILE_VERSION)
274  { "nolibio", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noLibio, 1,
275         N_("disable use of libio(3) API"), NULL},
276 #endif
277  { "nosignature", '\0', 0, 0, RPMCLI_POPT_NOSIGNATURE,
278         N_("don't verify package signature(s)"), NULL },
279
280  { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &rpmcliPipeOutput, 0,
281         N_("send stdout to CMD"),
282         N_("CMD") },
283 #if !defined(POPT_RCFILE)
284  { "rcfile", '\0', POPT_ARG_STRING, &rpmcliRcfile, 0,
285         N_("read <FILE:...> instead of default file(s)"),
286         N_("<FILE:...>") },
287 #else
288  { "rcfile", '\0', 0, NULL, POPT_RCFILE,        
289         N_("read <FILE:...> instead of default file(s)"),
290         N_("<FILE:...>") },
291 #endif
292  { "root", 'r', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmcliRootDir, 0,
293         N_("use ROOT as top level directory"),
294         N_("ROOT") },
295
296  { "querytags", '\0', 0, 0, POPT_QUERYTAGS,
297         N_("display known query tags"), NULL },
298  { "showrc", '\0', 0, NULL, POPT_SHOWRC,
299         N_("display final rpmrc and macro configuration"), NULL },
300  { "quiet", '\0', 0, NULL, 'q',
301         N_("provide less detailed output"), NULL},
302  { "verbose", 'v', 0, NULL, 'v',
303         N_("provide more detailed output"), NULL},
304  { "version", '\0', 0, NULL, POPT_SHOWVERSION,
305         N_("print the version of rpm being used"), NULL },
306
307 #if HAVE_LIBIO_H && defined(_G_IO_IO_FILE_VERSION)
308  { "nolibio", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noLibio, 1,
309        N_("disable use of libio(3) API"), NULL},
310 #endif
311
312  { "promoteepoch", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_nopromote, 0,
313         NULL, NULL},
314
315  { "fpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fps_debug, -1,
316         NULL, NULL},
317  { "fsmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_debug, -1,
318         N_("debug payload file state machine"), NULL},
319  { "fsmthreads", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_threads, -1,
320         N_("use threads for file state machine"), NULL},
321  { "ftpdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_ftp_debug, -1,
322         N_("debug FTP/HTTP data stream"), NULL},
323  { "avdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_av_debug, -1,
324         N_("debug argv collections"), NULL},
325  { "davdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_dav_debug, -1,
326         N_("debug WebDAV data stream"), NULL},
327  { "hdrdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_hdr_debug, -1,
328         NULL, NULL},
329 #ifdef  DYING
330  { "poptdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_popt_debug, -1,
331         N_("debug option/argument processing"), NULL},
332 #endif
333  { "prtpkts", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_print_pkts, -1,
334         NULL, NULL},
335  { "psmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_psm_debug, -1,
336         N_("debug package state machine"), NULL},
337  { "psmthreads", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_psm_threads, -1,
338         N_("use threads for package state machine"), NULL},
339  { "rpmaldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmal_debug, -1,
340         NULL, NULL},
341  { "rpmdbdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmdb_debug, -1,
342         NULL, NULL},
343  { "rpmdsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmds_debug, -1,
344         NULL, NULL},
345  { "rpmfcdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfc_debug, -1,
346         NULL, NULL},
347  { "rpmfidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfi_debug, -1,
348         NULL, NULL},
349  { "rpmgidebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmgi_debug, -1,
350         NULL, NULL},
351  { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
352         N_("debug rpmio I/O"), NULL},
353  { "rpmpsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmps_debug, -1,
354         NULL, NULL},
355  { "rpmsqdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmsq_debug, -1,
356         NULL, NULL},
357  { "rpmtedebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmte_debug, -1,
358         NULL, NULL},
359  { "rpmtsdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_debug, -1,
360         NULL, NULL},
361  { "stats", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_stats, -1,
362         NULL, NULL},
363  { "urldebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_url_debug, -1,
364         N_("debug URL cache handling"), NULL},
365
366    POPT_TABLEEND
367 };
368 /*@=bitwisesigned =compmempass @*/
369
370 poptContext
371 rpmcliFini(poptContext optCon)
372 {
373     optCon = poptFreeContext(optCon);
374
375 #if HAVE_MCHECK_H && HAVE_MTRACE
376     /*@-noeffect@*/
377     muntrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
378     /*@=noeffect@*/
379 #endif
380
381     return NULL;
382 }
383
384 /*@-globstate@*/
385 poptContext
386 rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
387 {
388     const char * optArg;
389     poptContext optCon;
390     int rc;
391
392 #if HAVE_MCHECK_H && HAVE_MTRACE
393     /*@-noeffect@*/
394     mtrace();   /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
395     /*@=noeffect@*/
396 #endif
397 /*@-globs -mods@*/
398     setprogname(argv[0]);       /* Retrofit glibc __progname */
399
400     /* XXX glibc churn sanity */
401     if (__progname == NULL) {
402         if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
403         else __progname = argv[0];
404     }
405 /*@=globs =mods@*/
406
407 #if defined(ENABLE_NLS)
408     (void) setlocale(LC_ALL, "" );
409     (void) bindtextdomain(PACKAGE, LOCALEDIR);
410     (void) textdomain(PACKAGE);
411 #endif
412
413     rpmSetVerbosity(RPMMESS_NORMAL);
414
415     if (optionsTable == NULL) {
416         /* Read rpm configuration (if not already read). */
417         rpmcliConfigured();
418         return NULL;
419     }
420
421 /*@-nullpass -temptrans@*/
422     optCon = poptGetContext(__progname, argc, (const char **)argv, optionsTable, 0);
423 /*@=nullpass =temptrans@*/
424     (void) poptReadConfigFile(optCon, LIBRPMALIAS_FILENAME);
425     (void) poptReadDefaultConfig(optCon, 1);
426     poptSetExecPath(optCon, RPMCONFIGDIR, 1);
427
428     /* Process all options, whine if unknown. */
429     while ((rc = poptGetNextOpt(optCon)) > 0) {
430         optArg = poptGetOptArg(optCon);
431         switch (rc) {
432         default:
433 /*@-nullpass@*/
434             fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
435                 __progname, rc);
436 /*@=nullpass@*/
437             exit(EXIT_FAILURE);
438
439             /*@notreached@*/ /*@switchbreak@*/ break;
440         }
441     }
442
443     if (rc < -1) {
444 /*@-nullpass@*/
445         fprintf(stderr, "%s: %s: %s\n", __progname,
446                 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
447                 poptStrerror(rc));
448 /*@=nullpass@*/
449         exit(EXIT_FAILURE);
450     }
451
452     /* Read rpm configuration (if not already read). */
453     rpmcliConfigured();
454
455     if (_debug) {
456         rpmIncreaseVerbosity();
457         rpmIncreaseVerbosity();
458     }
459
460     return optCon;
461 }
462 /*@=globstate@*/