/* * Copyright (c) 2007, Novell Inc. * * This program is licensed under the BSD license, read LICENSE.BSD * for further information */ /* * rpmdb2solv * * Reads rpm database (and evtl. more, like product metadata) to build * a .solv file of 'installed' solvables. * Writes .solv to stdout * */ #include #include #include #include #include #ifdef ENABLE_RPMDB_LIBRPM #include #endif #include "pool.h" #include "repo.h" #include "repo_rpmdb.h" #ifdef ENABLE_PUBKEY #include "repo_pubkey.h" #endif #include "repo_products.h" #include "repo_solv.h" #include "common_write.h" #ifdef ENABLE_APPDATA #include "repo_appdata.h" #endif #ifdef SUSE #include "repo_autopattern.h" #endif static void usage(int status) { fprintf(stderr, "\nUsage:\n" "rpmdb2solv [-P] [-C] [-n] [-b ] [-p ] [-r ]\n" " -n : No packages, do not read rpmdb, useful to only parse products\n" " -p : Scan for .prod files, representing installed products\n" " -r : Prefix rpmdb path and with \n" " -o : Write .solv to file instead of stdout\n" " -P : print percentage done\n" " -C : include the changelog\n" ); exit(status); } int main(int argc, char **argv) { FILE *reffp = 0; Pool *pool = pool_create(); Repo *repo; Repodata *data; int c, percent = 0; int nopacks = 0; int add_changelog = 0; const char *root = 0; const char *dbpath = 0; const char *refname = 0; #ifdef ENABLE_SUSEREPO char *proddir = 0; #endif char *outfile = 0; #ifdef ENABLE_PUBKEY int pubkeys = 0; #endif #ifdef ENABLE_APPDATA int add_appdata = 0; #endif #ifdef SUSE int add_auto = 0; #endif /* * parse arguments */ while ((c = getopt(argc, argv, "ACD:PhnkxXr:p:o:")) >= 0) switch (c) { case 'h': usage(0); break; case 'r': root = optarg; break; case 'D': dbpath = optarg; break; case 'n': nopacks = 1; break; case 'P': percent = 1; break; case 'p': #ifdef ENABLE_SUSEREPO proddir = optarg; #endif break; case 'x': break; /* extrapool no longer supported */ case 'X': #ifdef SUSE add_auto = 1; #endif break; case 'A': #ifdef ENABLE_APPDATA add_appdata = 1; #endif break; case 'o': outfile = optarg; break; #ifdef ENABLE_PUBKEY case 'k': nopacks = 1; pubkeys = 1; break; #endif case 'C': add_changelog = 1; break; default: usage(1); } if (outfile && !freopen(outfile, "w", stdout)) { perror(outfile); exit(1); } /* * optional arg is old version of rpmdb solv file * should make this a real option instead */ if (optind < argc) refname = argv[optind]; if (refname && !nopacks) { if ((reffp = fopen(refname, "r")) == NULL) perror(refname); } /* * create 'installed' repository * add products * add rpmdb * write .solv */ if (root && *root) pool_set_rootdir(pool, root); #ifdef ENABLE_PUBKEY if (dbpath && *dbpath && (!nopacks || pubkeys)) #else if (dbpath && *dbpath && !nopacks) #endif { #ifdef ENABLE_RPMDB_LIBRPM char *macro = solv_dupjoin("_dbpath ", dbpath, 0); rpmDefineMacro(NULL, macro, 0); free(macro); #else fprintf(stderr, "cannot set dbpath without librpm\n"); exit(1); #endif } repo = repo_create(pool, "installed"); data = repo_add_repodata(repo, 0); if (!nopacks) { int flags = REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE; if (percent) flags |= RPMDB_REPORT_PROGRESS; if (add_changelog) flags |= RPM_ADD_WITH_CHANGELOG; if (repo_add_rpmdb_reffp(repo, reffp, flags)) { fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool)); exit(1); } } #ifdef ENABLE_PUBKEY if (pubkeys) { if (repo_add_rpmdb_pubkeys(repo, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | ADD_WITH_KEYSIGNATURES)) { fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool)); exit(1); } } #endif #ifdef ENABLE_SUSEREPO if (proddir && *proddir) { if (root && *root) { int rootlen = strlen(root); if (!strncmp(root, proddir, rootlen)) { proddir += rootlen; if (*proddir != '/' && proddir[-1] == '/') proddir--; } } if (repo_add_products(repo, proddir, REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE)) { fprintf(stderr, "rpmdb2solv: %s\n", pool_errstr(pool)); exit(1); } } #endif #ifdef ENABLE_APPDATA if (add_appdata) { repo_add_appdata_dir(repo, "/usr/share/metainfo", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST); repo_add_appdata_dir(repo, "/usr/share/appdata", REPO_USE_ROOTDIR | REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | APPDATA_SEARCH_UNINTERNALIZED_FILELIST); } #endif repodata_internalize(data); if (reffp) fclose(reffp); #ifdef SUSE if (add_auto) repo_add_autopattern(repo, ADD_NO_AUTOPRODUCTS); #endif tool_write(repo, stdout); pool_free(pool); exit(0); }