1 #include "system.h"
2
3 #include <popt.h>
4 #include <rpm/rpmcli.h>
5 #include <rpm/rpmdb.h>
6 #include "cliutils.h"
7 #include "debug.h"
8
9 enum modes {
10 MODE_INITDB = (1 << 0),
11 MODE_REBUILDDB = (1 << 1),
12 MODE_VERIFYDB = (1 << 2),
13 MODE_EXPORTDB = (1 << 3),
14 MODE_IMPORTDB = (1 << 4),
15 MODE_SALVAGEDB = (1 << 5),
16 };
17
18 static int mode = 0;
19
20 static struct poptOption dbOptsTable[] = {
21 { "initdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_INITDB,
22 N_("initialize database"), NULL},
23 { "rebuilddb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_REBUILDDB,
24 N_("rebuild database inverted lists from installed package headers"),
25 NULL},
26 { "verifydb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN),
27 &mode, MODE_VERIFYDB, N_("verify database files"), NULL},
28 { "salvagedb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN),
29 &mode, MODE_SALVAGEDB, N_("salvage database"), NULL},
30 { "exportdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_EXPORTDB,
31 N_("export database to stdout header list"),
32 NULL},
33 { "importdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_IMPORTDB,
34 N_("import database from stdin header list"),
35 NULL},
36 POPT_TABLEEND
37 };
38
39 static struct poptOption optionsTable[] = {
40 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, dbOptsTable, 0,
41 N_("Database options:"), NULL },
42 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
43 N_("Common options for all rpm modes and executables:"), NULL },
44
45 POPT_AUTOALIAS
46 POPT_AUTOHELP
47 POPT_TABLEEND
48 };
49
exportDB(rpmts ts)50 static int exportDB(rpmts ts)
51 {
52 FD_t fd = fdDup(STDOUT_FILENO);
53 rpmtxn txn = rpmtxnBegin(ts, RPMTXN_READ);
54 int rc = 0;
55
56 if (txn && fd) {
57 Header h;
58 rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
59 while ((h = rpmdbNextIterator(mi))) {
60 rc += headerWrite(fd, h, HEADER_MAGIC_YES);
61 }
62 rpmdbFreeIterator(mi);
63 } else {
64 rc = -1;
65 }
66 Fclose(fd);
67 rpmtxnEnd(txn);
68 return rc;
69 }
70
71 /* XXX: only allow this on empty db? */
importDB(rpmts ts)72 static int importDB(rpmts ts)
73 {
74 FD_t fd = fdDup(STDIN_FILENO);
75 rpmtxn txn = rpmtxnBegin(ts, RPMTXN_WRITE);
76 int rc = 0;
77
78 if (txn && fd) {
79 Header h;
80 while ((h = headerRead(fd, HEADER_MAGIC_YES))) {
81 rc += rpmtsImportHeader(txn, h, 0);
82 }
83 } else {
84 rc = -1;
85 }
86 rpmtxnEnd(txn);
87 Fclose(fd);
88 return rc;
89 }
90
main(int argc,char * argv[])91 int main(int argc, char *argv[])
92 {
93 int ec = EXIT_FAILURE;
94 poptContext optCon = NULL;
95 rpmts ts = NULL;
96
97 xsetprogname(argv[0]); /* Portability call -- see system.h */
98
99 optCon = rpmcliInit(argc, argv, optionsTable);
100
101 if (argc < 2 || poptPeekArg(optCon)) {
102 printUsage(optCon, stderr, 0);
103 goto exit;
104 }
105
106 ts = rpmtsCreate();
107 rpmtsSetRootDir(ts, rpmcliRootDir);
108
109 switch (mode) {
110 case MODE_INITDB:
111 ec = rpmtsInitDB(ts, 0644);
112 break;
113 case MODE_REBUILDDB:
114 case MODE_SALVAGEDB:
115 { rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
116 rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
117 if (mode == MODE_SALVAGEDB)
118 rpmDefineMacro(NULL, "_rebuilddb_salvage 1", 0);
119 ec = rpmtsRebuildDB(ts);
120 rpmtsSetVSFlags(ts, ovsflags);
121 } break;
122 case MODE_VERIFYDB:
123 ec = rpmtsVerifyDB(ts);
124 break;
125 case MODE_EXPORTDB:
126 ec = exportDB(ts);
127 break;
128 case MODE_IMPORTDB:
129 ec = importDB(ts);
130 break;
131 default:
132 argerror(_("only one major mode may be specified"));
133 }
134
135 exit:
136 rpmtsFree(ts);
137 rpmcliFini(optCon);
138 return ec;
139 }
140