2 * testdb.c : Test a pacman local database for validity
4 * Copyright (c) 2007 by Aaron Griffin <aaronmgriffin@gmail.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 #include <alpm_list.h>
32 #define BASENAME "testdb"
34 pmhandle_t
*handle
= NULL
;
36 static void cleanup(int signum
) {
37 if(handle
&& alpm_release(handle
) == -1) {
38 fprintf(stderr
, "error releasing alpm\n");
44 static void output_cb(pmloglevel_t level
, const char *fmt
, va_list args
)
48 case PM_LOG_ERROR
: printf("error: "); break;
49 case PM_LOG_WARNING
: printf("warning: "); break;
56 static int check_localdb_files(void)
64 dbpath
= alpm_option_get_dbpath(handle
);
65 snprintf(path
, sizeof(path
), "%slocal", dbpath
);
66 if(!(dir
= opendir(path
))) {
67 fprintf(stderr
, "error : %s : %s\n", path
, strerror(errno
));
71 while((ent
= readdir(dir
)) != NULL
) {
72 if(strcmp(ent
->d_name
, ".") == 0 || strcmp(ent
->d_name
, "..") == 0
73 || ent
->d_name
[0] == '.') {
76 /* check for known db files in local database */
77 snprintf(path
, sizeof(path
), "%slocal/%s/desc", dbpath
, ent
->d_name
);
78 if(access(path
, F_OK
)) {
79 printf("%s: description file is missing\n", ent
->d_name
);
82 snprintf(path
, sizeof(path
), "%slocal/%s/files", dbpath
, ent
->d_name
);
83 if(access(path
, F_OK
)) {
84 printf("%s: file list is missing\n", ent
->d_name
);
89 fprintf(stderr
, "error closing dbpath : %s\n", strerror(errno
));
96 static int checkdeps(alpm_list_t
*pkglist
)
98 alpm_list_t
*data
, *i
;
100 /* check dependencies */
101 data
= alpm_checkdeps(handle
, pkglist
, NULL
, pkglist
, 0);
102 for(i
= data
; i
; i
= alpm_list_next(i
)) {
103 pmdepmissing_t
*miss
= alpm_list_getdata(i
);
104 char *depstring
= alpm_dep_compute_string(miss
->depend
);
105 printf("missing dependency for %s : %s\n", miss
->target
,
114 static int checkconflicts(alpm_list_t
*pkglist
)
116 alpm_list_t
*data
, *i
;
118 /* check conflicts */
119 data
= alpm_checkconflicts(handle
, pkglist
);
120 for(i
= data
; i
; i
= i
->next
) {
121 pmconflict_t
*conflict
= alpm_list_getdata(i
);
122 printf("%s conflicts with %s\n",
123 conflict
->package1
, conflict
->package2
);
130 static int check_localdb(void) {
133 alpm_list_t
*pkglist
;
135 ret
= check_localdb_files();
140 db
= alpm_option_get_localdb(handle
);
141 pkglist
= alpm_db_get_pkgcache(db
);
142 ret
+= checkdeps(pkglist
);
143 ret
+= checkconflicts(pkglist
);
147 static int check_syncdbs(alpm_list_t
*dbnames
) {
150 alpm_list_t
*i
, *pkglist
, *syncpkglist
= NULL
;
152 for(i
= dbnames
; i
; i
= alpm_list_next(i
)) {
153 char *dbname
= alpm_list_getdata(i
);
154 db
= alpm_db_register_sync(handle
, dbname
);
156 fprintf(stderr
, "error: could not register sync database (%s)\n",
157 alpm_strerror(alpm_errno(handle
)));
161 pkglist
= alpm_db_get_pkgcache(db
);
162 syncpkglist
= alpm_list_join(syncpkglist
, alpm_list_copy(pkglist
));
164 ret
+= checkdeps(syncpkglist
);
167 alpm_list_free(syncpkglist
);
171 static void usage(void) {
172 fprintf(stderr
, "usage:\n");
174 "\t%s [-b <pacman db>] : check the local database\n", BASENAME
);
176 "\t%s [-b <pacman db>] core extra ... : check the listed sync databases\n", BASENAME
);
180 int main(int argc
, char *argv
[])
184 const char *dbpath
= DBPATH
;
186 alpm_list_t
*dbnames
= NULL
;
189 if(strcmp(argv
[a
], "-b") == 0) {
195 } else if(strcmp(argv
[a
], "-h") == 0 ||
196 strcmp(argv
[a
], "--help") == 0 ) {
199 dbnames
= alpm_list_add(dbnames
, argv
[a
]);
204 handle
= alpm_initialize(ROOTDIR
, dbpath
, &err
);
206 fprintf(stderr
, "cannot initialize alpm: %s\n", alpm_strerror(err
));
210 /* let us get log messages from libalpm */
211 alpm_option_set_logcb(handle
, output_cb
);
214 ret
= check_localdb();
216 ret
= check_syncdbs(dbnames
);
217 alpm_list_free(dbnames
);
223 /* vim: set ts=2 sw=2 noet: */