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