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