static void log_cb(Pool *pool, void *cb_data, int level, const char *buf) { HySack sack = cb_data; if (sack->log_out == NULL) { const char *fn = pool_tmpjoin(pool, sack->cache_dir, "/hawkey.log", NULL); sack->log_out = fopen(fn, "a"); if (sack->log_out) HY_LOG_INFO("Started hawkey-%d.%d.%d.", HY_VERSION_MAJOR, HY_VERSION_MINOR, HY_VERSION_PATCH); } if (!sack->log_out) return; time_t t = time(NULL); struct tm tm; char timestr[26]; localtime_r(&t, &tm); strftime(timestr, 26, "%b-%d %H:%M:%S ", &tm); const char *pref = pool_tmpjoin(pool, ll_name(level), " ", timestr); pref = pool_tmpjoin(pool, pref, buf, NULL); fwrite(pref, strlen(pref), 1, sack->log_out); fflush(sack->log_out); }
END_TEST START_TEST(test_two_sacks) { /* This clumsily mimics create_ut_sack() and setup_with() to * create a second HySack. */ char *tmpdir = solv_dupjoin(test_globals.tmpdir, "/tmp", NULL); HySack sack1 = hy_sack_create(tmpdir, TEST_FIXED_ARCH, NULL, NULL, HY_MAKE_CACHE_DIR); Pool *pool1 = sack_pool(sack1); const char *path = pool_tmpjoin(pool1, test_globals.repo_dir, "change.repo", NULL); fail_if(load_repo(pool1, "change", path, 0)); HyPackage pkg1 = by_name(sack1, "penny-lib"); fail_if(pkg1 == NULL); HySack sack2 = test_globals.sack; Pool *pool2 = sack_pool(sack2); HyPackage pkg2 = by_name(sack2, "penny-lib"); fail_if(pkg2 == NULL); /* "penny-lib" is in both pools but at different offsets */ Solvable *s1 = pool_id2solvable(pool1, pkg1->id); Solvable *s2 = pool_id2solvable(pool2, pkg2->id); fail_if(s1->name == s2->name); fail_if(hy_package_cmp(pkg1, pkg2) != 0); hy_package_free(pkg1); hy_package_free(pkg2); hy_sack_free(sack1); solv_free(tmpdir); }
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; } }
static void add_cmdline(HySack sack) { Pool *pool = sack_pool(sack); const char *path = pool_tmpjoin(pool, test_globals.repo_dir, "yum/tour-4-6.noarch.rpm", NULL); HyPackage pkg = hy_sack_add_cmdline_package(sack, path); hy_package_free(pkg); }
HyRepo glob_for_repofiles(Pool *pool, const char *repo_name, const char *path) { HyRepo repo = hy_repo_create(repo_name); const char *tmpl; wordexp_t word_vector; tmpl = pool_tmpjoin(pool, path, "/repomd.xml", NULL); if (wordexp(tmpl, &word_vector, 0) || word_vector.we_wordc < 1) goto fail; hy_repo_set_string(repo, HY_REPO_MD_FN, word_vector.we_wordv[0]); tmpl = pool_tmpjoin(pool, path, "/*primary.xml.gz", NULL); if (wordexp(tmpl, &word_vector, WRDE_REUSE) || word_vector.we_wordc < 1) goto fail; hy_repo_set_string(repo, HY_REPO_PRIMARY_FN, word_vector.we_wordv[0]); tmpl = pool_tmpjoin(pool, path, "/*filelists.xml.gz", NULL); if (wordexp(tmpl, &word_vector, WRDE_REUSE) || word_vector.we_wordc < 1) goto fail; hy_repo_set_string(repo, HY_REPO_FILELISTS_FN, word_vector.we_wordv[0]); tmpl = pool_tmpjoin(pool, path, "/*prestodelta.xml.gz", NULL); if (wordexp(tmpl, &word_vector, WRDE_REUSE) || word_vector.we_wordc < 1) goto fail; hy_repo_set_string(repo, HY_REPO_PRESTO_FN, word_vector.we_wordv[0]); tmpl = pool_tmpjoin(pool, path, "/*updateinfo.xml.gz", NULL); if (wordexp(tmpl, &word_vector, WRDE_REUSE) || word_vector.we_wordc < 1) goto fail; hy_repo_set_string(repo, HY_REPO_UPDATEINFO_FN, word_vector.we_wordv[0]); wordfree(&word_vector); return repo; fail: wordfree(&word_vector); hy_repo_free(repo); return NULL; }
int susetags_load_ext(Repo *repo, Repodata *data) { const char *filename, *descrdir; Id defvendor; char ext[3]; FILE *fp; struct repoinfo *cinfo; const unsigned char *filechksum; Id filechksumtype; int flags; cinfo = repo->appdata; filename = repodata_lookup_str(data, SOLVID_META, SUSETAGS_FILE_NAME); if (!filename) return 0; /* susetags load */ ext[0] = filename[9]; ext[1] = filename[10]; ext[2] = 0; printf("[%s:%s", repo->name, ext); if (usecachedrepo(cinfo, ext, 0)) { printf(" cached]\n"); fflush(stdout); return 1; } printf(" fetching]\n"); fflush(stdout); defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR); descrdir = repo_lookup_str(repo, SOLVID_META, SUSETAGS_DESCRDIR); if (!descrdir) descrdir = "suse/setup/descr"; filechksumtype = 0; filechksum = repodata_lookup_bin_checksum(data, SOLVID_META, SUSETAGS_FILE_CHECKSUM, &filechksumtype); if ((fp = curlfopen(cinfo, pool_tmpjoin(repo->pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 0)) == 0) return 0; flags = REPO_USE_LOADING|REPO_EXTEND_SOLVABLES; if (strcmp(ext, "DL") != 0) flags |= REPO_LOCALPOOL; if (repo_add_susetags(repo, fp, defvendor, ext, flags)) { fclose(fp); printf("%s\n", pool_errstr(repo->pool)); return 0; } fclose(fp); writecachedrepo(cinfo, ext, data); return 1; }
void setup_yum_sack(HySack sack, const char *yum_repo_name) { Pool *pool = sack_pool(sack); const char *repo_path = pool_tmpjoin(pool, test_globals.repo_dir, YUM_DIR_SUFFIX, NULL); fail_if(access(repo_path, X_OK)); HyRepo repo = glob_for_repofiles(pool, yum_repo_name, repo_path); fail_if(hy_sack_load_repo(sack, repo, HY_BUILD_CACHE | HY_LOAD_FILELISTS | HY_LOAD_UPDATEINFO | HY_LOAD_PRESTO)); fail_unless(hy_sack_count(sack) == TEST_EXPECT_YUM_NSOLVABLES); hy_repo_free(repo); }
FILE * downloadpackage(Solvable *s, const char *loc) { const unsigned char *chksum; Id chksumtype; struct repoinfo *cinfo = s->repo->appdata; #ifdef ENABLE_SUSEREPO if (cinfo->type == TYPE_SUSETAGS) { const char *datadir = repo_lookup_str(cinfo->repo, SOLVID_META, SUSETAGS_DATADIR); loc = pool_tmpjoin(s->repo->pool, datadir ? datadir : "suse", "/", loc); } #endif chksumtype = 0; chksum = solvable_lookup_bin_checksum(s, SOLVABLE_CHECKSUM, &chksumtype); return curlfopen(cinfo, loc, 0, chksum, chksumtype, 0); }
static const char * solvable_lookup_str_joinarray(Solvable *s, Id keyname, const char *joinstr) { Queue q; Id qbuf[10]; char *str = 0; queue_init_buffer(&q, qbuf, sizeof(qbuf)/sizeof(*qbuf)); if (solvable_lookup_idarray(s, keyname, &q) && q.count) { Pool *pool = s->repo->pool; int i; str = pool_tmpjoin(pool, pool_id2str(pool, q.elements[0]), 0, 0); for (i = 1; i < q.count; i++) str = pool_tmpappend(pool, str, joinstr, pool_id2str(pool, q.elements[i])); } queue_free(&q); return str; }
static int setup_with(HySack sack, ...) { Pool *pool = sack_pool(sack); va_list names; int ret = 0; va_start(names, sack); const char *name = va_arg(names, const char *); while (name) { const char *path = pool_tmpjoin(pool, test_globals.repo_dir, name, ".repo"); int installed = !strncmp(name, HY_SYSTEM_REPO_NAME, strlen(HY_SYSTEM_REPO_NAME)); ret |= load_repo(pool, name, path, installed); name = va_arg(names, const char *); } va_end(names); return ret; }
/* add all files ending in .appdata.xml */ int repo_add_appdata_dir(Repo *repo, const char *appdatadir, int flags) { DIR *dir; char *dirpath; Repodata *data; data = repo_add_repodata(repo, flags); if (flags & REPO_USE_ROOTDIR) dirpath = pool_prepend_rootdir(repo->pool, appdatadir); else dirpath = solv_strdup(appdatadir); if ((dir = opendir(dirpath)) != 0) { struct dirent *entry; while ((entry = readdir(dir))) { const char *n; FILE *fp; int len = strlen(entry->d_name); if (len <= 12 || strcmp(entry->d_name + len - 12, ".appdata.xml") != 0) continue; if (entry->d_name[0] == '.') continue; n = pool_tmpjoin(repo->pool, dirpath, "/", entry->d_name); fp = fopen(n, "r"); if (!fp) { pool_error(repo->pool, 0, "%s: %s", n, strerror(errno)); continue; } repo_add_appdata(repo, fp, flags | REPO_NO_INTERNALIZE | REPO_REUSE_REPODATA); fclose(fp); } } if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return 0; }
int repo_add_mdk(Repo *repo, FILE *fp, int flags) { Pool *pool = repo->pool; Repodata *data; Solvable *s; char *buf; int bufa, bufl; data = repo_add_repodata(repo, flags); bufa = 4096; buf = solv_malloc(bufa); bufl = 0; s = 0; while (fgets(buf + bufl, bufa - bufl, fp) > 0) { bufl += strlen(buf + bufl); if (bufl && buf[bufl - 1] != '\n') { if (bufa - bufl < 256) { bufa += 4096; buf = solv_realloc(buf, bufa); } continue; } buf[--bufl] = 0; bufl = 0; if (buf[0] != '@') { pool_debug(pool, SOLV_ERROR, "bad line <%s>\n", buf); continue; } if (!s) s = pool_id2solvable(pool, repo_add_solvable(repo)); if (!strncmp(buf + 1, "filesize@", 9)) repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, strtoull(buf + 10, 0, 10)); else if (!strncmp(buf + 1, "summary@", 8)) repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, buf + 9); else if (!strncmp(buf + 1, "provides@", 9)) s->provides = parse_deps(s, buf + 10, 0); else if (!strncmp(buf + 1, "requires@", 9)) s->requires = parse_deps(s, buf + 10, SOLVABLE_PREREQMARKER); else if (!strncmp(buf + 1, "suggests@", 9)) s->suggests = parse_deps(s, buf + 10, 0); else if (!strncmp(buf + 1, "obsoletes@", 10)) s->obsoletes = parse_deps(s, buf + 11, 0); else if (!strncmp(buf + 1, "conflicts@", 10)) s->conflicts = parse_deps(s, buf + 11, 0); else if (!strncmp(buf + 1, "info@", 5)) { char *nvra = buf + 6; char *epochstr; char *arch; char *version; char *filename; if ((epochstr = strchr(nvra, '@')) != 0) { char *sizestr; *epochstr++ = 0; if ((sizestr = strchr(epochstr, '@')) != 0) { char *groupstr; *sizestr++ = 0; if ((groupstr = strchr(sizestr, '@')) != 0) { char *n; *groupstr++ = 0; if ((n = strchr(groupstr, '@')) != 0) *n = 0; if (*groupstr) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, groupstr); } repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(sizestr, 0, 10)); } } filename = pool_tmpjoin(pool, nvra, ".rpm", 0); arch = strrchr(nvra, '.'); if (arch) { *arch++ = 0; s->arch = pool_str2id(pool, arch, 1); } /* argh, do we have a distepoch or not, check self-provides */ if (s->provides) { Id id, lastid, *idp = s->repo->idarraydata + s->provides; lastid = 0; for (idp = s->repo->idarraydata + s->provides; (id = *idp) != 0; idp++) { const char *evr, *name; int namel; Reldep *rd; if (!ISRELDEP(id)) continue; rd = GETRELDEP(pool, id); if (rd->flags != REL_EQ) continue; name = pool_id2str(pool, rd->name); namel = strlen(name); if (strncmp(name, nvra, namel) != 0 || nvra[namel] != '-') continue; evr = pool_id2str(pool, rd->evr); evr = strrchr(evr, '-'); if (evr && strchr(evr, ':') != 0) lastid = id; } if (lastid) { /* self provides found, and it contains a distepoch */ /* replace with self-provides distepoch to get rid of the disttag */ char *nvradistepoch = strrchr(nvra, '-'); if (nvradistepoch) { Reldep *rd = GETRELDEP(pool, lastid); const char *evr = pool_id2str(pool, rd->evr); evr = strrchr(evr, '-'); if (evr && (evr = strchr(evr, ':')) != 0) { if (strlen(evr) < strlen(nvradistepoch)) strcpy(nvradistepoch, evr); } } } } version = strrchr(nvra, '-'); if (version) { char *release = version; *release = 0; version = strrchr(nvra, '-'); *release = '-'; if (!version) version = release; *version++ = 0; } else version = ""; s->name = pool_str2id(pool, nvra, 1); if (epochstr && *epochstr && strcmp(epochstr, "0") != 0) { char *evr = pool_tmpjoin(pool, epochstr, ":", version); s->evr = pool_str2id(pool, evr, 1); } else s->evr = pool_str2id(pool, version, 1); repodata_set_location(data, s - pool->solvables, 0, 0, filename); if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(s->repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); s = 0; } else { char *tagend = strchr(buf + 1, '@'); if (tagend) *tagend = 0; pool_debug(pool, SOLV_ERROR, "unknown tag <%s>\n", buf + 1); continue; } } if (s) { pool_debug(pool, SOLV_ERROR, "unclosed package at EOF\n"); repo_free_solvable(s->repo, s - pool->solvables, 1); } solv_free(buf); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); return 0; }
int susetags_load(struct repoinfo *cinfo, Pool **sigpoolp) { Repo *repo = cinfo->repo; Pool *pool = repo->pool; Repodata *data; const char *filename; const unsigned char *filechksum; Id filechksumtype; FILE *fp; const char *descrdir; int defvendor; printf("susetags repo '%s':", cinfo->alias); fflush(stdout); descrdir = 0; defvendor = 0; if ((fp = curlfopen(cinfo, "content", 0, 0, 0, 0)) == 0) { printf(" no content file\n"); cinfo->incomplete = 1; return 0; } calc_cookie_fp(fp, REPOKEY_TYPE_SHA256, cinfo->cookie); cinfo->cookieset = 1; if (usecachedrepo(cinfo, 0, 1)) { printf(" cached\n"); fclose(fp); return 1; } if (cinfo->repo_gpgcheck && !downloadchecksig(cinfo, fp, "content.asc", sigpoolp)) { fclose(fp); cinfo->incomplete = 1; return 0; } if (repo_add_content(repo, fp, 0)) { printf("content: %s\n", pool_errstr(pool)); fclose(fp); cinfo->incomplete = 1; return 0; } fclose(fp); defvendor = repo_lookup_id(repo, SOLVID_META, SUSETAGS_DEFAULTVENDOR); descrdir = repo_lookup_str(repo, SOLVID_META, SUSETAGS_DESCRDIR); if (!descrdir) descrdir = "suse/setup/descr"; filename = susetags_find(repo, "packages.gz", &filechksum, &filechksumtype); if (!filename) filename = susetags_find(repo, "packages", &filechksum, &filechksumtype); if (!filename) { printf(" no packages file entry, skipped\n"); cinfo->incomplete = 1; return 0; } printf(" fetching\n"); if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) == 0) { cinfo->incomplete = 1; return 0; /* hopeless */ } if (repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|SUSETAGS_RECORD_SHARES)) { printf("packages: %s\n", pool_errstr(pool)); fclose(fp); cinfo->incomplete = 1; return 0; /* hopeless */ } fclose(fp); /* add default language */ filename = susetags_find(repo, "packages.en.gz", &filechksum, &filechksumtype); if (!filename) filename = susetags_find(repo, "packages.en", &filechksum, &filechksumtype); if (filename) { if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0) { if (repo_add_susetags(repo, fp, defvendor, 0, REPO_NO_INTERNALIZE|REPO_REUSE_REPODATA|REPO_EXTEND_SOLVABLES)) { printf("packages.en: %s\n", pool_errstr(pool)); cinfo->incomplete = 1; } fclose(fp); } } filename = susetags_find(repo, "patterns", &filechksum, &filechksumtype); if (filename) { if ((fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0) { char pbuf[256]; while (fgets(pbuf, sizeof(pbuf), fp)) { int l = strlen(pbuf); FILE *fp2; if (l && pbuf[l - 1] == '\n') pbuf[--l] = 0; if (!*pbuf || *pbuf == '.' || strchr(pbuf, '/') != 0) continue; filename = susetags_find(repo, pbuf, &filechksum, &filechksumtype); if (filename && (fp2 = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0) { if (repo_add_susetags(repo, fp2, defvendor, 0, REPO_NO_INTERNALIZE)) { printf("%s: %s\n", pbuf, pool_errstr(pool)); cinfo->incomplete = 1; } fclose(fp2); } } fclose(fp); } } #ifdef ENABLE_APPDATA filename = susetags_find(repo, "appdata.xml.gz", &filechksum, &filechksumtype); if (!filename) filename = susetags_find(repo, "appdata.xml", &filechksum, &filechksumtype); if (filename && (fp = curlfopen(cinfo, pool_tmpjoin(pool, descrdir, "/", filename), 1, filechksum, filechksumtype, 1)) != 0) { if (repo_add_appdata(repo, fp, 0)) { printf("appdata: %s\n", pool_errstr(pool)); cinfo->incomplete = 1; } fclose(fp); } #endif repo_internalize(repo); #ifdef SUSE repo_add_autopattern(repo, 0); #endif data = repo_add_repodata(repo, 0); repodata_extend_block(data, repo->start, repo->end - repo->start); susetags_add_ext(repo, data); repodata_internalize(data); writecachedrepo(cinfo, 0, 0); repodata_create_stubs(repo_last_repodata(repo)); return 1; }
static void XMLCALL endElement(void *userData, const char *name) { struct parsedata *pd = userData; Pool *pool = pd->pool; Solvable *s = pd->solvable; Id id; #if 0 fprintf(stderr, "end: [%d]%s\n", pd->state, name); #endif if (pd->depth != pd->statedepth) { pd->depth--; #if 0 fprintf(stderr, "back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); #endif return; } pd->depth--; pd->statedepth--; switch (pd->state) { case STATE_APPLICATION: if (!s->arch) s->arch = ARCH_NOARCH; if (!s->evr) s->evr = ID_EMPTY; if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(pd->repo, s->provides, pool_rel2id(pd->pool, s->name, s->evr, REL_EQ, 1), 0); pd->solvable = 0; break; case STATE_ID: if (pd->lcontent > 8 && !strcmp(".desktop", pd->content + pd->lcontent - 8)) pd->content[pd->lcontent - 8] = 0; id = pool_str2id(pd->pool, pool_tmpjoin(pool, "appdata(", pd->content, ")"), 1); s->requires = repo_addid_dep(pd->repo, s->requires, id, 0); id = pool_str2id(pd->pool, pool_tmpjoin(pool, "application-appdata(", pd->content, ")"), 1); s->provides = repo_addid_dep(pd->repo, s->provides, id, 0); break; case STATE_NAME: s->name = pool_str2id(pd->pool, pool_tmpjoin(pool, "application:", pd->content, 0), 1); break; case STATE_LICENCE: repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_LICENSE, pd->content); break; case STATE_SUMMARY: repodata_set_str(pd->data, pd->handle, SOLVABLE_SUMMARY, pd->content); break; case STATE_URL: repodata_set_str(pd->data, pd->handle, SOLVABLE_URL, pd->content); break; case STATE_GROUP: repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_GROUP, pd->content); break; case STATE_DESCRIPTION: if (pd->description) { /* strip trailing newlines */ int l = strlen(pd->description); while (l && pd->description[l - 1] == '\n') pd->description[--l] = 0; repodata_set_str(pd->data, pd->handle, SOLVABLE_DESCRIPTION, pd->description); } break; case STATE_P: wsstrip(pd); pd->description = solv_dupappend(pd->description, pd->content, "\n\n"); break; case STATE_UL_LI: wsstrip(pd); indent(pd, 4); pd->content[2] = '-'; pd->description = solv_dupappend(pd->description, pd->content, "\n"); break; case STATE_OL_LI: wsstrip(pd); indent(pd, 4); if (++pd->licnt >= 10) pd->content[0] = '0' + (pd->licnt / 10) % 10; pd->content[1] = '0' + pd->licnt % 10; pd->content[2] = '.'; pd->description = solv_dupappend(pd->description, pd->content, "\n"); break; case STATE_UL: case STATE_OL: pd->description = solv_dupappend(pd->description, "\n", 0); break; default: break; } pd->state = pd->sbtab[pd->state]; pd->docontent = 0; #if 0 fprintf(stderr, "end: [%s] -> %d\n", name, pd->state); #endif }
int repo_add_autopattern(Repo *repo, int flags) { Pool *pool = repo->pool; Repodata *data = 0; Solvable *s, *s2; Queue patq, patq2; Queue prdq, prdq2; Id p; Id pattern_id, product_id; Id autopattern_id = 0, autoproduct_id = 0; int i, j; queue_init(&patq); queue_init(&patq2); queue_init(&prdq); queue_init(&prdq2); pattern_id = pool_str2id(pool, "pattern()", 9); product_id = pool_str2id(pool, "product()", 9); FOR_REPO_SOLVABLES(repo, p, s) { const char *n = pool_id2str(pool, s->name); if (*n == 'p') { if (!strncmp("pattern:", n, 8)) { queue_push(&patq, p); continue; } else if (!strncmp("product:", n, 8)) { queue_push(&prdq, p); continue; } } if (s->provides) { Id prv, *prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); if (rd->flags != REL_EQ) continue; if (rd->name == pattern_id) { queue_push2(&patq2, p, rd->evr); break; } if (rd->name == product_id) { queue_push2(&prdq2, p, rd->evr); break; } } } } for (i = 0; i < patq2.count; i += 2) { const char *pn = 0; char *newname; Id name, prv, *prvp; const char *str; unsigned long long num; s = pool->solvables + patq2.elements[i]; /* construct new name */ newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, patq2.elements[i + 1]), 0); unescape(newname); name = pool_str2id(pool, newname, 0); if (name) { /* check if we already have that pattern */ for (j = 0; j < patq.count; j++) { s2 = pool->solvables + patq.elements[j]; if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr) break; } if (j < patq.count) continue; /* yes, do not add again */ } /* new pattern */ if (!name) name = pool_str2id(pool, newname, 1); if (!data) { repo_internalize(repo); /* to make that the lookups work */ data = repo_add_repodata(repo, flags); } s2 = pool_id2solvable(pool, repo_add_solvable(repo)); s = pool->solvables + patq2.elements[i]; /* re-calc pointer */ s2->name = name; s2->arch = s->arch; s2->evr = s->evr; s2->vendor = s->vendor; /* add link requires */ s2->requires = repo_addid_dep(repo, s2->requires, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1) , 0); /* add autopattern provides */ if (!autopattern_id) autopattern_id = pool_str2id(pool, "autopattern()", 1); s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autopattern_id, s->name, REL_EQ, 1), 0); /* add self provides */ s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0); if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0) repodata_set_num(data, s2 - pool->solvables, SOLVABLE_INSTALLTIME, num); if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0) repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num); if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str); if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str); /* fill in stuff from provides */ prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ { Id evr = 0; if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); if (rd->flags != REL_EQ) continue; prv = rd->name; evr = rd->evr; } pn = pool_id2str(pool, prv); if (strncmp("pattern-", pn, 8) != 0) continue; newname = 0; if (evr) { newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0); unescape(newname); } if (!strncmp(pn, "pattern-category(", 17) && evr) { char lang[9]; int l = strlen(pn); Id langtag; if (l > 17 + 9 || pn[l - 1] != ')') continue; strncpy(lang, pn + 17, l - 17 - 1); lang[l - 17 - 1] = 0; langtag = SOLVABLE_CATEGORY; if (*lang && strcmp(lang, "en") != 0) langtag = pool_id2langid(pool, SOLVABLE_CATEGORY, lang, 1); if (newname[solv_validutf8(newname)] == 0) repodata_set_str(data, s2 - pool->solvables, langtag, newname); else { char *ustr = solv_latin1toutf8(newname); repodata_set_str(data, s2 - pool->solvables, langtag, ustr); solv_free(ustr); } } else if (!strcmp(pn, "pattern-includes()") && evr) repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_INCLUDES, pool_tmpjoin(pool, "pattern:", newname, 0)); else if (!strcmp(pn, "pattern-extends()") && evr) repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_EXTENDS, pool_tmpjoin(pool, "pattern:", newname, 0)); else if (!strcmp(pn, "pattern-icon()") && evr) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ICON, newname); else if (!strcmp(pn, "pattern-order()") && evr) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ORDER, newname); else if (!strcmp(pn, "pattern-visible()") && !evr) repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE); } } queue_free(&patq); queue_free(&patq2); if (repo == pool->installed) queue_empty(&prdq2); /* no auto products for installed repos */ for (i = 0; i < prdq2.count; i += 2) { const char *pn = 0; char *newname; Id name, evr = 0, prv, *prvp; const char *str; unsigned long long num; s = pool->solvables + prdq2.elements[i]; /* construct new name */ newname = pool_tmpjoin(pool, "product(", pool_id2str(pool, prdq2.elements[i + 1]), ")"); unescape(newname); name = pool_str2id(pool, newname, 0); if (!name) continue; /* must have it in provides! */ prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ { if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); if (rd->name == name && rd->flags == REL_EQ) { evr = rd->evr; break; } } } if (!prv) continue; /* not found in provides */ newname = pool_tmpjoin(pool, "product:", pool_id2str(pool, prdq2.elements[i + 1]), 0); unescape(newname); name = pool_str2id(pool, newname, 0); if (name) { /* check if we already have that product */ for (j = 0; j < prdq.count; j++) { s2 = pool->solvables + prdq.elements[j]; if (s2->name == name && s2->arch == s->arch && s2->evr == evr) break; } if (j < prdq.count) continue; /* yes, do not add again */ } /* new product */ if (!name) name = pool_str2id(pool, newname, 1); if (!data) { repo_internalize(repo); /* to make that the lookups work */ data = repo_add_repodata(repo, flags); } if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0) continue; /* eek, not for installed packages, please! */ s2 = pool_id2solvable(pool, repo_add_solvable(repo)); s = pool->solvables + prdq2.elements[i]; /* re-calc pointer */ s2->name = name; s2->arch = s->arch; s2->evr = evr; s2->vendor = s->vendor; /* add link requires */ s2->requires = repo_addid_dep(repo, s2->requires, prv, 0); if (!autoproduct_id) autoproduct_id = pool_str2id(pool, "autoproduct()", 1); s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autoproduct_id, s->name, REL_EQ, 1), 0); /* add self provides */ s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0); if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0) repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num); if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str); if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str); if ((str = solvable_lookup_str(s, SOLVABLE_DISTRIBUTION)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DISTRIBUTION, str); /* fill in stuff from provides */ prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ { Id evr = 0; if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); if (rd->flags != REL_EQ) continue; prv = rd->name; evr = rd->evr; } pn = pool_id2str(pool, prv); if (strncmp("product-", pn, 8) != 0) continue; newname = 0; if (evr) { newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0); unescape(newname); } if (!strcmp(pn, "product-label()") && evr) repodata_set_str(data, s2 - pool->solvables, PRODUCT_SHORTLABEL, newname); else if (!strcmp(pn, "product-type()") && evr) repodata_set_str(data, s2 - pool->solvables, PRODUCT_TYPE, newname); else if (!strcmp(pn, "product-cpeid()") && evr) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_CPEID, newname); else if (!strcmp(pn, "product-flags()") && evr) repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_FLAGS, newname); else if (!strcmp(pn, "product-updates-repoid()") && evr) repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_UPDATES_REPOID, newname); else if (!strncmp(pn, "product-url(", 12) && evr && pn[12] && pn[13] && strlen(pn + 12) < 32) { char type[34]; strcpy(type, pn + 12); type[strlen(type) - 1] = 0; /* closing ) */ repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL_TYPE, type); repodata_add_poolstr_array(data, s2 - pool->solvables, PRODUCT_URL, newname); } } } queue_free(&prdq); queue_free(&prdq2); if (data && !(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); else if (!data && !(flags & REPO_NO_INTERNALIZE)) repo_internalize(repo); return 0; }
int repo_add_autopattern(Repo *repo, int flags) { Pool *pool = repo->pool; Repodata *data = 0; Solvable *s, *s2; Queue q, q2; Id p; Id pattern_id; Id autopattern_id = 0; int i, j; queue_init(&q); queue_init(&q2); pattern_id = pool_str2id(pool, "pattern()", 9); FOR_REPO_SOLVABLES(repo, p, s) { const char *n = pool_id2str(pool, s->name); if (!strncmp("pattern:", n, 8)) queue_push(&q, p); else if (s->provides) { Id prv, *prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); if (rd->name == pattern_id && rd->flags == REL_EQ) { queue_push2(&q2, p, rd->evr); break; } } } } for (i = 0; i < q2.count; i += 2) { const char *pn = 0; char *newname; Id name, prv, *prvp; const char *str; unsigned long long num; s = pool->solvables + q2.elements[i]; /* construct new name */ newname = pool_tmpjoin(pool, "pattern:", pool_id2str(pool, q2.elements[i + 1]), 0); unescape(newname); name = pool_str2id(pool, newname, 0); if (name) { /* check if we already have that pattern */ for (j = 0; j < q.count; j++) { s2 = pool->solvables + q.elements[j]; if (s2->name == name && s2->arch == s->arch && s2->evr == s->evr) break; } if (j < q.count) continue; /* yes, do not add again */ } /* new pattern */ if (!name) name = pool_str2id(pool, newname, 1); if (!data) { repo_internalize(repo); /* to make that the lookups work */ data = repo_add_repodata(repo, flags); } s2 = pool_id2solvable(pool, repo_add_solvable(repo)); s = pool->solvables + q2.elements[i]; /* re-calc pointer */ s2->name = name; s2->arch = s->arch; s2->evr = s->evr; s2->vendor = s->vendor; /* add link requires */ s2->requires = repo_addid_dep(repo, s2->requires, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1) , 0); /* add autopattern provides */ if (!autopattern_id) autopattern_id = pool_str2id(pool, "autopattern()", 1); s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, autopattern_id, s->name, REL_EQ, 1), 0); /* add self provides */ s2->provides = repo_addid_dep(repo, s2->provides, pool_rel2id(pool, s2->name, s2->evr, REL_EQ, 1), 0); if ((num = solvable_lookup_num(s, SOLVABLE_INSTALLTIME, 0)) != 0) repodata_set_num(data, s2 - pool->solvables, SOLVABLE_INSTALLTIME, num); if ((num = solvable_lookup_num(s, SOLVABLE_BUILDTIME, 0)) != 0) repodata_set_num(data, s2 - pool->solvables, SOLVABLE_BUILDTIME, num); if ((str = solvable_lookup_str(s, SOLVABLE_SUMMARY)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_SUMMARY, str); if ((str = solvable_lookup_str(s, SOLVABLE_DESCRIPTION)) != 0) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_DESCRIPTION, str); /* fill in stuff from provides */ prvp = repo->idarraydata + s->provides; while ((prv = *prvp++) != 0) /* go through all provides */ { Id evr = 0; if (ISRELDEP(prv)) { Reldep *rd = GETRELDEP(pool, prv); if (rd->flags != REL_EQ) continue; prv = rd->name; evr = rd->evr; } pn = pool_id2str(pool, prv); if (strncmp("pattern-", pn, 8) != 0) continue; newname = 0; if (evr) { newname = pool_tmpjoin(pool, pool_id2str(pool, evr), 0, 0); unescape(newname); } if (!strncmp(pn, "pattern-category(", 17) && evr) { char lang[9]; int l = strlen(pn); Id langtag; if (l > 17 + 9 || pn[l - 1] != ')') continue; strncpy(lang, pn + 17, l - 17 - 1); lang[l - 17 - 1] = 0; langtag = SOLVABLE_CATEGORY; if (*lang && strcmp(lang, "en") != 0) langtag = pool_id2langid(pool, SOLVABLE_CATEGORY, lang, 1); repodata_set_str(data, s2 - pool->solvables, langtag, newname); } else if (!strcmp(pn, "pattern-includes()") && evr) repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_INCLUDES, pool_tmpjoin(pool, "pattern:", newname, 0)); else if (!strcmp(pn, "pattern-extends()") && evr) repodata_add_poolstr_array(data, s2 - pool->solvables, SOLVABLE_EXTENDS, pool_tmpjoin(pool, "pattern:", newname, 0)); else if (!strcmp(pn, "pattern-icon()") && evr) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ICON, newname); else if (!strcmp(pn, "pattern-order()") && evr) repodata_set_str(data, s2 - pool->solvables, SOLVABLE_ORDER, newname); else if (!strcmp(pn, "pattern-visible()") && !evr) repodata_set_void(data, s2 - pool->solvables, SOLVABLE_ISVISIBLE); } } queue_free(&q); queue_free(&q2); if (data && !(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); else if (!data && !(flags & REPO_NO_INTERNALIZE)) repo_internalize(repo); return 0; }
int checksig(Pool *sigpool, FILE *fp, FILE *sigfp) { char *gpgdir; char *keysfile; const char *pubkey; char cmd[256]; FILE *kfp; Solvable *s; Id p; off_t posfp, possigfp; int r, nkeys; gpgdir = mkdtemp(pool_tmpjoin(sigpool, "/var/tmp/solvgpg.XXXXXX", 0, 0)); if (!gpgdir) return 0; keysfile = pool_tmpjoin(sigpool, gpgdir, "/keys", 0); if (!(kfp = fopen(keysfile, "w")) ) { cleanupgpg(gpgdir); return 0; } nkeys = 0; for (p = 1, s = sigpool->solvables + p; p < sigpool->nsolvables; p++, s++) { if (!s->repo) continue; pubkey = solvable_lookup_str(s, SOLVABLE_DESCRIPTION); if (!pubkey || !*pubkey) continue; if (fwrite(pubkey, strlen(pubkey), 1, kfp) != 1) break; if (fputc('\n', kfp) == EOF) /* Just in case... */ break; nkeys++; } if (fclose(kfp) || !nkeys || p < sigpool->nsolvables) { cleanupgpg(gpgdir); return 0; } snprintf(cmd, sizeof(cmd), "gpg2 -q --homedir %s --import %s", gpgdir, keysfile); if (system(cmd)) { fprintf(stderr, "key import error\n"); cleanupgpg(gpgdir); return 0; } unlink(keysfile); posfp = lseek(fileno(fp), 0, SEEK_CUR); lseek(fileno(fp), 0, SEEK_SET); possigfp = lseek(fileno(sigfp), 0, SEEK_CUR); lseek(fileno(sigfp), 0, SEEK_SET); snprintf(cmd, sizeof(cmd), "gpgv -q --homedir %s --keyring %s/pubring.gpg /dev/fd/%d /dev/fd/%d >/dev/null 2>&1", gpgdir, gpgdir, fileno(sigfp), fileno(fp)); fcntl(fileno(fp), F_SETFD, 0); /* clear CLOEXEC */ fcntl(fileno(sigfp), F_SETFD, 0); /* clear CLOEXEC */ r = system(cmd); lseek(fileno(sigfp), possigfp, SEEK_SET); lseek(fileno(fp), posfp, SEEK_SET); fcntl(fileno(fp), F_SETFD, FD_CLOEXEC); fcntl(fileno(sigfp), F_SETFD, FD_CLOEXEC); cleanupgpg(gpgdir); return r == 0 ? 1 : 0; }