added NEED_TIMEZONE, NEED_MYREALLOC
[platform/upstream/rpm.git] / rpm-qo.c
1 #include <getopt.h>
2 #include <locale.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <sys/stat.h>
8
9 #include "install.h"
10 #include <intl.h>
11 #include "lib/messages.h"
12 #include "lib/signature.h"
13 #include "query.h"
14 #include "verify.h"
15 #include "checksig.h"
16 #include "rpmlib.h"
17 #include "build/build.h"
18
19 #define GETOPT_QUERYFORMAT      1000
20 #define GETOPT_WHATREQUIRES     1001
21 #define GETOPT_WHATPROVIDES     1002
22 #define GETOPT_REBUILD          1003
23 #define GETOPT_RECOMPILE        1004
24 #define GETOPT_ADDSIGN          1005
25 #define GETOPT_RESIGN           1006
26 #define GETOPT_BUILDROOT        1007
27 #define GETOPT_PROVIDES         1008
28 #define GETOPT_QUERYBYNUMBER    1009
29 #define GETOPT_DBPATH           1010
30 #define GETOPT_PREFIX           1011
31 #define GETOPT_TIMECHECK        1012
32 #define GETOPT_REBUILDDB        1013
33 #define GETOPT_FTPPORT          1014
34 #define GETOPT_FTPPROXY         1015
35
36 char * version = VERSION;
37
38 enum modes { MODE_QUERY, MODE_INSTALL, MODE_UNINSTALL, MODE_VERIFY,
39              MODE_BUILD, MODE_REBUILD, MODE_CHECKSIG, MODE_RESIGN,
40              MODE_RECOMPILE, MODE_QUERYTAGS, MODE_INITDB, 
41              MODE_REBUILDDB, MODE_UNKNOWN };
42
43 static void argerror(char * desc);
44
45 static void argerror(char * desc) {
46     fprintf(stderr, "rpm: %s\n", desc);
47     exit(1);
48 }
49
50 void printHelp(void);
51 void printVersion(void);
52 void printBanner(void);
53 void printUsage(void);
54 int build(char *arg, int buildAmount, char *passPhrase,
55           char *buildRootOverride);
56
57 void printVersion(void) {
58     printf(_("RPM version %s\n"), version);
59 }
60
61 void printBanner(void) {
62     puts(_("Copyright (C) 1995 - Red Hat Software"));
63     puts(_("This may be freely redistributed under the terms of the GNU "
64            "Public License"));
65 }
66
67 void printUsage(void) {
68     printVersion();
69     printBanner();
70     puts("");
71
72     puts(_("usage: rpm {--help}"));
73     puts(_("       rpm {--version}"));
74     puts(_("       rpm {--query -q} [-afFpP] [-i] [-l] [-s] [-d] [-c] [-v] [-R]"));
75     puts(_("                        [--scripts] [--root <dir>] [--rcfile <file>]"));
76     puts(_("                        [--whatprovides] [--whatrequires] [--requires]"));
77     puts(_("                        [--ftpuseport] [--ftpproxy <host>] [--ftpport <port>]"));
78     puts(_("                        [--provides] [--dump] [--dbpath <dir>] [targets]"));
79     puts(_("       rpm {--querytags}"));
80 }
81
82 void printHelp(void) {
83     printVersion();
84     printBanner();
85     puts(_(""));
86
87     puts(_("usage:"));
88     puts(_("   --help           - print this message"));
89     puts(_("   --version        - print the version of rpm being used"));
90     puts(_("   all modes support the following arguments:"));
91     puts(_("       -v                 - be a little more verbose"));
92     puts(_("       -vv                - be incredibly verbose (for debugging)"));
93     puts(_("   -q                   - query mode"));
94     puts(_("      --queryformat <s>   - use s as the header format (implies -i)"));
95     puts(_("      Package specification options:"));
96     puts(_("        -a                - query all packages"));
97     puts(_("        -f <file>+        - query package owning <file>"));
98     puts(_("        -F                - like -f, but read file names from stdin"));
99     puts(_("        -p <packagefile>+ - query (uninstalled) package <packagefile>"));
100     puts(_("        -P                - like -p, but read package names from stdin"));
101     puts(_("       --whatprovides <i> - query packages which provide <i> capability"));
102     puts(_("       --whatrequires <i> - query packages which require <i> capability"));
103     puts(_("      Information selection options:"));
104     puts(_("        -i                - display package information"));
105     puts(_("        -l                - display package file list"));
106     puts(_("        -s                - show file states (implies -l)"));
107     puts(_("        -d                - list only documentation files (implies -l)"));
108     puts(_("        -c                - list only configuration files (implies -l)"));
109     puts(_("        --dump            - show all verifiable information for each file"));
110     puts(_("                            (must be used with -l, -c, or -d)"));
111     puts(_("        --provides        - list capabilbities package provides"));
112     puts(_("        --requires"));
113     puts(_("        -R                - list package dependencies"));
114     puts(_("        --scripts         - print the various [un]install scripts"));
115     puts(_(""));
116     puts(_("    --querytags         - list the tags that can be used in a query format"));
117 }
118
119 int main(int argc, char ** argv) {
120     int long_index;
121     enum modes bigMode = MODE_UNKNOWN;
122     enum querysources querySource = QUERY_PACKAGE;
123     enum verifysources verifySource = VERIFY_PACKAGE;
124     int arg;
125     int queryFor = 0, test = 0, version = 0, help = 0, force = 0;
126     int quiet = 0, replaceFiles = 0, replacePackages = 0, showPercents = 0;
127     int showHash = 0, installFlags = 0, uninstallFlags = 0, interfaceFlags = 0;
128     int buildAmount = 0, oldPackage = 0, clean = 0, signIt = 0;
129     int shortCircuit = 0, badOption = 0, queryTags = 0, excldocs = 0;
130     int incldocs = 0, queryScripts = 0, noScripts = 0, noDeps = 0;
131     int noPgp = 0, dump = 0, initdb = 0, ignoreArch = 0, showrc = 0;
132     int gotDbpath = 0, building = 0, ignoreOs = 0, noFiles = 0, verifyFlags;
133     char *tce;
134     int timeCheck;
135     int addSign = NEW_SIGNATURE;
136     char * rcfile = NULL, * queryFormat = NULL, * prefix = NULL;
137     char buildChar = ' ';
138     char * rootdir = "/";
139     char * specFile;
140     char *passPhrase = "";
141     char *buildRootOverride = NULL;
142     char *arch = NULL;
143     char * ftpProxy = NULL, * ftpPort = NULL;
144     char *os = NULL;
145     char * smallArgv[2] = { NULL, NULL };
146     char ** currarg;
147     int ec = 0;
148     struct option optionsTable[] = {
149             { "all", 0, 0, 'a' },
150             { "configfiles", 0, 0, 'c' },
151             { "docfiles", 0, 0, 'd' },
152             { "dump", 0, &dump, 0 },
153             { "group", 0, 0, 'g' },
154             { "help", 0, &help, 0 },
155             { "info", 0, 0, 'i' },
156             { "package", 0, 0, 'p' },
157             { "provides", 0, 0, GETOPT_PROVIDES },
158             { "qf", 1, 0, GETOPT_QUERYFORMAT },
159             { "query", 0, 0, 'q' },
160             { "querybynumber", 0, 0, GETOPT_QUERYBYNUMBER },
161             { "queryformat", 1, 0, GETOPT_QUERYFORMAT },
162             { "querytags", 0, &queryTags, 0 },
163             { "quiet", 0, &quiet, 0 },
164             { "requires", 0, 0, 'R' },
165             { "scripts", 0, &queryScripts, 0 },
166             { "state", 0, 0, 's' },
167             { "stdin-files", 0, 0, 'F' },
168             { "stdin-group", 0, 0, 'G' },
169             { "stdin-packages", 0, 0, 'P' },
170             { "stdin-query", 0, 0, 'Q' },
171             { "verbose", 0, 0, 'v' },
172             { "version", 0, &version, 0 },
173             { "whatrequires", 0, 0, GETOPT_WHATREQUIRES },
174             { "whatprovides", 0, 0, GETOPT_WHATPROVIDES },
175             { 0, 0, 0, 0 } 
176         } ;
177     struct option * options = optionsTable;
178
179     /* set up the correct locale via the LANG environment variable */
180     setlocale(LC_ALL, "" );
181
182     bindtextdomain(NLSPACKAGE, "/usr/lib/locale");
183     textdomain(NLSPACKAGE);
184
185     /* reading this early makes it easy to override */
186     if (rpmReadConfigFiles(rcfile, arch, os, building))  
187         exit(1);
188     if (showrc) {
189         rpmShowRC(stdout);
190         exit(0);
191     }
192
193     while (1) {
194         long_index = 0;
195
196         arg = getopt_long(argc, argv, "RQqVyUYhpvKPfFilseagGDducr:b:", options, 
197                           &long_index);
198         if (arg == -1) break;
199
200         switch (arg) {
201           case '?':
202             badOption = 1;
203             break;
204
205           case 'Q':
206             if (querySource != QUERY_PACKAGE && querySource != QUERY_SPACKAGE)
207                 argerror(_("only one type of query may be performed at a "
208                            "time"));
209             querySource = QUERY_SPACKAGE;
210             /* fallthrough */
211           case 'q':
212             if (bigMode != MODE_UNKNOWN && bigMode != MODE_QUERY)
213                 argerror(_("only one major mode may be specified"));
214             bigMode = MODE_QUERY;
215             break;
216
217           case 'v':
218             rpmIncreaseVerbosity();
219             break;
220
221           case 'i':
222             if (!long_index) {
223                 if (bigMode == MODE_QUERY)
224                     queryFor |= QUERY_FOR_INFO;
225                 else if (bigMode == MODE_INSTALL)
226                     /* ignore it */ ;
227                 else if (bigMode == MODE_UNKNOWN)
228                     bigMode = MODE_INSTALL;
229             }
230             else if (!strcmp(options[long_index].name, "info"))
231                 queryFor |= QUERY_FOR_INFO;
232             else 
233                 bigMode = MODE_INSTALL;
234                 
235             break;
236
237           case 's':
238             queryFor |= QUERY_FOR_LIST | QUERY_FOR_STATE;
239             break;
240
241           case 'R':
242             queryFor |= QUERY_FOR_REQUIRES;
243             break;
244
245           case 'l':
246             queryFor |= QUERY_FOR_LIST;
247             break;
248
249           case 'd':
250             queryFor |= QUERY_FOR_DOCS | QUERY_FOR_LIST;
251             break;
252
253           case 'c':
254             queryFor |= QUERY_FOR_CONFIG | QUERY_FOR_LIST;
255             break;
256
257           case 'P':
258             if (querySource != QUERY_PACKAGE && querySource != QUERY_SRPM)
259                 argerror(_("one type of query/verify may be performed at a "
260                                 "time"));
261             querySource = QUERY_SRPM;
262             verifySource = VERIFY_SRPM;
263             break;
264
265           case 'p':
266             if (querySource != QUERY_PACKAGE && querySource != QUERY_RPM)
267                 argerror(_("one type of query/verify may be performed at a " "time"));
268             querySource = QUERY_RPM;
269             verifySource = VERIFY_RPM;
270             break;
271
272           case 'G':
273             if (querySource != QUERY_PACKAGE && querySource != QUERY_SGROUP)
274                 argerror(_("one type of query/verify may be performed at a "
275                                 "time"));
276             querySource = QUERY_SGROUP;
277             verifySource = VERIFY_SGROUP;
278             break;
279
280           case 'g':
281             if (querySource != QUERY_PACKAGE && querySource != QUERY_GROUP)
282                 argerror(_("one type of query/verify may be performed at a "
283                                 "time"));
284             querySource = QUERY_GROUP;
285             verifySource = VERIFY_GRP;
286             break;
287
288           case 'F':
289             if (querySource != QUERY_PACKAGE && querySource != QUERY_SPATH)
290                 argerror(_("one type of query/verify may be performed at a "
291                                 "time"));
292             querySource = QUERY_SPATH;
293             verifySource = VERIFY_SPATH;
294             break;
295
296           case 'f':
297             if (querySource != QUERY_PACKAGE && querySource != QUERY_PATH)
298                 argerror(_("one type of query/verify may be performed at a "
299                                 "time"));
300             querySource = QUERY_PATH;
301             verifySource = VERIFY_PATH;
302             break;
303
304           case 'a':
305             if (querySource != QUERY_PACKAGE && querySource != QUERY_ALL)
306                 argerror(_("one type of query/verify may be performed at a "
307                                 "time"));
308             querySource = QUERY_ALL;
309             verifySource = VERIFY_EVERY;
310             break;
311
312           case GETOPT_QUERYFORMAT:
313             if (bigMode != MODE_UNKNOWN && bigMode != MODE_QUERY)
314                 argerror(_("only one major mode may be specified"));
315             bigMode = MODE_QUERY;
316             queryFormat = optarg;
317             queryFor |= QUERY_FOR_INFO;
318             break;
319
320           case GETOPT_WHATREQUIRES:
321             if (querySource != QUERY_PACKAGE && 
322                 querySource != QUERY_WHATREQUIRES)
323                 argerror(_("one type of query/verify may be performed at a "
324                                 "time"));
325             querySource = QUERY_WHATREQUIRES;
326             break;
327
328           case GETOPT_WHATPROVIDES:
329             if (querySource != QUERY_PACKAGE && 
330                 querySource != QUERY_WHATPROVIDES)
331                 argerror(_("one type of query/verify may be performed at a "
332                                 "time"));
333             querySource = QUERY_WHATPROVIDES;
334             break;
335
336           case GETOPT_PROVIDES:
337             queryFor |= QUERY_FOR_PROVIDES;
338             break;
339
340           default:
341             if (options[long_index].flag) {
342                 *options[long_index].flag = 1;
343             } else {
344                 badOption = 1;
345             }
346             break;
347         }
348     }
349
350     if (quiet)
351         rpmSetVerbosity(RPMMESS_QUIET);
352
353     if (version) printVersion();
354     if (help) printHelp();
355
356     if (badOption)
357         exit(1);
358
359     if (queryScripts) {
360         queryFor |= QUERY_FOR_SCRIPTS;
361     }
362
363     if (queryTags)
364         if (bigMode != MODE_UNKNOWN) 
365             argerror(_("only one major mode may be specified"));
366         else
367             bigMode = MODE_QUERYTAGS;
368
369     if (bigMode != MODE_QUERY && bigMode != MODE_INSTALL && 
370         bigMode != MODE_UNINSTALL && bigMode != MODE_VERIFY &&
371         bigMode != MODE_INITDB && gotDbpath)
372         argerror(_("--dbpath given for operation that does not use a "
373                         "database"));
374     
375     if (bigMode != MODE_QUERY && queryFor) 
376         argerror(_("unexpected query specifiers"));
377
378     if (bigMode != MODE_QUERY && bigMode != MODE_VERIFY &&
379         querySource != QUERY_PACKAGE) 
380         argerror(_("unexpected query source"));
381
382     if (bigMode != MODE_INSTALL && force)
383         argerror(_("only installation and upgrading may be forced"));
384
385     if (bigMode != MODE_INSTALL && prefix)
386         argerror(_("--prefix may only be used when installing new packages"));
387
388     if (bigMode != MODE_INSTALL && showHash)
389         argerror(_("--hash (-h) may only be specified during package "
390                         "installation"));
391
392     if (bigMode != MODE_INSTALL && showPercents)
393         argerror(_("--percent may only be specified during package "
394                         "installation"));
395
396     if (bigMode != MODE_INSTALL && replaceFiles)
397         argerror(_("--replacefiles may only be specified during package "
398                         "installation"));
399
400     if (bigMode != MODE_INSTALL && replacePackages)
401         argerror(_("--replacepkgs may only be specified during package "
402                         "installation"));
403
404     if (bigMode != MODE_INSTALL && excldocs)
405         argerror(_("--excludedocs may only be specified during package "
406                    "installation"));
407
408     if (bigMode != MODE_INSTALL && incldocs)
409         argerror(_("--includedocs may only be specified during package "
410                    "installation"));
411
412     if (excldocs && incldocs)
413         argerror(_("only one of --excludedocs and --includedocs may be "
414                  "specified"));
415   
416     if (bigMode != MODE_INSTALL && ignoreArch)
417         argerror(_("--ignorearch may only be specified during package "
418                    "installation"));
419
420     if (bigMode != MODE_INSTALL && ignoreOs)
421         argerror(_("--ignoreos may only be specified during package "
422                    "installation"));
423
424     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && noScripts)
425         argerror(_("--noscripts may only be specified during package "
426                    "installation and uninstallation"));
427
428     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && 
429         bigMode != MODE_VERIFY && noDeps)
430         argerror(_("--nodeps may only be specified during package "
431                    "installation, uninstallation, and verification"));
432
433     if (bigMode != MODE_VERIFY && noFiles)
434         argerror(_("--nofiles may only be specified during package "
435                    "verification"));
436
437     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL &&
438         bigMode != MODE_BUILD && test)
439         argerror(_("--test may only be specified during package installation, "
440                  "uninstallation, and building"));
441
442     if (bigMode != MODE_INSTALL && bigMode != MODE_UNINSTALL && 
443         bigMode != MODE_QUERY   && bigMode != MODE_VERIFY    &&                         bigMode != MODE_REBUILDDB && rootdir[1])
444         argerror(_("--root (-r) may only be specified during "
445                  "installation, uninstallation, querying, and "
446                  "database rebuilds"));
447
448     if (bigMode != MODE_BUILD && clean) 
449         argerror(_("--clean may only be used during package building"));
450
451     if (bigMode != MODE_BUILD && shortCircuit) 
452         argerror(_("--short-circuit may only be used during package building"));
453
454     if (shortCircuit && (buildChar != 'c') && (buildChar != 'i')) {
455         argerror(_("--short-circuit may only be used with -bc or -bi"));
456     }
457
458     if (oldPackage && !(installFlags & RPMINSTALL_UPGRADE))
459         argerror(_("--oldpackage may only be used during upgrades"));
460
461     if (bigMode != MODE_QUERY && dump) 
462         argerror(_("--dump may only be used during queryies"));
463
464     if (bigMode == MODE_QUERY && dump && !(queryFor & QUERY_FOR_LIST))
465         argerror(_("--dump of queries must be used with -l, -c, or -d"));
466
467     if ((ftpProxy || ftpPort) && !(bigMode == MODE_INSTALL ||
468         (bigMode == MODE_QUERY && (querySource == QUERY_RPM ||
469             querySource == QUERY_SRPM)))) 
470         argerror(_("ftp options can only be used during package queries, "
471                  "installs, and upgrades"));
472
473     if (oldPackage || (force && (installFlags & RPMINSTALL_UPGRADE)))
474         installFlags |= RPMINSTALL_UPGRADETOOLD;
475
476     switch (bigMode) {
477       case MODE_UNKNOWN:
478         if (!version && !help) printUsage();
479         break;
480
481       case MODE_QUERYTAGS:
482         if (argc != 2)
483             argerror(_("unexpected arguments to --querytags "));
484
485         queryPrintTags();
486         break;
487
488       case MODE_QUERY:
489         if (dump) queryFor |= QUERY_FOR_DUMPFILES;
490
491         if (querySource == QUERY_ALL) {
492             if (optind != argc) 
493                 argerror(_("extra arguments given for query of all packages"));
494
495             ec = doQuery(rootdir, QUERY_ALL, queryFor, NULL, queryFormat);
496         } else if (querySource == QUERY_SPATH || 
497                    querySource == QUERY_SPACKAGE ||
498                    querySource == QUERY_SRPM) {
499             char buffer[255];
500             int i;
501
502             while (fgets(buffer, 255, stdin)) {
503                 i = strlen(buffer) - 1;
504                 if (buffer[i] == '\n') buffer[i] = 0;
505                 if (strlen(buffer)) 
506                     ec += doQuery(rootdir, querySource, queryFor, buffer, 
507                                   queryFormat);
508             }
509         } else {
510             if (optind == argc) 
511                 argerror(_("no arguments given for query"));
512             while (optind < argc) 
513                 ec = doQuery(rootdir, querySource, queryFor, argv[optind++], 
514                              queryFormat);
515         }
516         break;
517     }
518
519     return ec;
520 }