int repo_add_products(Repo *repo, const char *proddir, int flags) { const char *fullpath; DIR *dir; if (proddir) { dir = opendir(flags & REPO_USE_ROOTDIR ? pool_prepend_rootdir_tmp(repo->pool, proddir) : proddir); if (dir) { /* assume code11 stype products */ closedir(dir); return repo_add_code11_products(repo, proddir, flags); } } /* code11 didn't work, try old code10 zyppdb */ fullpath = "/var/lib/zypp/db/products"; if (flags & REPO_USE_ROOTDIR) fullpath = pool_prepend_rootdir_tmp(repo->pool, fullpath); dir = opendir(fullpath); if (dir) { closedir(dir); /* assume code10 style products */ return repo_add_zyppdb_products(repo, "/var/lib/zypp/db/products", flags); } /* code10/11 didn't work, try -release files parsing */ fullpath = "/etc"; if (flags & REPO_USE_ROOTDIR) fullpath = pool_prepend_rootdir_tmp(repo->pool, fullpath); dir = opendir(fullpath); if (dir) { closedir(dir); return repo_add_releasefile_products(repo, "/etc", flags); } /* no luck. check if the rootdir exists */ fullpath = pool_get_rootdir(repo->pool); if (fullpath && *fullpath) { dir = opendir(fullpath); if (!dir) return pool_error(repo->pool, -1, "%s: %s", fullpath, strerror(errno)); closedir(dir); } /* the least we can do... */ if (!(flags & REPO_NO_INTERNALIZE) && (flags & REPO_REUSE_REPODATA) != 0) repodata_internalize(repo_last_repodata(repo)); return 0; }
int read_installed_debian(struct repoinfo *cinfo) { struct stat stb; Repo *repo = cinfo->repo; Pool *pool = repo->pool; memset(&stb, 0, sizeof(stb)); printf("dpgk database:"); if (stat(pool_prepend_rootdir_tmp(pool, "/var/lib/dpkg/status"), &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; } if (repo_add_debdb(repo, REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE | REPO_USE_ROOTDIR)) { fprintf(stderr, "installed db: %s\n", pool_errstr(pool)); return 0; } repo_internalize(repo); writecachedrepo(cinfo, 0, 0); return 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; }
int repo_add_debdb(Repo *repo, int flags) { FILE *fp; const char *path = "/var/lib/dpkg/status"; if (flags & REPO_USE_ROOTDIR) path = pool_prepend_rootdir_tmp(repo->pool, path); if ((fp = fopen(path, "r")) == 0) return pool_error(repo->pool, -1, "%s: %s", path, strerror(errno)); repo_add_debpackages(repo, fp, flags); fclose(fp); return 0; }
static int current_rpmdb_checksum(Pool *pool, unsigned char csout[CHKSUM_BYTES]) { const char *rpmdb_prefix_paths[] = { "/var/lib/rpm/Packages", "/usr/share/rpm/Packages" }; unsigned int i; const char *fn; FILE *fp_rpmdb = NULL; int ret = 0; for (i = 0; i < sizeof(rpmdb_prefix_paths)/sizeof(*rpmdb_prefix_paths); i++) { fn = pool_prepend_rootdir_tmp(pool, rpmdb_prefix_paths[i]); fp_rpmdb = fopen(fn, "r"); if (fp_rpmdb) break; } if (!fp_rpmdb || checksum_stat(csout, fp_rpmdb)) ret = 1; if (fp_rpmdb) fclose(fp_rpmdb); return ret; }
Id repo_add_deb(Repo *repo, const char *deb, int flags) { Pool *pool = repo->pool; Repodata *data; unsigned char buf[4096], *bp; int l, l2, vlen, clen, ctarlen; unsigned char *ctgz; unsigned char pkgid[16]; unsigned char *ctar; int gotpkgid; FILE *fp; Solvable *s; struct stat stb; data = repo_add_repodata(repo, flags); if ((fp = fopen(flags & REPO_USE_ROOTDIR ? pool_prepend_rootdir_tmp(pool, deb) : deb, "r")) == 0) { pool_error(pool, -1, "%s: %s", deb, strerror(errno)); return 0; } if (fstat(fileno(fp), &stb)) { pool_error(pool, -1, "fstat: %s", strerror(errno)); fclose(fp); return 0; } l = fread(buf, 1, sizeof(buf), fp); if (l < 8 + 60 || strncmp((char *)buf, "!<arch>\ndebian-binary ", 8 + 16) != 0) { pool_error(pool, -1, "%s: not a deb package", deb); fclose(fp); return 0; } vlen = atoi((char *)buf + 8 + 48); if (vlen < 0 || vlen > l) { pool_error(pool, -1, "%s: not a deb package", deb); fclose(fp); return 0; } vlen += vlen & 1; if (l < 8 + 60 + vlen + 60) { pool_error(pool, -1, "%s: unhandled deb package", deb); fclose(fp); return 0; } if (strncmp((char *)buf + 8 + 60 + vlen, "control.tar.gz ", 16) != 0) { pool_error(pool, -1, "%s: control.tar.gz is not second entry", deb); fclose(fp); return 0; } clen = atoi((char *)buf + 8 + 60 + vlen + 48); if (clen <= 0 || clen >= 0x100000) { pool_error(pool, -1, "%s: control.tar.gz has illegal size", deb); fclose(fp); return 0; } ctgz = solv_calloc(1, clen + 4); bp = buf + 8 + 60 + vlen + 60; l -= 8 + 60 + vlen + 60; if (l > clen) l = clen; if (l) memcpy(ctgz, bp, l); if (l < clen) { if (fread(ctgz + l, clen - l, 1, fp) != 1) { pool_error(pool, -1, "%s: unexpected EOF", deb); solv_free(ctgz); fclose(fp); return 0; } } fclose(fp); gotpkgid = 0; if (flags & DEBS_ADD_WITH_PKGID) { Chksum *chk = solv_chksum_create(REPOKEY_TYPE_MD5); solv_chksum_add(chk, ctgz, clen); solv_chksum_free(chk, pkgid); gotpkgid = 1; } if (ctgz[0] != 0x1f || ctgz[1] != 0x8b) { pool_error(pool, -1, "%s: control.tar.gz is not gzipped", deb); solv_free(ctgz); return 0; } if (ctgz[2] != 8 || (ctgz[3] & 0xe0) != 0) { pool_error(pool, -1, "%s: control.tar.gz is compressed in a strange way", deb); solv_free(ctgz); return 0; } bp = ctgz + 4; bp += 6; /* skip time, xflags and OS code */ if (ctgz[3] & 0x04) { /* skip extra field */ l = bp[0] | bp[1] << 8; bp += l + 2; if (bp >= ctgz + clen) { pool_error(pool, -1, "%s: control.tar.gz is corrupt", deb); solv_free(ctgz); return 0; } } if (ctgz[3] & 0x08) /* orig filename */ while (*bp) bp++; if (ctgz[3] & 0x10) /* file comment */ while (*bp) bp++; if (ctgz[3] & 0x02) /* header crc */ bp += 2; if (bp >= ctgz + clen) { pool_error(pool, -1, "%s: control.tar.gz is corrupt", deb); solv_free(ctgz); return 0; } ctar = decompress(bp, ctgz + clen - bp, &ctarlen); solv_free(ctgz); if (!ctar) { pool_error(pool, -1, "%s: control.tar.gz is corrupt", deb); return 0; } bp = ctar; l = ctarlen; while (l > 512) { int j; l2 = 0; for (j = 124; j < 124 + 12; j++) if (bp[j] >= '0' && bp[j] <= '7') l2 = l2 * 8 + (bp[j] - '0'); if (!strcmp((char *)bp, "./control") || !strcmp((char *)bp, "control")) break; l2 = 512 + ((l2 + 511) & ~511); l -= l2; bp += l2; } if (l <= 512 || l - 512 - l2 <= 0 || l2 <= 0) { pool_error(pool, -1, "%s: control.tar.gz contains no control file", deb); free(ctar); return 0; } memmove(ctar, bp + 512, l2); ctar = solv_realloc(ctar, l2 + 1); ctar[l2] = 0; s = pool_id2solvable(pool, repo_add_solvable(repo)); control2solvable(s, data, (char *)ctar); if (!(flags & REPO_NO_LOCATION)) repodata_set_location(data, s - pool->solvables, 0, 0, deb); if (S_ISREG(stb.st_mode)) repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size); if (gotpkgid) repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid); solv_free(ctar); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return s - pool->solvables; }
Id repo_add_arch_pkg(Repo *repo, const char *fn, int flags) { Pool *pool = repo->pool; Repodata *data; FILE *fp; struct tarhead th; char line[4096]; int ignoreline; Solvable *s; int l, fd; struct stat stb; void *pkgidhandle = 0; data = repo_add_repodata(repo, flags); if ((fd = open(flags & REPO_USE_ROOTDIR ? pool_prepend_rootdir_tmp(pool, fn) : fn, O_RDONLY, 0)) < 0) { pool_error(pool, -1, "%s: %s", fn, strerror(errno)); return 0; } if (fstat(fd, &stb)) { pool_error(pool, -1, "%s: fstat: %s", fn, strerror(errno)); close(fd); return 0; } if (!(fp = solv_xfopen_fd(fn, fd, "r"))) { pool_error(pool, -1, "%s: fdopen failed", fn); close(fd); return 0; } s = 0; inittarhead(&th, fp); while (gettarhead(&th) > 0) { if (th.type != 1 || strcmp(th.path, ".PKGINFO") != 0) { skipentry(&th); continue; } ignoreline = 0; s = pool_id2solvable(pool, repo_add_solvable(repo)); if (flags & ARCH_ADD_WITH_PKGID) pkgidhandle = solv_chksum_create(REPOKEY_TYPE_MD5); while (getsentry(&th, line, sizeof(line))) { l = strlen(line); if (l == 0) continue; if (pkgidhandle) solv_chksum_add(pkgidhandle, line, l); if (line[l - 1] != '\n') { ignoreline = 1; continue; } if (ignoreline) { ignoreline = 0; continue; } line[--l] = 0; if (l == 0 || line[0] == '#') continue; if (!strncmp(line, "pkgname = ", 10)) s->name = pool_str2id(pool, line + 10, 1); else if (!strncmp(line, "pkgver = ", 9)) s->evr = pool_str2id(pool, line + 9, 1); else if (!strncmp(line, "pkgdesc = ", 10)) { repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line + 10); repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line + 10); } else if (!strncmp(line, "url = ", 6)) repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line + 6); else if (!strncmp(line, "builddate = ", 12)) repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line + 12, 0, 10)); else if (!strncmp(line, "packager = ", 11)) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line + 11); else if (!strncmp(line, "size = ", 7)) repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line + 7, 0, 10)); else if (!strncmp(line, "arch = ", 7)) s->arch = pool_str2id(pool, line + 7, 1); else if (!strncmp(line, "license = ", 10)) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_LICENSE, line + 10); else if (!strncmp(line, "replaces = ", 11)) s->obsoletes = adddep(repo, s->obsoletes, line + 11); else if (!strncmp(line, "group = ", 8)) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line + 8); else if (!strncmp(line, "depend = ", 9)) s->requires = adddep(repo, s->requires, line + 9); else if (!strncmp(line, "optdepend = ", 12)) { char *p = strchr(line, ':'); if (p) *p = 0; s->suggests = adddep(repo, s->suggests, line + 12); } else if (!strncmp(line, "conflict = ", 11)) s->conflicts = adddep(repo, s->conflicts, line + 11); else if (!strncmp(line, "provides = ", 11)) s->provides = adddep(repo, s->provides, line + 11); } break; } freetarhead(&th); fclose(fp); if (!s) { pool_error(pool, -1, "%s: not an arch package", fn); if (pkgidhandle) solv_chksum_free(pkgidhandle, 0); return 0; } if (s && !s->name) { pool_error(pool, -1, "%s: package has no name", fn); repo_free_solvable(repo, s - pool->solvables, 1); s = 0; } if (s) { if (!s->arch) s->arch = ARCH_ANY; if (!s->evr) s->evr = ID_EMPTY; s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); if (!(flags & REPO_NO_LOCATION)) repodata_set_location(data, s - pool->solvables, 0, 0, fn); if (S_ISREG(stb.st_mode)) repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size); if (pkgidhandle) { unsigned char pkgid[16]; solv_chksum_free(pkgidhandle, pkgid); repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid); pkgidhandle = 0; } } if (pkgidhandle) solv_chksum_free(pkgidhandle, 0); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return s ? s - pool->solvables : 0; }