Add config.sub update to %configure macro
[platform/upstream/rpm.git] / rpmqv.c
1 #include "system.h"
2
3 #include <rpm/rpmcli.h>
4 #include <rpm/rpmlib.h>                 /* RPMSIGTAG, rpmReadPackageFile .. */
5 #include <rpm/rpmlog.h>
6 #include <rpm/rpmps.h>
7 #include <rpm/rpmts.h>
8
9 #include "cliutils.h"
10
11 #include "debug.h"
12
13 #if defined(IAM_RPMQ) || defined(IAM_RPMV)
14 #define IAM_RPMQV
15 #endif
16
17 enum modes {
18
19     MODE_QUERY          = (1 <<  0),
20     MODE_VERIFY         = (1 <<  3),
21 #define MODES_QV (MODE_QUERY | MODE_VERIFY)
22
23     MODE_INSTALL        = (1 <<  1),
24     MODE_ERASE          = (1 <<  2),
25 #define MODES_IE (MODE_INSTALL | MODE_ERASE)
26
27     MODE_UNKNOWN        = 0
28 };
29
30 #define MODES_FOR_NODEPS        (MODES_IE | MODE_VERIFY)
31 #define MODES_FOR_TEST          (MODES_IE)
32
33 static int quiet;
34
35 /* the structure describing the options we take and the defaults */
36 static struct poptOption optionsTable[] = {
37
38 #ifdef  IAM_RPMQV
39  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQVSourcePoptTable, 0,
40         N_("Query/Verify package selection options:"),
41         NULL },
42 #endif
43 #ifdef IAM_RPMQ
44  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmQueryPoptTable, 0,
45         N_("Query options (with -q or --query):"),
46         NULL },
47 #endif
48 #ifdef IAM_RPMV
49  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmVerifyPoptTable, 0,
50         N_("Verify options (with -V or --verify):"),
51         NULL },
52 #endif
53
54 #ifdef  IAM_RPMEIU
55  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmInstallPoptTable, 0,
56         N_("Install/Upgrade/Erase options:"),
57         NULL },
58 #endif  /* IAM_RPMEIU */
59
60  { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
61
62  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
63         N_("Common options for all rpm modes and executables:"),
64         NULL },
65
66    POPT_AUTOALIAS
67    POPT_AUTOHELP
68    POPT_TABLEEND
69 };
70
71 int main(int argc, char *argv[])
72 {
73     rpmts ts = NULL;
74     enum modes bigMode = MODE_UNKNOWN;
75
76 #if defined(IAM_RPMQV)
77     QVA_t qva = &rpmQVKArgs;
78 #endif
79
80 #ifdef  IAM_RPMEIU
81    struct rpmInstallArguments_s * ia = &rpmIArgs;
82 #endif
83
84     poptContext optCon;
85     int ec = 0;
86 #ifdef  IAM_RPMEIU
87     int i;
88 #endif
89
90     xsetprogname(argv[0]); /* Portability call -- see system.h */
91
92     optCon = rpmcliInit(argc, argv, optionsTable);
93
94     /* Set the major mode based on argv[0] */
95 #ifdef  IAM_RPMQV
96     if (rstreq(xgetprogname(), "rpmquery"))     bigMode = MODE_QUERY;
97     if (rstreq(xgetprogname(), "rpmverify")) bigMode = MODE_VERIFY;
98 #endif
99
100 #if defined(IAM_RPMQV)
101     /* Jumpstart option from argv[0] if necessary. */
102     switch (bigMode) {
103     case MODE_QUERY:    qva->qva_mode = 'q';    break;
104     case MODE_VERIFY:   qva->qva_mode = 'V';    break;
105     case MODE_INSTALL:
106     case MODE_ERASE:
107     case MODE_UNKNOWN:
108     default:
109         break;
110     }
111 #endif
112
113 #ifdef  IAM_RPMQV
114   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_QV)) {
115     switch (qva->qva_mode) {
116     case 'q':   bigMode = MODE_QUERY;           break;
117     case 'V':   bigMode = MODE_VERIFY;          break;
118     }
119
120     if (qva->qva_sourceCount) {
121         if (qva->qva_sourceCount > 1)
122             argerror(_("one type of query/verify may be performed at a "
123                         "time"));
124     }
125     if (qva->qva_flags && (bigMode & ~MODES_QV)) 
126         argerror(_("unexpected query flags"));
127
128     if (qva->qva_queryFormat && (bigMode & ~MODES_QV)) 
129         argerror(_("unexpected query format"));
130
131     if (qva->qva_source != RPMQV_PACKAGE && (bigMode & ~MODES_QV)) 
132         argerror(_("unexpected query source"));
133   }
134 #endif  /* IAM_RPMQV */
135
136 #ifdef  IAM_RPMEIU
137   if (bigMode == MODE_UNKNOWN || (bigMode & MODES_IE))
138     {   int iflags = (ia->installInterfaceFlags &
139                         (INSTALL_UPGRADE|INSTALL_FRESHEN|
140                          INSTALL_INSTALL|INSTALL_REINSTALL));
141         int eflags = (ia->installInterfaceFlags & INSTALL_ERASE);
142
143         if (iflags & eflags)
144             argerror(_("only one major mode may be specified"));
145         else if (iflags)
146             bigMode = MODE_INSTALL;
147         else if (eflags)
148             bigMode = MODE_ERASE;
149     }
150 #endif  /* IAM_RPMEIU */
151
152 #if defined(IAM_RPMEIU)
153     if (!( bigMode == MODE_INSTALL ) &&
154 (ia->probFilter & (RPMPROB_FILTER_REPLACEPKG | RPMPROB_FILTER_OLDPACKAGE)))
155         argerror(_("only installation and upgrading may be forced"));
156     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_FORCERELOCATE))
157         argerror(_("files may only be relocated during package installation"));
158
159     if (ia->relocations && ia->prefix)
160         argerror(_("cannot use --prefix with --relocate or --excludepath"));
161
162     if (bigMode != MODE_INSTALL && ia->relocations)
163         argerror(_("--relocate and --excludepath may only be used when installing new packages"));
164
165     if (bigMode != MODE_INSTALL && ia->prefix)
166         argerror(_("--prefix may only be used when installing new packages"));
167
168     if (ia->prefix && ia->prefix[0] != '/') 
169         argerror(_("arguments to --prefix must begin with a /"));
170
171     if (!(bigMode & MODES_IE) && (ia->installInterfaceFlags & INSTALL_HASH))
172         argerror(_("--hash (-h) may only be specified during package "
173                         "installation and erasure"));
174
175     if (!(bigMode & MODES_IE) && (ia->installInterfaceFlags & INSTALL_PERCENT))
176         argerror(_("--percent may only be specified during package "
177                         "installation and erasure"));
178
179     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_REPLACEPKG))
180         argerror(_("--replacepkgs may only be specified during package "
181                         "installation"));
182
183     if (bigMode != MODE_INSTALL && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
184         argerror(_("--excludedocs may only be specified during package "
185                    "installation"));
186
187     if (bigMode != MODE_INSTALL && ia->incldocs)
188         argerror(_("--includedocs may only be specified during package "
189                    "installation"));
190
191     if (ia->incldocs && (ia->transFlags & RPMTRANS_FLAG_NODOCS))
192         argerror(_("only one of --excludedocs and --includedocs may be "
193                  "specified"));
194   
195     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREARCH))
196         argerror(_("--ignorearch may only be specified during package "
197                    "installation"));
198
199     if (bigMode != MODE_INSTALL && (ia->probFilter & RPMPROB_FILTER_IGNOREOS))
200         argerror(_("--ignoreos may only be specified during package "
201                    "installation"));
202
203     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE &&
204         (ia->probFilter & (RPMPROB_FILTER_DISKSPACE|RPMPROB_FILTER_DISKNODES)))
205         argerror(_("--ignoresize may only be specified during package "
206                    "installation"));
207
208     if ((ia->installInterfaceFlags & UNINSTALL_ALLMATCHES) && bigMode != MODE_ERASE)
209         argerror(_("--allmatches may only be specified during package "
210                    "erasure"));
211
212     if ((ia->transFlags & RPMTRANS_FLAG_ALLFILES) && bigMode != MODE_INSTALL)
213         argerror(_("--allfiles may only be specified during package "
214                    "installation"));
215
216     if ((ia->transFlags & RPMTRANS_FLAG_JUSTDB) &&
217         bigMode != MODE_INSTALL && bigMode != MODE_ERASE)
218         argerror(_("--justdb may only be specified during package "
219                    "installation and erasure"));
220
221     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
222         (ia->transFlags & (RPMTRANS_FLAG_NOSCRIPTS | _noTransScripts | _noTransTriggers)))
223         argerror(_("script disabling options may only be specified during "
224                    "package installation and erasure"));
225
226     if (bigMode != MODE_INSTALL && bigMode != MODE_ERASE && bigMode != MODE_VERIFY &&
227         (ia->transFlags & (RPMTRANS_FLAG_NOTRIGGERS | _noTransTriggers)))
228         argerror(_("trigger disabling options may only be specified during "
229                    "package installation and erasure"));
230
231     if (ia->noDeps & (bigMode & ~MODES_FOR_NODEPS))
232         argerror(_("--nodeps may only be specified during package "
233                    "installation, erasure, and verification"));
234
235     if ((ia->transFlags & RPMTRANS_FLAG_TEST) && (bigMode & ~MODES_FOR_TEST))
236         argerror(_("--test may only be specified during package installation "
237                  "and erasure"));
238 #endif  /* IAM_RPMEIU */
239
240     if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
241         argerror(_("arguments to --root (-r) must begin with a /"));
242     }
243
244     if (quiet)
245         rpmSetVerbosity(RPMLOG_WARNING);
246
247     if (rpmcliPipeOutput && initPipe())
248         exit(EXIT_FAILURE);
249         
250     ts = rpmtsCreate();
251     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
252     switch (bigMode) {
253 #ifdef  IAM_RPMEIU
254     case MODE_ERASE:
255         if (ia->noDeps) ia->installInterfaceFlags |= UNINSTALL_NODEPS;
256
257         if (!poptPeekArg(optCon)) {
258             argerror(_("no packages given for erase"));
259         } else {
260             ec += rpmErase(ts, ia, (ARGV_const_t) poptGetArgs(optCon));
261         }
262         break;
263
264     case MODE_INSTALL:
265
266         /* RPMTRANS_FLAG_KEEPOBSOLETE */
267
268         if (!ia->incldocs) {
269             if (ia->transFlags & RPMTRANS_FLAG_NODOCS) {
270                 ;
271             } else if (rpmExpandNumeric("%{_excludedocs}"))
272                 ia->transFlags |= RPMTRANS_FLAG_NODOCS;
273         }
274
275         if (ia->noDeps) ia->installInterfaceFlags |= INSTALL_NODEPS;
276
277         /* we've already ensured !(!ia->prefix && !ia->relocations) */
278         if (ia->prefix) {
279             ia->relocations = xmalloc(2 * sizeof(*ia->relocations));
280             ia->relocations[0].oldPath = NULL;   /* special case magic */
281             ia->relocations[0].newPath = ia->prefix;
282             ia->relocations[1].oldPath = NULL;
283             ia->relocations[1].newPath = NULL;
284         } else if (ia->relocations) {
285             ia->relocations = xrealloc(ia->relocations, 
286                         sizeof(*ia->relocations) * (ia->numRelocations + 1));
287             ia->relocations[ia->numRelocations].oldPath = NULL;
288             ia->relocations[ia->numRelocations].newPath = NULL;
289         }
290
291         if (!poptPeekArg(optCon)) {
292             argerror(_("no packages given for install"));
293         } else {
294             /* FIX: ia->relocations[0].newPath undefined */
295             ec += rpmInstall(ts, ia, (ARGV_t) poptGetArgs(optCon));
296         }
297         break;
298
299 #endif  /* IAM_RPMEIU */
300
301 #ifdef  IAM_RPMQV
302     case MODE_QUERY:
303         if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
304             argerror(_("no arguments given for query"));
305
306         ec = rpmcliQuery(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
307         break;
308
309     case MODE_VERIFY:
310     {   rpmVerifyFlags verifyFlags = VERIFY_ALL;
311
312         verifyFlags &= ~qva->qva_flags;
313         qva->qva_flags = (rpmQueryFlags) verifyFlags;
314
315         rpmtsSetFlags(ts, rpmtsFlags(ts) | (ia->transFlags & RPMTRANS_FLAG_NOPLUGINS));
316
317         if (!poptPeekArg(optCon) && !(qva->qva_source == RPMQV_ALL))
318             argerror(_("no arguments given for verify"));
319         ec = rpmcliVerify(ts, qva, (ARGV_const_t) poptGetArgs(optCon));
320     }   break;
321 #endif  /* IAM_RPMQV */
322
323 #if !defined(IAM_RPMQV)
324     case MODE_QUERY:
325     case MODE_VERIFY:
326 #endif
327 #if !defined(IAM_RPMEIU)
328     case MODE_INSTALL:
329     case MODE_ERASE:
330 #endif
331     case MODE_UNKNOWN:
332         if (poptPeekArg(optCon) != NULL || argc <= 1) {
333             printUsage(optCon, stderr, 0);
334             ec = argc;
335         }
336         break;
337     }
338
339     rpmtsFree(ts);
340     if (finishPipe())
341         ec = EXIT_FAILURE;
342
343 #ifdef  IAM_RPMQV
344     free(qva->qva_queryFormat);
345 #endif
346
347 #ifdef  IAM_RPMEIU
348     if (ia->relocations != NULL) {
349         for (i = 0; i < ia->numRelocations; i++)
350             free(ia->relocations[i].oldPath);
351         free(ia->relocations);
352     }
353 #endif
354
355     rpmcliFini(optCon);
356
357     rpmlog(RPMLOG_DEBUG, "Exit status: %d\n", ec);
358
359     return RETVAL(ec);
360 }