summaryrefslogtreecommitdiff
path: root/rpmdb.c
blob: 22b0b3e5d25137e561262eb7bd01436f4880aa84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "system.h"

#include <popt.h>
#include <rpm/rpmcli.h>
#include <rpm/rpmdb.h>
#include "cliutils.h"
#include "debug.h"

enum modes {
    MODE_INITDB		= (1 << 0),
    MODE_REBUILDDB	= (1 << 1),
    MODE_VERIFYDB	= (1 << 2),
    MODE_EXPORTDB	= (1 << 3),
    MODE_IMPORTDB	= (1 << 4),
    MODE_SALVAGEDB	= (1 << 5),
};

static int mode = 0;

static struct poptOption dbOptsTable[] = {
    { "initdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_INITDB,
	N_("initialize database"), NULL},
    { "rebuilddb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_REBUILDDB,
	N_("rebuild database inverted lists from installed package headers"),
	NULL},
    { "verifydb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN),
	&mode, MODE_VERIFYDB, N_("verify database files"), NULL},
    { "salvagedb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR|POPT_ARGFLAG_DOC_HIDDEN),
	&mode, MODE_SALVAGEDB, N_("salvage database"), NULL},
    { "exportdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_EXPORTDB,
	N_("export database to stdout header list"),
	NULL},
    { "importdb", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_IMPORTDB,
	N_("import database from stdin header list"),
	NULL},
    POPT_TABLEEND
};

static struct poptOption optionsTable[] = {
    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, dbOptsTable, 0,
	N_("Database options:"), NULL },
    { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
	N_("Common options for all rpm modes and executables:"), NULL },

    POPT_AUTOALIAS
    POPT_AUTOHELP
    POPT_TABLEEND
};

static int exportDB(rpmts ts)
{
    FD_t fd = fdDup(STDOUT_FILENO);
    rpmtxn txn = rpmtxnBegin(ts, RPMTXN_READ);
    int rc = 0;

    if (txn && fd) {
	Header h;
	rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_PACKAGES, NULL, 0);
	while ((h = rpmdbNextIterator(mi))) {
	    rc += headerWrite(fd, h, HEADER_MAGIC_YES);
	}
	rpmdbFreeIterator(mi);
    } else {
	rc = -1;
    }
    Fclose(fd);
    rpmtxnEnd(txn);
    return rc;
}

/* XXX: only allow this on empty db? */
static int importDB(rpmts ts)
{
    FD_t fd = fdDup(STDIN_FILENO);
    rpmtxn txn = rpmtxnBegin(ts, RPMTXN_WRITE);
    int rc = 0;

    if (txn && fd) {
	Header h;
	while ((h = headerRead(fd, HEADER_MAGIC_YES))) {
	    rc += rpmtsImportHeader(txn, h, 0);
	}
    } else {
	rc = -1;
    }
    rpmtxnEnd(txn);
    Fclose(fd);
    return rc;
}

int main(int argc, char *argv[])
{
    int ec = EXIT_FAILURE;
    poptContext optCon = NULL;
    rpmts ts = NULL;

    optCon = rpmcliInit(argc, argv, optionsTable);

    if (argc < 2 || poptPeekArg(optCon)) {
	printUsage(optCon, stderr, 0);
	goto exit;
    }

    ts = rpmtsCreate();
    rpmtsSetRootDir(ts, rpmcliRootDir);

    switch (mode) {
    case MODE_INITDB:
	ec = rpmtsInitDB(ts, 0644);
	break;
    case MODE_REBUILDDB:
    case MODE_SALVAGEDB:
    {   rpmVSFlags vsflags = rpmExpandNumeric("%{_vsflags_rebuilddb}");
	rpmVSFlags ovsflags = rpmtsSetVSFlags(ts, vsflags);
	if (mode == MODE_SALVAGEDB)
	    rpmDefineMacro(NULL, "_rebuilddb_salvage 1", 0);
	ec = rpmtsRebuildDB(ts);
	rpmtsSetVSFlags(ts, ovsflags);
    }	break;
    case MODE_VERIFYDB:
	ec = rpmtsVerifyDB(ts);
	break;
    case MODE_EXPORTDB:
	ec = exportDB(ts);
	break;
    case MODE_IMPORTDB:
	ec = importDB(ts);
	break;
    default:
	argerror(_("only one major mode may be specified"));
    }

exit:
    rpmtsFree(ts);
    rpmcliFini(optCon);
    return ec;
}