_q_static int q_vdb_foreach_pkg(q_vdb_pkg_cb callback, void *priv, q_vdb_cat_filter filter) { q_vdb_ctx *ctx; q_vdb_cat_ctx *cat_ctx; q_vdb_pkg_ctx *pkg_ctx; int ret; ctx = q_vdb_open(); if (!ctx) return EXIT_FAILURE; ret = 0; while ((cat_ctx = q_vdb_next_cat(ctx))) { if (filter && !filter(cat_ctx, priv)) continue; while ((pkg_ctx = q_vdb_next_pkg(cat_ctx))) { ret |= callback(pkg_ctx, priv); q_vdb_close_pkg(pkg_ctx); } } return ret; }
int qpkg_main(int argc, char **argv) { q_vdb_ctx *ctx; q_vdb_cat_ctx *cat_ctx; q_vdb_pkg_ctx *pkg_ctx; size_t s, pkgs_made; int i; struct stat st; char buf[BUFSIZE]; const char *bindir; depend_atom *atom; int restrict_chmod = 0; int qclean = 0; while ((i = GETOPT_LONG(QPKG, qpkg, "")) != -1) { switch (i) { case 'E': eclean = qclean = 1; break; case 'c': qclean = 1; break; case 'p': pretend = 1; break; case 'P': restrict_chmod = 1; free(qpkg_bindir); qpkg_bindir = xstrdup(optarg); if (access(qpkg_bindir, W_OK) != 0) errp("%s", qpkg_bindir); break; COMMON_GETOPTS_CASES(qpkg) } } if (qclean) return qpkg_clean(qpkg_bindir == NULL ? pkgdir : qpkg_bindir); if (argc == optind) qpkg_usage(EXIT_FAILURE); /* setup temp dirs */ i = 0; bindir = qpkg_get_bindir(); if (*bindir != '/') err("'%s' is not a valid package destination", bindir); retry_mkdir: if (mkdir(bindir, 0750) == -1) { lstat(bindir, &st); if (!S_ISDIR(st.st_mode)) { unlink(bindir); if (!i++) goto retry_mkdir; errp("could not create temp bindir '%s'", bindir); } if (!restrict_chmod) if (chmod(bindir, 0750)) errp("could not chmod(0750) temp bindir '%s'", bindir); } /* we have to change to the root so that we can feed the full paths * to tar when we create the binary package. */ xchdir(portroot); /* first process any arguments which point to /var/db/pkg */ pkgs_made = 0; s = strlen(portvdb); for (i = optind; i < argc; ++i) { size_t asize = strlen(argv[i]); if (asize == 0) { argv[i] = NULL; continue; } if (argv[i][asize-1] == '/') argv[i][asize-1] = '\0'; if (!strncmp(portvdb, argv[i], s)) memmove(argv[i], argv[i]+s+1, asize-s); else if (argv[i][0] == '/' && !strncmp(portvdb, argv[i]+1, s)) memmove(argv[i], argv[i]+s+2, asize-s-1); else continue; atom = atom_explode(argv[i]); if (atom) { if (!qpkg_make(atom)) ++pkgs_made; atom_implode(atom); } else warn("could not explode '%s'", argv[i]); argv[i] = NULL; } /* now try to run through vdb and locate matches for user inputs */ ctx = q_vdb_open(portroot, portvdb); if (!ctx) return EXIT_FAILURE; /* scan all the categories */ while ((cat_ctx = q_vdb_next_cat(ctx))) { /* scan all the packages in this category */ const char *catname = cat_ctx->name; while ((pkg_ctx = q_vdb_next_pkg(cat_ctx))) { const char *pkgname = pkg_ctx->name; /* see if user wants any of these packages */ snprintf(buf, sizeof(buf), "%s/%s", catname, pkgname); atom = atom_explode(buf); if (!atom) { warn("could not explode '%s'", buf); goto next_pkg; } snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN); for (i = optind; i < argc; ++i) { if (!argv[i]) continue; if (!strcmp(argv[i], atom->PN) || !strcmp(argv[i], atom->P) || !strcmp(argv[i], buf) || !strcmp(argv[i], "world")) if (!qpkg_make(atom)) ++pkgs_made; } atom_implode(atom); next_pkg: q_vdb_close_pkg(pkg_ctx); } } s = (argc - optind) - pkgs_made; if (s && !pretend) printf(" %s*%s %i package%s could not be matched :/\n", RED, NORM, (int)s, (s > 1 ? "s" : "")); if (pkgs_made) qprintf(" %s*%s Packages can be found in %s\n", GREEN, NORM, bindir); return (pkgs_made ? EXIT_SUCCESS : EXIT_FAILURE); }