#if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA)) #include #include #include #include #include #include #include #include "pool.h" #include "repo.h" #include "repo_rpmdb.h" #if defined(ENABLE_SUSEREPO) && defined(SUSE) #include "repo_products.h" #endif #if defined(ENABLE_APPDATA) #include "repo_appdata.h" #endif #ifdef SUSE #include "repo_autopattern.h" #endif #include "transaction.h" #include "repoinfo.h" #include "repoinfo_cache.h" #include "repoinfo_system_rpm.h" #ifdef SUSE # define PRODUCTS_PATH "/etc/products.d" #endif #ifdef ENABLE_APPDATA # define APPDATA_PATH "/usr/share/metainfo" # define APPDATA_LEGACY_PATH "/usr/share/appdata" #endif static void runrpm(const char *arg, const char *name, int dupfd3, const char *rootdir) { pid_t pid; int status; if ((pid = fork()) == (pid_t)-1) { perror("fork"); exit(1); } if (pid == 0) { if (!rootdir) rootdir = "/"; if (dupfd3 != -1 && dupfd3 != 3) { dup2(dupfd3, 3); close(dupfd3); } if (dupfd3 != -1) fcntl(3, F_SETFD, 0); /* clear CLOEXEC */ if (strcmp(arg, "-e") == 0) execlp("rpm", "rpm", arg, "--nodeps", "--nodigest", "--nosignature", "--root", rootdir, name, (char *)0); else execlp("rpm", "rpm", arg, "--force", "--nodeps", "--nodigest", "--nosignature", "--root", rootdir, name, (char *)0); perror("rpm"); _exit(0); } while (waitpid(pid, &status, 0) != pid) ; if (status) { printf("rpm failed\n"); exit(1); } } int read_installed_rpm(struct repoinfo *cinfo) { Repo *repo = cinfo->repo; Pool *pool = repo->pool; FILE *ofp = 0; struct stat stb; memset(&stb, 0, sizeof(stb)); printf("rpm database:"); if (stat(pool_prepend_rootdir_tmp(pool, "/var/lib/rpm/Packages"), &stb)) memset(&stb, 0, sizeof(stb)); calc_cookie_stat(&stb, REPOKEY_TYPE_SHA256, 0, cinfo->cookie); cinfo->cookieset = 1; if (usecachedrepo(cinfo, 0, 0)) { printf(" cached\n"); return 1; } printf(" reading\n"); #if defined(ENABLE_SUSEREPO) && defined(PRODUCTS_PATH) if (repo_add_products(repo, PRODUCTS_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR)) { fprintf(stderr, "product reading failed: %s\n", pool_errstr(pool)); return 0; } #endif #if defined(ENABLE_APPDATA) && defined(APPDATA_PATH) if (repo_add_appdata_dir(repo, APPDATA_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR)) { fprintf(stderr, "appdata reading failed: %s\n", pool_errstr(pool)); return 0; } #elif defined(ENABLE_APPDATA) && defined(APPDATA_LEGACY_PATH) if (repo_add_appdata_dir(repo, APPDATA_LEGACY_PATH, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR)) { fprintf(stderr, "appdata reading from legacy dir failed: %s\n", pool_errstr(pool)); return 0; } #endif ofp = fopen(calc_cachepath(repo, 0, 0), "r"); if (repo_add_rpmdb_reffp(repo, ofp, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR)) { fprintf(stderr, "installed db: %s\n", pool_errstr(pool)); return 0; } if (ofp) fclose(ofp); repo_internalize(repo); #ifdef SUSE repo_add_autopattern(repo, 0); #endif writecachedrepo(cinfo, 0, 0); return 1; } void commit_transactionelement_rpm(Pool *pool, Id type, Id p, FILE *fp) { Solvable *s = pool_id2solvable(pool, p); const char *rootdir = pool_get_rootdir(pool); const char *evr, *evrp, *nvra; switch(type) { case SOLVER_TRANSACTION_ERASE: if (!s->repo->rpmdbid || !s->repo->rpmdbid[p - s->repo->start]) break; /* strip epoch from evr */ evr = evrp = pool_id2str(pool, s->evr); while (*evrp >= '0' && *evrp <= '9') evrp++; if (evrp > evr && evrp[0] == ':' && evrp[1]) evr = evrp + 1; nvra = pool_tmpjoin(pool, pool_id2str(pool, s->name), "-", evr); nvra = pool_tmpappend(pool, nvra, ".", pool_id2str(pool, s->arch)); runrpm("-e", nvra, -1, rootdir); /* too bad that --querybynumber doesn't work */ break; case SOLVER_TRANSACTION_INSTALL: case SOLVER_TRANSACTION_MULTIINSTALL: rewind(fp); lseek(fileno(fp), 0, SEEK_SET); runrpm(type == SOLVER_TRANSACTION_MULTIINSTALL ? "-i" : "-U", "/dev/fd/3", fileno(fp), rootdir); break; default: break; } } #endif