1 /** \ingroup rpmcli
2 * \file lib/poptALL.c
3 * Popt tables for all rpm modes.
4 */
5
6 #include "system.h"
7
8 #include <rpm/rpmcli.h>
9 #include <rpm/rpmlib.h> /* rpmEVR, rpmReadConfigFiles etc */
10 #include <rpm/rpmlog.h>
11 #include <rpm/rpmstring.h>
12 #include <rpm/rpmfileutil.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 #define POPT_DBPATH -995
21 #define POPT_UNDEFINE -994
22 #define POPT_PIPE -993
23 #define POPT_LOAD -992
24
25 static int _debug = 0;
26
27 extern int _rpm_nouserns;
28
29 extern int _fsm_debug;
30
31 extern int _print_pkts;
32
33 extern int _psm_debug;
34
35 /* XXX avoid -lrpmbuild linkage. */
36 int _rpmfc_debug;
37
38 extern int _rpmts_stats;
39
40 const char * rpmcliPipeOutput = NULL;
41
42 const char * rpmcliRcfile = NULL;
43
44 const char * rpmcliRootDir = "/";
45
46 rpmQueryFlags rpmcliQueryFlags;
47
48 rpmVSFlags rpmcliVSFlags;
49
50 int rpmcliVfyLevelMask;
51
52 extern int _rpmio_debug;
53
54 static int rpmcliInitialized = -1;
55
56 /**
57 * Display rpm version.
58 */
printVersion(FILE * fp)59 static void printVersion(FILE * fp)
60 {
61 fprintf(fp, _("RPM version %s\n"), rpmEVR);
62 }
63
64 /**
65 * Make sure that config files have been read.
66 * @warning Options like --rcfile and --verbose must precede callers option.
67 */
rpmcliConfigured(void)68 void rpmcliConfigured(void)
69 {
70
71 if (rpmcliInitialized < 0)
72 rpmcliInitialized = rpmReadConfigFiles(rpmcliRcfile, NULL);
73 if (rpmcliInitialized)
74 exit(EXIT_FAILURE);
75 }
76
cliDefine(const char * arg,int predefine)77 static int cliDefine(const char *arg, int predefine)
78 {
79 int rc;
80 char *s, *t;
81 /* XXX Convert '-' in macro name to underscore, skip leading %. */
82 s = t = xstrdup(arg);
83 while (*t && !risspace(*t) && (*t != '(')) {
84 if (*t == '-') *t = '_';
85 t++;
86 }
87 t = s;
88 if (*t == '%') t++;
89
90 rc = rpmDefineMacro(NULL, t, RMIL_CMDLINE);
91 if (!predefine && rc == 0)
92 (void) rpmDefineMacro(rpmCLIMacroContext, t, RMIL_CMDLINE);
93
94 free(s);
95 return rc;
96 }
97
98 /**
99 */
rpmcliAllArgCallback(poptContext con,enum poptCallbackReason reason,const struct poptOption * opt,const char * arg,const void * data)100 static void rpmcliAllArgCallback( poptContext con,
101 enum poptCallbackReason reason,
102 const struct poptOption * opt, const char * arg,
103 const void * data)
104 {
105
106 /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
107 if (opt->arg == NULL)
108 switch (opt->val) {
109 case 'q':
110 rpmSetVerbosity(RPMLOG_WARNING);
111 break;
112 case 'v':
113 rpmIncreaseVerbosity();
114 break;
115 case POPT_PREDEFINE:
116 if (cliDefine(arg, 1))
117 exit(EXIT_FAILURE);
118 break;
119 case 'D':
120 rpmcliConfigured();
121 if (cliDefine(arg, 0))
122 exit(EXIT_FAILURE);
123 break;
124 case POPT_UNDEFINE:
125 rpmcliConfigured();
126 if (*arg == '%')
127 arg++;
128 rpmPopMacro(NULL, arg);
129 break;
130 case 'E':
131 rpmcliConfigured();
132 { char *val = NULL;
133 if (rpmExpandMacros(NULL, arg, &val, 0) < 0)
134 exit(EXIT_FAILURE);
135 fprintf(stdout, "%s\n", val);
136 free(val);
137 }
138 break;
139 case POPT_LOAD:
140 rpmcliConfigured();
141 if (rpmLoadMacroFile(NULL, arg)) {
142 fprintf(stderr, _("failed to load macro file %s\n"), arg);
143 exit(EXIT_FAILURE);
144 }
145 break;
146 case POPT_DBPATH:
147 rpmcliConfigured();
148 if (arg && arg[0] != '/') {
149 fprintf(stderr, _("arguments to --dbpath must begin with '/'\n"));
150 exit(EXIT_FAILURE);
151 }
152 rpmPushMacro(NULL, "_dbpath", NULL, arg, RMIL_CMDLINE);
153 break;
154 case POPT_SHOWVERSION:
155 printVersion(stdout);
156 exit(EXIT_SUCCESS);
157 break;
158 case POPT_SHOWRC:
159 rpmcliConfigured();
160 (void) rpmShowRC(stdout);
161 exit(EXIT_SUCCESS);
162 break;
163 case POPT_QUERYTAGS:
164 rpmDisplayQueryTags(stdout);
165 exit(EXIT_SUCCESS);
166 break;
167 case POPT_PIPE:
168 if (rpmcliPipeOutput) {
169 fprintf(stderr,
170 _("%s: error: more than one --pipe specified "
171 "(incompatible popt aliases?)\n"), xgetprogname());
172 exit(EXIT_FAILURE);
173 }
174 rpmcliPipeOutput = xstrdup(arg);
175 break;
176 case RPMCLI_POPT_NODIGEST:
177 rpmcliVSFlags |= RPMVSF_MASK_NODIGESTS;
178 rpmcliVfyLevelMask |= RPMSIG_DIGEST_TYPE;
179 break;
180 case RPMCLI_POPT_NOSIGNATURE:
181 rpmcliVSFlags |= RPMVSF_MASK_NOSIGNATURES;
182 rpmcliVfyLevelMask |= RPMSIG_SIGNATURE_TYPE;
183 break;
184 case RPMCLI_POPT_NOHDRCHK:
185 rpmcliVSFlags |= RPMVSF_NOHDRCHK;
186 break;
187
188 case RPMCLI_POPT_TARGETPLATFORM:
189 rpmcliInitialized = rpmReadConfigFiles(rpmcliRcfile, arg);
190 break;
191 }
192 }
193
194 struct poptOption rpmcliAllPoptTable[] = {
195 /* FIX: cast? */
196 { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
197 rpmcliAllArgCallback, 0, NULL, NULL },
198
199 { "debug", 'd', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_debug, -1,
200 NULL, NULL },
201
202 { "predefine", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_PREDEFINE,
203 N_("predefine MACRO with value EXPR"),
204 N_("'MACRO EXPR'") },
205 { "define", 'D', POPT_ARG_STRING, 0, 'D',
206 N_("define MACRO with value EXPR"),
207 N_("'MACRO EXPR'") },
208 { "undefine", '\0', POPT_ARG_STRING, 0, POPT_UNDEFINE,
209 N_("undefine MACRO"),
210 N_("MACRO") },
211 { "eval", 'E', POPT_ARG_STRING, 0, 'E',
212 N_("print macro expansion of EXPR"),
213 N_("'EXPR'") },
214 { "target", '\0', POPT_ARG_STRING, NULL, RPMCLI_POPT_TARGETPLATFORM,
215 N_("Specify target platform"), N_("CPU-VENDOR-OS") },
216 { "macros", '\0', POPT_ARG_STRING, ¯ofiles, 0,
217 N_("read <FILE:...> instead of default file(s)"),
218 N_("<FILE:...>") },
219 { "load", '\0', POPT_ARG_STRING, 0, POPT_LOAD,
220 N_("load a single macro file"),
221 N_("<FILE>") },
222
223 /* XXX this is a bit out of place here but kinda unavoidable... */
224 { "noplugins", '\0', POPT_BIT_SET,
225 &rpmIArgs.transFlags, RPMTRANS_FLAG_NOPLUGINS,
226 N_("don't enable any plugins"), NULL },
227
228 { "nodigest", '\0', 0, 0, RPMCLI_POPT_NODIGEST,
229 N_("don't verify package digest(s)"), NULL },
230 { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_NOHDRCHK,
231 N_("don't verify database header(s) when retrieved"), NULL },
232 { "nosignature", '\0', 0, 0, RPMCLI_POPT_NOSIGNATURE,
233 N_("don't verify package signature(s)"), NULL },
234
235 { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_PIPE,
236 N_("send stdout to CMD"),
237 N_("CMD") },
238 { "rcfile", '\0', POPT_ARG_STRING, &rpmcliRcfile, 0,
239 N_("read <FILE:...> instead of default file(s)"),
240 N_("<FILE:...>") },
241 { "root", 'r', POPT_ARG_STRING|POPT_ARGFLAG_SHOW_DEFAULT, &rpmcliRootDir, 0,
242 N_("use ROOT as top level directory"),
243 N_("ROOT") },
244 { "dbpath", '\0', POPT_ARG_STRING, 0, POPT_DBPATH,
245 N_("use database in DIRECTORY"),
246 N_("DIRECTORY") },
247
248 { "querytags", '\0', 0, 0, POPT_QUERYTAGS,
249 N_("display known query tags"), NULL },
250 { "showrc", '\0', 0, NULL, POPT_SHOWRC,
251 N_("display final rpmrc and macro configuration"), NULL },
252 { "quiet", '\0', 0, NULL, 'q',
253 N_("provide less detailed output"), NULL},
254 { "verbose", 'v', 0, NULL, 'v',
255 N_("provide more detailed output"), NULL},
256 { "version", '\0', 0, NULL, POPT_SHOWVERSION,
257 N_("print the version of rpm being used"), NULL },
258
259 { "fsmdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_fsm_debug, -1,
260 N_("debug payload file state machine"), NULL},
261 { "prtpkts", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_print_pkts, -1,
262 NULL, NULL},
263 { "rpmfcdebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmfc_debug, -1,
264 NULL, NULL},
265 { "rpmiodebug", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmio_debug, -1,
266 N_("debug rpmio I/O"), NULL},
267 { "nouserns", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpm_nouserns, -1,
268 N_("disable user namespace support"), NULL},
269 { "stats", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &_rpmts_stats, -1,
270 NULL, NULL},
271
272 POPT_TABLEEND
273 };
274
275 poptContext
rpmcliFini(poptContext optCon)276 rpmcliFini(poptContext optCon)
277 {
278 poptFreeContext(optCon);
279 rpmFreeMacros(NULL);
280 rpmFreeMacros(rpmCLIMacroContext);
281 rpmFreeRpmrc();
282 rpmlogClose();
283 rpmcliInitialized = -1;
284
285 return NULL;
286 }
287
288 poptContext
rpmcliInit(int argc,char * const argv[],struct poptOption * optionsTable)289 rpmcliInit(int argc, char *const argv[], struct poptOption * optionsTable)
290 {
291 poptContext optCon;
292 int rc;
293 const char *ctx, *execPath;
294
295 #if defined(ENABLE_NLS)
296 (void) setlocale(LC_ALL, "" );
297
298 (void) bindtextdomain(PACKAGE, LOCALEDIR);
299 (void) textdomain(PACKAGE);
300 #endif
301
302 rpmSetVerbosity(RPMLOG_NOTICE);
303
304 if (optionsTable == NULL) {
305 /* Read rpm configuration (if not already read). */
306 rpmcliConfigured();
307 return NULL;
308 }
309
310 /* XXX hack to get popt working from build tree wrt lt-foo names */
311 ctx = rstreqn(xgetprogname(), "lt-", 3) ? xgetprogname() + 3 : xgetprogname();
312
313 optCon = poptGetContext(ctx, argc, (const char **)argv, optionsTable, 0);
314 {
315 char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL);
316 (void) poptReadConfigFile(optCon, poptfile);
317 free(poptfile);
318 }
319 (void) poptReadDefaultConfig(optCon, 1);
320
321 if ((execPath = getenv("RPM_POPTEXEC_PATH")) == NULL)
322 execPath = LIBRPMALIAS_EXECPATH;
323 poptSetExecPath(optCon, execPath, 1);
324
325 /* Process all options, whine if unknown. */
326 while ((rc = poptGetNextOpt(optCon)) > 0) {
327 fprintf(stderr, _("%s: option table misconfigured (%d)\n"),
328 xgetprogname(), rc);
329 exit(EXIT_FAILURE);
330 }
331
332 if (rc < -1) {
333 fprintf(stderr, "%s: %s: %s\n", xgetprogname(),
334 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
335 poptStrerror(rc));
336 exit(EXIT_FAILURE);
337 }
338
339 /* Read rpm configuration (if not already read). */
340 rpmcliConfigured();
341
342 if (_debug) {
343 rpmIncreaseVerbosity();
344 rpmIncreaseVerbosity();
345 }
346
347 return optCon;
348 }
349