1 #define _POSIX_C_SOURCE 200809L
9 #include "lib/jsw/jsw_hlib.h"
10 #include "lib/jsw/jsw_atree.h"
13 * find packages, and lib deps
22 char *checkfile(char *pkgstr, char *path) {
26 if (!zpm_open(&pkgfile, path)) {
30 pkgid = zpm_findpkg(&pkgfile, pkgstr, "hash is not null");
36 char *checkfileforlib(char *soname, char *path) {
40 if (!zpm_open(&pkgfile, path)) {
44 pkgid = zpm_findlib(&pkgfile, soname, "hash is not null");
46 fprintf(stderr, "sql error: %s\n", pkgfile.errmsg);
53 int find_lib(char *soname, struct pkgloc *pkg) {
55 char *installed = 0, *found = 0;
60 if (zpm_open(&localdb, NULL)) {
61 installed = zpm_findlib(&localdb, soname, "status = 'installed'");
65 /* we're done, the lib is installed */
69 fprintf(stderr, "can't open localdb\n");
74 rv = glob("/var/lib/zpm/repos/*.repo", 0, NULL, &repos);
77 fprintf(stderr, "glob no mem\n");
78 exit(EXIT_FAILURE); break;
80 fprintf(stderr, "glob abort\n");
81 exit(EXIT_FAILURE); break;
91 for (i = 0; i < repos.gl_pathc; i++) {
92 found = checkfileforlib(soname, repos.gl_pathv[i]);
94 rv = zpm_vercmp(found, latest);
98 pkgfile = strdup(repos.gl_pathv[i]);
106 char *pkgdir = "/home/zoranix/zrepo/packages";
109 size_t globlen = strlen(pkgdir)+7;
110 pkgglob = malloc(globlen+1);
111 snprintf(pkgglob, globlen, "%s/*.zpm", pkgdir);
112 rv = glob(pkgglob, 0, NULL, &repos);
117 exit(EXIT_FAILURE); break;
119 exit(EXIT_FAILURE); break;
120 case GLOB_NOMATCH: break;
127 for (i = 0; i < repos.gl_pathc; i++) {
128 found = checkfileforlib(soname, repos.gl_pathv[i]);
130 rv = zpm_vercmp(found, latest);
134 pkgfile = strdup(repos.gl_pathv[i]);
139 if (latest && pkgfile) {
140 pkg->id = strdup(latest);
148 struct pkgloc *find_package(char *pkgstr) {
150 char *installed = 0, *found = 0;
152 struct pkgloc *pkg = 0;
156 if (zpm_open(&localdb, NULL)) {
157 installed = zpm_findpkg(&localdb, pkgstr, "status = 'installed'");
161 found = zpm_findpkg(&localdb, pkgstr, NULL);
163 rv = zpm_vercmp(found, latest);
166 pkgfile = localdb.path;
171 fprintf(stderr, "can't open localdb\n");
176 rv = glob("/var/lib/zpm/repos/*.repo", 0, NULL, &repos);
179 fprintf(stderr, "glob no mem\n");
180 exit(EXIT_FAILURE); break;
182 fprintf(stderr, "glob abort\n");
183 exit(EXIT_FAILURE); break;
193 for (i = 0; i < repos.gl_pathc; i++) {
194 found = checkfile(pkgstr, repos.gl_pathv[i]);
196 rv = zpm_vercmp(found, latest);
199 pkgfile = repos.gl_pathv[i];
207 char *pkgdir = "/home/zoranix/zrepo/packages";
210 size_t globlen = strlen(pkgdir)+strlen(pkgstr)+7;
211 pkgglob = malloc(globlen+1);
212 snprintf(pkgglob, globlen, "%s/%s*.zpm", pkgdir, pkgstr);
214 rv = glob(pkgglob, 0, NULL, &repos);
217 exit(EXIT_FAILURE); break;
219 exit(EXIT_FAILURE); break;
220 case GLOB_NOMATCH: break;
227 for (i = 0; i < repos.gl_pathc; i++) {
228 found = checkfile(pkgstr, repos.gl_pathv[i]);
230 rv = zpm_vercmp(found, latest);
233 pkgfile = strdup(repos.gl_pathv[i]);
238 if (latest && pkgfile) {
239 pkg = malloc(sizeof *pkg);
240 pkg->id = strdup(latest);
247 char *pkglibsneeded = "\
249 select distinct EN.needed as soname, PF.pkgid\
251 join packagefiles_pkgid PF on PF.hash = EN.file\
254 select distinct EL.soname, PF.pkgid\
255 from elflibraries EL\
256 join packagefiles_pkgid PF on PF.hash = EL.file\
258 select distinct PL.soname, PP.soname is not null as selfsatisfied\
260 left join pkgprovides PP on PL.pkgid = PP.pkgid and PL.soname = PP.soname\
264 void checklibs(jsw_hash_t *check, jsw_hash_t *forlibs, jsw_hash_t *nfound) {
265 char *pkgid = 0, *pkgfile = 0;
268 /* checked_libs is a list of checked sonames
269 * checked is a list of checked packages
270 * needed is list of libs for package
272 jsw_atree_t *needed = 0, *checked, *checked_libs;
278 checked = jsw_anew((cmp_f)strcmp, (dup_f)strdup, (rel_f)free);
279 checked_libs = jsw_anew((cmp_f)strcmp, (dup_f)strdup, (rel_f)free);
281 while (jsw_hsize(check) > 0) {
287 pkgid = strdup(jsw_hkey(check));
288 pkgfile = strdup(jsw_hitem(check));
290 if (!pkgid || !pkgfile) {
294 jsw_herase(check, pkgid);
296 if (jsw_afind(checked, pkgid)) {
297 /* already checked this one */
301 /* we do this now so we catch self deps */
302 jsw_ainsert(checked, pkgid);
304 /* get the libraries needed by this package */
305 if (!zpm_open(&src, pkgfile)) {
306 fprintf(stderr, "can't zpm open %s\n", pkgfile);
310 if (needed) jsw_adelete(needed);
311 needed = jsw_anew((cmp_f)strcmp, (dup_f)strdup, (rel_f)free);
312 libs = zpm_libraries_needed(&src, pkgid, needed);
321 for (soname = jsw_atfirst(i, needed); soname; soname = jsw_atnext(i)) {
323 struct pkgloc pkginfo;
325 /* if it's in checked_libs, we've already looked at this one */
326 if (jsw_afind(checked_libs, soname)) {
330 /* haven't found this soname */
331 jsw_ainsert(checked_libs, soname);
333 found = find_lib(soname, &pkginfo);
335 if (!jsw_hinsert(nfound, soname, pkgid)) {
336 fprintf(stderr,"insert error\n");
342 /* if not alreacy checked, add to check */
343 if (!jsw_afind(checked, pkginfo.file)) {
344 jsw_hinsert(check,pkginfo.id,pkginfo.file);
346 /* shouldn't be in there already */
347 jsw_hinsert(forlibs, pkginfo.id, pkginfo.file);
349 /* otherwise found == 2, so just continue */
360 char *pathcat(char *dir, char *path) {
361 size_t dirlen = 0, pathlen = 0;
364 /* chop off trailing / on dir */
366 dirlen = strlen(dir);
367 while (dirlen && dir[dirlen-1] == '/') {
373 pathlen = strlen(path);
374 while (*path && *path == '/') {
380 cat = malloc(dirlen + pathlen + 2);
382 strncpy(cat, dir, dirlen);
384 strcpy(cat+dirlen+1, path);
389 void print_pkghash(jsw_hash_t *hash, int json) {
390 const char *pkgid, *file;
395 fmt = json ? "\"%s\": \"%s\"" : "%s:%s";
396 sep = json ? ", " : "\n";
402 if (jsw_hsize(hash) > 0) {
403 for (jsw_hreset(hash); jsw_hitem(hash); jsw_hnext(hash)) {
404 pkgid = jsw_hkey(hash);
405 file = jsw_hitem(hash);
409 printf(fmt, pkgid, file);
412 if (json) printf(" }");
416 int main(int ac, char *av[]) {
418 int findlibs = 0, json = 0;
419 struct pkgloc *found;
420 jsw_hash_t *packages, *check, *forlibs, *nolib;
423 /* -l also find packages needed for libs
425 * -q quiet - suppress output
427 * -d debug - trace each step
430 * ZPMDB - path to localdb, /var/lib/zpm/local.db
431 * ZPM_REPO_DIR - path to *.repo files, '/var/lib/zpm/repos'
432 * ZPM_PACKAGE_DIRS - : separated paths to *.zpm files,
433 * '/var/lib/zpm/packages'
434 * ZPM_ROOT_DIR :- prepends to above paths
436 * -M (missing) invert the output and only output missing
438 * packages found (suppress with -P)
439 * package strings not found (suppress with -S)
440 * library dependency packages needed and found (suppress with -N)
441 * library dependency packages already installed (suppress with -H)
442 * library dependency packages in install set (suppress with -I)
443 * library dependency sonames not found (suppress with -L)
445 * exit value is 0 if no missing libs and no bad package strings
446 * exit value is non zero otherwise
450 while ((opt = getopt(ac, av, "lj")) != -1) {
452 case 'l': findlibs = 1; break;
453 case 'j': json = 1; break;
454 case 'q': output = 0;
462 packages = jsw_hnew(ac,NULL,(cmp_f)strcmp,(keydup_f)strdup,
463 (itemdup_f)strdup,free,free);
464 check = jsw_hnew(ac,NULL,(cmp_f)strcmp,(keydup_f)strdup,
465 (itemdup_f)strdup,free,free);
466 forlibs = jsw_hnew(ac,NULL,(cmp_f)strcmp,(keydup_f)strdup,
467 (itemdup_f)strdup,free,free);
468 nolib = jsw_hnew(ac,NULL,(cmp_f)strcmp,(keydup_f)strdup,
469 (itemdup_f)strdup,free,free);
470 nfound = jsw_anew((cmp_f)strcmp, (dup_f)strdup, (rel_f)free);
473 for (arg = argn; arg < ac; arg++) {
474 found = find_package(av[arg]);
476 jsw_hinsert(packages, found->id, found->file);
477 jsw_hinsert(check, found->id, found->file);
482 jsw_ainsert(nfound, av[arg]);
488 checklibs(check, forlibs, nolib);
492 print_pkghash(packages, json);
493 print_pkghash(forlibs, json);
496 if (jsw_hsize(nolib) > 0) {
497 for (jsw_hreset(nolib); jsw_hitem(nolib); jsw_hnext(nolib)) {
498 const char *pkgid, *file;
499 pkgid = jsw_hkey(nolib);
500 file = jsw_hitem(nolib);
501 fprintf(stderr, "no lib found %s:%s\n", pkgid, file);
505 if (jsw_asize(nfound) > 0) {
510 for (pkgstr = jsw_atfirst(i, nfound); pkgstr; pkgstr = jsw_atnext(i)) {
511 fprintf(stderr, "%s:\n", pkgstr);
515 return jsw_asize(nfound) > 0 || jsw_hsize(nolib) > 0 ? 1 : 0;