Add options to populate transaction set while iterating.
[platform/upstream/rpm.git] / lib / poptQV.c
1 /** \ingroup rpmcli
2  * \file lib/poptQV.c
3  *  Popt tables for query/verify modes.
4  */
5
6 #include "system.h"
7
8 #include <rpmcli.h>
9 #include <rpmbuild.h>
10 #include <rpmgi.h>      /* XXX for giFlags */
11
12 #include "debug.h"
13
14 /*@unchecked@*/
15 struct rpmQVKArguments_s rpmQVKArgs;
16
17 /*@unchecked@*/
18 int specedit = 0;
19
20 #define POPT_QUERYFORMAT        -1000
21 #define POPT_WHATREQUIRES       -1001
22 #define POPT_WHATPROVIDES       -1002
23 #define POPT_QUERYBYNUMBER      -1003
24 #define POPT_TRIGGEREDBY        -1004
25 #define POPT_DUMP               -1005
26 #define POPT_SPECFILE           -1006
27 #define POPT_QUERYBYPKGID       -1007
28 #define POPT_QUERYBYHDRID       -1008
29 #define POPT_QUERYBYFILEID      -1009
30 #define POPT_QUERYBYTID         -1010
31 #define POPT_HDLIST             -1011
32 #define POPT_FTSWALK            -1012
33
34 /* ========== Query/Verify/Signature source args */
35 static void rpmQVSourceArgCallback( /*@unused@*/ poptContext con,
36                 /*@unused@*/ enum poptCallbackReason reason,
37                 const struct poptOption * opt, /*@unused@*/ const char * arg, 
38                 /*@unused@*/ const void * data)
39         /*@globals rpmQVKArgs @*/
40         /*@modifies rpmQVKArgs @*/
41 {
42     QVA_t qva = &rpmQVKArgs;
43
44     switch (opt->val) {
45     case 'q':   /* from --query, -q */
46     case 'Q':   /* from --querytags (handled by poptALL) */
47     case 'V':   /* from --verify, -V */
48     case 'A':   /* from --addsign */
49     case 'I':   /* from --import */
50     case 'K':   /* from --checksig, -K */
51     case 'R':   /* from --resign */
52         if (qva->qva_mode == '\0' || strchr("qQ ", qva->qva_mode)) {
53             qva->qva_mode = opt->val;
54             qva->qva_char = ' ';
55         }
56         break;
57     case 'a': qva->qva_source |= RPMQV_ALL; qva->qva_sourceCount++; break;
58     case 'f': qva->qva_source |= RPMQV_PATH; qva->qva_sourceCount++; break;
59     case 'g': qva->qva_source |= RPMQV_GROUP; qva->qva_sourceCount++; break;
60     case 'p': qva->qva_source |= RPMQV_RPM; qva->qva_sourceCount++; break;
61     case POPT_WHATPROVIDES: qva->qva_source |= RPMQV_WHATPROVIDES; 
62                                 qva->qva_sourceCount++; break;
63     case POPT_WHATREQUIRES: qva->qva_source |= RPMQV_WHATREQUIRES; 
64                                 qva->qva_sourceCount++; break;
65     case POPT_TRIGGEREDBY: qva->qva_source |= RPMQV_TRIGGEREDBY;
66                                 qva->qva_sourceCount++; break;
67     case POPT_QUERYBYPKGID: qva->qva_source |= RPMQV_PKGID;
68                                 qva->qva_sourceCount++; break;
69     case POPT_QUERYBYHDRID: qva->qva_source |= RPMQV_HDRID;
70                                 qva->qva_sourceCount++; break;
71     case POPT_QUERYBYFILEID: qva->qva_source |= RPMQV_FILEID;
72                                 qva->qva_sourceCount++; break;
73     case POPT_QUERYBYTID: qva->qva_source |= RPMQV_TID;
74                                 qva->qva_sourceCount++; break;
75     case POPT_HDLIST: qva->qva_source |= RPMQV_HDLIST;
76                                 qva->qva_sourceCount++; break;
77     case POPT_FTSWALK:qva->qva_source |= RPMQV_FTSWALK;
78                                 qva->qva_sourceCount++; break;
79
80 /* XXX SPECFILE is not verify sources */
81     case POPT_SPECFILE:
82         qva->qva_source |= RPMQV_SPECFILE;
83         qva->qva_sourceCount++;
84         break;
85     case POPT_QUERYBYNUMBER:
86         qva->qva_source |= RPMQV_DBOFFSET; 
87         qva->qva_sourceCount++;
88         break;
89     }
90 }
91
92 /**
93  * Common query/verify mode options.
94  */
95 /*@unchecked@*/
96 struct poptOption rpmQVSourcePoptTable[] = {
97 /*@-type@*/ /* FIX: cast? */
98  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA, 
99         rpmQVSourceArgCallback, 0, NULL, NULL },
100 /*@=type@*/
101  { "all", 'a', 0, 0, 'a',
102         N_("query/verify all packages"), NULL },
103  { "checksig", 'K', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'K',
104         N_("rpm checksig mode"), NULL },
105  { "file", 'f', 0, 0, 'f',
106         N_("query/verify package(s) owning file"), "FILE" },
107  { "group", 'g', 0, 0, 'g',
108         N_("query/verify package(s) in group"), "GROUP" },
109  { "package", 'p', 0, 0, 'p',
110         N_("query/verify a package file"), NULL },
111
112  { "ftswalk", 'W', 0, 0, POPT_FTSWALK,
113         N_("query/verify package(s) from TOP file tree walk"), "TOP" },
114  { "hdlist", 'H', POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_HDLIST,
115         N_("query/verify package(s) from system HDLIST"), "HDLIST" },
116
117  { "pkgid", '\0', 0, 0, POPT_QUERYBYPKGID,
118         N_("query/verify package(s) with package identifier"), "MD5" },
119  { "hdrid", '\0', 0, 0, POPT_QUERYBYHDRID,
120         N_("query/verify package(s) with header identifier"), "SHA1" },
121  { "fileid", '\0', 0, 0, POPT_QUERYBYFILEID,
122         N_("query/verify package(s) with file identifier"), "MD5" },
123
124  { "query", 'q', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'q',
125         N_("rpm query mode"), NULL },
126  { "querybynumber", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_QUERYBYNUMBER,
127         N_("query/verify a header instance"), "HDRNUM" },
128  { "specfile", '\0', 0, 0, POPT_SPECFILE,
129         N_("query a spec file"), N_("<spec>") },
130  { "tid", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_QUERYBYTID,
131         N_("query/verify package(s) from install transaction"), "TID" },
132  { "triggeredby", '\0', 0, 0, POPT_TRIGGEREDBY, 
133         N_("query the package(s) triggered by the package"), "PACKAGE" },
134  { "verify", 'V', POPT_ARGFLAG_DOC_HIDDEN, NULL, 'V',
135         N_("rpm verify mode"), NULL },
136  { "whatrequires", '\0', 0, 0, POPT_WHATREQUIRES, 
137         N_("query/verify the package(s) which require a dependency"), "CAPABILITY" },
138  { "whatprovides", '\0', 0, 0, POPT_WHATPROVIDES, 
139         N_("query/verify the package(s) which provide a dependency"), "CAPABILITY" },
140
141  { "transaction", 'T', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &giFlags, (RPMGI_TSADD|RPMGI_TSORDER),
142         N_("create transaction set"), NULL},
143  { "noorder", '\0', POPT_BIT_CLR|POPT_ARGFLAG_DOC_HIDDEN, &giFlags, RPMGI_TSORDER,
144         N_("do not order transaction set"), NULL},
145  { "noglob", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &giFlags, RPMGI_NOGLOB,
146         N_("do not glob arguments"), NULL},
147  { "nomanifest", '\0', POPT_BIT_SET, &giFlags, RPMGI_NOMANIFEST,
148         N_("do not process non-package files as manifests"), NULL},
149  { "noheader", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN, &giFlags, RPMGI_NOHEADER,
150         N_("do not read headers"), NULL},
151
152
153    POPT_TABLEEND
154 };
155
156 /* ========== Query specific popt args */
157
158 static void queryArgCallback(poptContext con,
159                 /*@unused@*/enum poptCallbackReason reason,
160                 const struct poptOption * opt, const char * arg, 
161                 /*@unused@*/ const void * data)
162         /*@globals rpmQVKArgs @*/
163         /*@modifies con, rpmQVKArgs @*/
164 {
165     QVA_t qva = &rpmQVKArgs;
166
167     switch (opt->val) {
168     case 'c': qva->qva_flags |= QUERY_FOR_CONFIG | QUERY_FOR_LIST; break;
169     case 'd': qva->qva_flags |= QUERY_FOR_DOCS | QUERY_FOR_LIST; break;
170     case 'l': qva->qva_flags |= QUERY_FOR_LIST; break;
171     case 's': qva->qva_flags |= QUERY_FOR_STATE | QUERY_FOR_LIST;
172         break;
173     case POPT_DUMP: qva->qva_flags |= QUERY_FOR_DUMPFILES | QUERY_FOR_LIST;
174         break;
175
176     case POPT_QUERYFORMAT:
177         if (arg) {
178             char * qf = (char *)qva->qva_queryFormat;
179             /*@-branchstate@*/
180             if (qf) {
181                 int len = strlen(qf) + strlen(arg) + 1;
182                 qf = xrealloc(qf, len);
183 /*@-boundswrite@*/
184                 strcat(qf, arg);
185 /*@=boundswrite@*/
186             } else {
187                 qf = xmalloc(strlen(arg) + 1);
188                 strcpy(qf, arg);
189             }
190             /*@=branchstate@*/
191             qva->qva_queryFormat = qf;
192         }
193         break;
194
195     case 'i':
196         if (qva->qva_mode == 'q') {
197             /*@-nullassign -readonlytrans@*/
198             const char * infoCommand[] = { "--info", NULL };
199             /*@=nullassign =readonlytrans@*/
200             (void) poptStuffArgs(con, infoCommand);
201         }
202         break;
203
204     case RPMCLI_POPT_NODIGEST:
205         qva->qva_flags |= VERIFY_DIGEST;
206         break;
207
208     case RPMCLI_POPT_NOSIGNATURE:
209         qva->qva_flags |= VERIFY_SIGNATURE;
210         break;
211
212     case RPMCLI_POPT_NOHDRCHK:
213         qva->qva_flags |= VERIFY_HDRCHK;
214         break;
215
216     case RPMCLI_POPT_NODEPS:
217         qva->qva_flags |= VERIFY_DEPS;
218         break;
219
220     case RPMCLI_POPT_NOMD5:
221         qva->qva_flags |= VERIFY_MD5;
222         break;
223
224     case RPMCLI_POPT_NOCONTEXTS:
225         qva->qva_flags |= VERIFY_CONTEXTS;
226         break;
227
228 #ifdef  NOTYET
229     case RPMCLI_POPT_FORCE:
230         ia->probFilter |=
231                 ( RPMPROB_FILTER_REPLACEPKG
232                 | RPMPROB_FILTER_REPLACEOLDFILES
233                 | RPMPROB_FILTER_REPLACENEWFILES
234                 | RPMPROB_FILTER_OLDPACKAGE );
235         break;
236 #endif
237
238     case RPMCLI_POPT_NOSCRIPTS:
239         qva->qva_flags |= VERIFY_SCRIPT;
240         break;
241
242     }
243 }
244
245 /**
246  * Query mode options.
247  */
248 /*@unchecked@*/
249 struct poptOption rpmQueryPoptTable[] = {
250 /*@-type@*/ /* FIX: cast? */
251  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE, 
252         queryArgCallback, 0, NULL, NULL },
253 /*@=type@*/
254  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
255         NULL, NULL },
256  { "configfiles", 'c', 0, 0, 'c',
257         N_("list all configuration files"), NULL },
258  { "docfiles", 'd', 0, 0, 'd',
259         N_("list all documentation files"), NULL },
260  { "dump", '\0', 0, 0, POPT_DUMP,
261         N_("dump basic file information"), NULL },
262  { NULL, 'i', POPT_ARGFLAG_DOC_HIDDEN, 0, 'i',
263         NULL, NULL },
264  { "list", 'l', 0, 0, 'l',
265         N_("list files in package"), NULL },
266
267  /* Duplicate file attr flags from packages into command line options. */
268  { "noghost", '\0', POPT_BIT_CLR|POPT_ARGFLAG_DOC_HIDDEN,
269         &rpmQVKArgs.qva_fflags, RPMFILE_GHOST,
270         N_("skip %%ghost files"), NULL },
271 #ifdef  NOTEVER         /* XXX there's hardly a need for these */
272  { "nolicense", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
273         &rpmQVKArgs.qva_fflags, RPMFILE_LICENSE,
274         N_("skip %%license files"), NULL },
275  { "noreadme", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
276         &rpmQVKArgs.qva_fflags, RPMFILE_README,
277         N_("skip %%readme files"), NULL },
278 #endif
279
280  { "qf", '\0', POPT_ARG_STRING | POPT_ARGFLAG_DOC_HIDDEN, 0, 
281         POPT_QUERYFORMAT, NULL, NULL },
282  { "queryformat", '\0', POPT_ARG_STRING, 0, POPT_QUERYFORMAT,
283         N_("use the following query format"), "QUERYFORMAT" },
284  { "specedit", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &specedit, -1,
285         N_("substitute i18n sections into spec file"), NULL },
286  { "state", 's', 0, 0, 's',
287         N_("display the states of the listed files"), NULL },
288    POPT_TABLEEND
289 };
290
291 /**
292  * Verify mode options.
293  */
294 struct poptOption rpmVerifyPoptTable[] = {
295 /*@-type@*/ /* FIX: cast? */
296  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE, 
297         queryArgCallback, 0, NULL, NULL },
298 /*@=type@*/
299  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
300         NULL, NULL },
301
302  /* Duplicate file verify flags from packages into command line options. */
303 /** @todo Add --nomd5 alias to rpmpopt, eliminate. */
304 #ifdef  DYING
305  { "nomd5", '\0', POPT_BIT_SET, &rpmQVKArgs.qva_flags, VERIFY_MD5,
306         N_("don't verify MD5 digest of files"), NULL },
307 #else
308  { "nomd5", '\0', 0, NULL, RPMCLI_POPT_NOMD5,
309         N_("don't verify MD5 digest of files"), NULL },
310 #endif
311  { "nosize", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
312         &rpmQVKArgs.qva_flags, VERIFY_SIZE,
313         N_("don't verify size of files"), NULL },
314  { "nolinkto", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
315         &rpmQVKArgs.qva_flags, VERIFY_LINKTO,
316         N_("don't verify symlink path of files"), NULL },
317  { "nouser", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
318         &rpmQVKArgs.qva_flags, VERIFY_USER,
319         N_("don't verify owner of files"), NULL },
320  { "nogroup", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
321         &rpmQVKArgs.qva_flags, VERIFY_GROUP,
322         N_("don't verify group of files"), NULL },
323  { "nomtime", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
324         &rpmQVKArgs.qva_flags, VERIFY_MTIME,
325         N_("don't verify modification time of files"), NULL },
326  { "nomode", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
327         &rpmQVKArgs.qva_flags, VERIFY_MODE,
328         N_("don't verify mode of files"), NULL },
329  { "nordev", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
330         &rpmQVKArgs.qva_flags, VERIFY_RDEV,
331         N_("don't verify mode of files"), NULL },
332
333  { "nocontexts", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOCONTEXTS,
334         N_("don't verify file security contexts"), NULL },
335  { "nofiles", '\0', POPT_BIT_SET, &rpmQVKArgs.qva_flags, VERIFY_FILES,
336         N_("don't verify files in package"), NULL},
337 #ifdef  DYING
338  { "nodeps", '\0', POPT_BIT_SET, &rpmQVKArgs.qva_flags, VERIFY_DEPS,
339         N_("don't verify package dependencies"), NULL },
340 #else
341  { "nodeps", '\0', 0, NULL, RPMCLI_POPT_NODEPS,
342         N_("don't verify package dependencies"), NULL },
343 #endif
344
345 #ifdef  DYING
346  { "noscript", '\0', POPT_BIT_SET,&rpmQVKArgs.qva_flags, VERIFY_SCRIPT,
347         N_("don't execute verify script(s)"), NULL },
348  /* XXX legacy had a trailing s on --noscript */
349  { "noscripts", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
350         &rpmQVKArgs.qva_flags, VERIFY_SCRIPT,
351         N_("don't execute verify script(s)"), NULL },
352 #else
353  { "noscript", '\0', 0, NULL, RPMCLI_POPT_NOSCRIPTS,
354         N_("don't execute verify script(s)"), NULL },
355  /* XXX legacy had a trailing s on --noscript */
356  { "noscripts", '\0', POPT_ARGFLAG_DOC_HIDDEN, NULL, RPMCLI_POPT_NOSCRIPTS,
357         N_("don't execute verify script(s)"), NULL },
358 #endif
359
360 #ifdef  DYING
361  { "nodigest", '\0', POPT_BIT_SET, &rpmQVKArgs.qva_flags, VERIFY_DIGEST,
362         N_("don't verify package digest(s)"), NULL },
363  { "nohdrchk", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
364         &rpmQVKArgs.qva_flags, VERIFY_HDRCHK,
365         N_("don't verify database header(s) when retrieved"), NULL },
366  { "nosignature", '\0', POPT_BIT_SET,
367         &rpmQVKArgs.qva_flags, VERIFY_SIGNATURE,
368         N_("don't verify package signature(s)"), NULL },
369 #else
370  { "nodigest", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_NODIGEST,
371         N_("don't verify package digest(s)"), NULL },
372  { "nohdrchk", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_NOHDRCHK,
373         N_("don't verify database header(s) when retrieved"), NULL },
374  { "nosignature", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_NOSIGNATURE,
375         N_("don't verify package signature(s)"), NULL },
376 #endif
377
378 /** @todo Add --nogpg/--nopgp aliases to rpmpopt, eliminate. */
379  { "nogpg", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
380         &rpmQVKArgs.qva_flags, VERIFY_SIGNATURE,
381         N_("don't verify GPG V3 DSA signature(s)"), NULL },
382  { "nopgp", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
383         &rpmQVKArgs.qva_flags, VERIFY_SIGNATURE,
384         N_("don't verify PGP V3 RSA/MD5 signature(s)"), NULL },
385
386     POPT_TABLEEND
387 };
388
389 /**
390  * Signature mode options.
391  */
392 /*@unchecked@*/
393 struct poptOption rpmSignPoptTable[] = {
394 /*@-type@*/ /* FIX: cast? */
395  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
396         rpmQVSourceArgCallback, 0, NULL, NULL },
397 /*@=type@*/
398  { "addsign", '\0', 0, NULL, 'A',
399         N_("sign package(s) (identical to --resign)"), NULL },
400  { "checksig", 'K', 0, NULL, 'K',
401         N_("verify package signature(s)"), NULL },
402  { "import", '\0', 0, NULL, 'I',
403         N_("import an armored public key"), NULL },
404  { "resign", '\0', 0, NULL, 'R',
405         N_("sign package(s) (identical to --addsign)"), NULL },
406  { "sign", '\0', POPT_ARGFLAG_DOC_HIDDEN, &rpmQVKArgs.sign, 0,
407         N_("generate signature"), NULL },
408
409  { "nodigest", '\0', POPT_BIT_SET, &rpmQVKArgs.qva_flags, VERIFY_DIGEST,
410         N_("don't verify package digest(s)"), NULL },
411  { "nohdrchk", '\0', POPT_BIT_SET|POPT_ARGFLAG_DOC_HIDDEN,
412         &rpmQVKArgs.qva_flags, VERIFY_HDRCHK,
413         N_("don't verify database header(s) when retrieved"), NULL },
414  { "nosignature", '\0', POPT_BIT_SET, &rpmQVKArgs.qva_flags, VERIFY_SIGNATURE,
415         N_("don't verify package signature(s)"), NULL },
416
417    POPT_TABLEEND
418 };