static void add_multiple_urls(Repodata *data, Id handle, char *value, Id type) { char *url; while ((url = splitword(&value)) != 0) { repodata_add_poolstr_array(data, handle, PRODUCT_URL, url); repodata_add_idarray(data, handle, PRODUCT_URL_TYPE, type); } }
static void write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location) { Id h, *keyarray = 0; int i; repo_write(repo, fp, keyfilter, kfdata, &keyarray); h = repodata_new_handle(info); if (keyarray) { for (i = 0; keyarray[i]; i++) repodata_add_idarray(info, h, REPOSITORY_KEYS, keyarray[i]); } solv_free(keyarray); repodata_set_str(info, h, REPOSITORY_LOCATION, location); repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h); }
void repo_add_deparray(Repo *repo, Id p, Id keyname, Id dep, Id marker) { Repodata *data; if (p >= 0) { Solvable *s = repo->pool->solvables + p; switch (keyname) { case SOLVABLE_PROVIDES: s->provides = repo_addid_dep(repo, s->provides, dep, marker); return; case SOLVABLE_OBSOLETES: s->obsoletes = repo_addid_dep(repo, s->obsoletes, dep, marker); return; case SOLVABLE_CONFLICTS: s->conflicts = repo_addid_dep(repo, s->conflicts, dep, marker); return; case SOLVABLE_REQUIRES: s->requires = repo_addid_dep(repo, s->requires, dep, marker); return; case SOLVABLE_RECOMMENDS: s->recommends = repo_addid_dep(repo, s->recommends, dep, marker); return; case SOLVABLE_SUGGESTS: s->suggests = repo_addid_dep(repo, s->suggests, dep, marker); return; case SOLVABLE_SUPPLEMENTS: s->supplements = repo_addid_dep(repo, s->supplements, dep, marker); return; case SOLVABLE_ENHANCES: s->enhances = repo_addid_dep(repo, s->enhances, dep, marker); return; } } data = repo_last_repodata(repo); repodata_add_idarray(data, p, keyname, dep); }
static void XMLCALL endElement(void *userData, const char *name) { //fprintf(stderr,"-tag: %s\n", name); struct parsedata *pd = userData; Pool *pool = pd->common.pool; Solvable *s = pd->solvable; Repo *repo = pd->common.repo; Id handle = pd->handle; Id id; char *p; if (pd->depth != pd->statedepth) { pd->depth--; // printf("back from unknown %d %d %d\n", pd->state, pd->depth, pd->statedepth); return; } /* ignore patterns & metadata */ if (pd->state == STATE_START && !strcmp(name, "patterns")) return; if (pd->state == STATE_START && !strcmp(name, "products")) return; //if (pd->state == STATE_START && !strcmp(name, "metadata")) // return; if (pd->state == STATE_SOLVABLE && !strcmp(name, "format")) return; pd->depth--; pd->statedepth--; switch (pd->state) { case STATE_SOLVABLE: if (pd->kind && !s->name) /* add namespace in case of NULL name */ s->name = str2id(pool, join2(pd->kind, ":", ""), 1); if (!s->arch) s->arch = ARCH_NOARCH; if (!s->evr) s->evr = ID_EMPTY; /* some patterns have this */ if (s->name && s->arch != ARCH_SRC && s->arch != ARCH_NOSRC) s->provides = repo_addid_dep(repo, s->provides, rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, pd->freshens); s->conflicts = repo_fix_conflicts(repo, s->conflicts); pd->freshens = 0; pd->kind = 0; break; case STATE_NAME: if (pd->kind) s->name = str2id(pool, join2(pd->kind, ":", pd->content), 1); else s->name = str2id(pool, pd->content, 1); break; case STATE_ARCH: s->arch = str2id(pool, pd->content, 1); break; case STATE_VENDOR: s->vendor = str2id(pool, pd->content, 1); break; case STATE_RPM_GROUP: repodata_set_poolstr(pd->data, handle, SOLVABLE_GROUP, pd->content); break; case STATE_RPM_LICENSE: repodata_set_poolstr(pd->data, handle, SOLVABLE_LICENSE, pd->content); break; case STATE_CHECKSUM: { Id type, index; type = sat_chksum_str2type(pd->tmpattr); if (!type) { fprintf(stderr, "Unknown checksum type: %d: %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr); exit(1); } if (strlen(pd->content) != 2 * sat_chksum_len(type)) { fprintf(stderr, "Invalid checksum length: %d: for %s\n", (unsigned int)XML_GetCurrentLineNumber(*pd->parser), pd->tmpattr); exit(1); } repodata_set_checksum(pd->data, handle, SOLVABLE_CHECKSUM, type, pd->content); /* we save the checksum to solvable id relationship for extended metadata */ index = stringpool_str2id(&pd->cspool, pd->content, 1 /* create it */); if (index >= pd->ncscache) { pd->cscache = sat_zextend(pd->cscache, pd->ncscache, index + 1 - pd->ncscache, sizeof(Id), 255); pd->ncscache = index + 1; } /* add the checksum to the cache */ pd->cscache[index] = s - pool->solvables; break; } case STATE_FILE: #if 0 id = str2id(pool, pd->content, 1); s->provides = repo_addid_dep(repo, s->provides, id, SOLVABLE_FILEMARKER); #endif if ((p = strrchr(pd->content, '/')) != 0) { *p++ = 0; if (pd->lastdir && !strcmp(pd->lastdirstr, pd->content)) { id = pd->lastdir; } else { int l; id = repodata_str2dir(pd->data, pd->content, 1); l = strlen(pd->content) + 1; if (l > pd->lastdirstrl) { pd->lastdirstrl = l + 128; pd->lastdirstr = sat_realloc(pd->lastdirstr, pd->lastdirstrl); } strcpy(pd->lastdirstr, pd->content); pd->lastdir = id; } } else { p = pd->content; id = 0; } if (!id) id = repodata_str2dir(pd->data, "/", 1); repodata_add_dirstr(pd->data, handle, SOLVABLE_FILELIST, id, p); break; case STATE_SUMMARY: repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_SUMMARY, pd->tmplang), pd->content); break; case STATE_DESCRIPTION: set_description_author(pd->data, handle, pd->content, pd); break; case STATE_CATEGORY: repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_CATEGORY, pd->tmplang), pd->content); break; case STATE_DISTRIBUTION: repodata_set_poolstr(pd->data, handle, SOLVABLE_DISTRIBUTION, pd->content); break; case STATE_URL: if (pd->content[0]) repodata_set_str(pd->data, handle, SOLVABLE_URL, pd->content); break; case STATE_PACKAGER: if (pd->content[0]) repodata_set_poolstr(pd->data, handle, SOLVABLE_PACKAGER, pd->content); break; case STATE_SOURCERPM: set_sourcerpm(pd->data, s, handle, pd->content); break; case STATE_RELNOTESURL: if (pd->content[0]) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "releasenotes", 1)); } break; case STATE_UPDATEURL: if (pd->content[0]) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "update", 1)); } break; case STATE_OPTIONALURL: if (pd->content[0]) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, str2id(pool, "optional", 1)); } break; case STATE_FLAG: if (pd->content[0]) repodata_set_poolstr(pd->data, handle, PRODUCT_FLAGS, pd->content); break; case STATE_EULA: if (pd->content[0]) repodata_set_str(pd->data, handle, langtag(pd, SOLVABLE_EULA, pd->tmplang), pd->content); break; case STATE_KEYWORD: if (pd->content[0]) repodata_add_poolstr_array(pd->data, pd->handle, SOLVABLE_KEYWORDS, pd->content); break; case STATE_DISKUSAGE: if (pd->ndirs) commit_diskusage(pd, pd->handle); break; case STATE_ORDER: if (pd->content[0]) repodata_set_str(pd->data, pd->handle, SOLVABLE_ORDER, pd->content); default: break; } pd->state = pd->sbtab[pd->state]; pd->docontent = 0; // fprintf(stderr, "back from known %d %d %d\n", pd->state, pd->depth, pd->statedepth); }
int tool_write(Repo *repo, const char *basename, const char *attrname) { Repodata *data; Repodata *info = 0; Repokey *key; char **languages = 0; int nlanguages = 0; int i, j, k, l; Id *addedfileprovides = 0; struct keyfilter_data kd; memset(&kd, 0, sizeof(kd)); info = repo_add_repodata(repo, 0); repodata_set_str(info, SOLVID_META, REPOSITORY_TOOLVERSION, LIBSOLV_TOOLVERSION); pool_addfileprovides_ids(repo->pool, 0, &addedfileprovides); if (addedfileprovides && *addedfileprovides) { kd.haveaddedfileprovides = 1; for (i = 0; addedfileprovides[i]; i++) repodata_add_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addedfileprovides[i]); } solv_free(addedfileprovides); pool_freeidhashes(repo->pool); /* free some mem */ if (basename) { char fn[4096]; FILE *fp; int has_DU = 0; int has_FL = 0; /* find languages and other info */ FOR_REPODATAS(repo, i, data) { for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++) { const char *keyname = pool_id2str(repo->pool, key->name); if (key->name == SOLVABLE_DISKUSAGE) has_DU = 1; if (key->name == SOLVABLE_FILELIST) has_FL = 1; for (k = 0; languagetags[k] != 0; k++) if (!strncmp(keyname, languagetags[k], strlen(languagetags[k]))) break; if (!languagetags[k]) continue; l = strlen(languagetags[k]); if (strlen(keyname + l) > 5) continue; for (k = 0; k < nlanguages; k++) if (!strcmp(languages[k], keyname + l)) break; if (k < nlanguages) continue; languages = solv_realloc2(languages, nlanguages + 1, sizeof(char *)); languages[nlanguages++] = strdup(keyname + l); } } /* write language subfiles */ for (i = 0; i < nlanguages; i++) { sprintf(fn, "%s.%s.solv", basename, languages[i]); if (!(fp = fopen(fn, "w"))) { perror(fn); exit(1); } write_info(repo, fp, keyfilter_language, languages[i], info, fn); fclose(fp); kd.haveexternal = 1; } /* write DU subfile */ if (has_DU) { sprintf(fn, "%s.DU.solv", basename); if (!(fp = fopen(fn, "w"))) { perror(fn); exit(1); } write_info(repo, fp, keyfilter_DU, 0, info, fn); fclose(fp); kd.haveexternal = 1; } /* write filelist */ if (has_FL) { sprintf(fn, "%s.FL.solv", basename); if (!(fp = fopen(fn, "w"))) { perror(fn); exit(1); } write_info(repo, fp, keyfilter_FL, 0, info, fn); fclose(fp); kd.haveexternal = 1; } /* write everything else */ sprintf(fn, "%s.solv", basename); if (!(fp = fopen(fn, "w"))) { perror(fn); exit(1); } kd.languages = languages; kd.nlanguages = nlanguages; repodata_internalize(info); repo_write(repo, fp, keyfilter_other, &kd, 0); fclose(fp); for (i = 0; i < nlanguages; i++) free(languages[i]); solv_free(languages); repodata_free(info); return 0; } if (attrname) { FILE *fp; test_separate = 1; fp = fopen(attrname, "w"); write_info(repo, fp, keyfilter_attr, 0, info, attrname); fclose(fp); kd.haveexternal = 1; } repodata_internalize(info); repo_write(repo, stdout, keyfilter_solv, &kd, 0); repodata_free(info); return 0; }
static void XMLCALL endElement(void *userData, const char *name) { struct parsedata *pd = userData; Solvable *s = pd->solvable; #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_PRODUCT: /* product done, finish solvable */ if (pd->ctime) repodata_set_num(pd->data, pd->handle, SOLVABLE_INSTALLTIME, pd->ctime); if (pd->basename) repodata_set_str(pd->data, pd->handle, PRODUCT_REFERENCEFILE, pd->basename); /* this is where <productsdir>/baseproduct points to */ if (pd->currentproduct == pd->baseproduct) repodata_set_str(pd->data, pd->handle, PRODUCT_TYPE, "base"); if (pd->tmprel) { if (pd->tmpvers) s->evr = makeevr(pd->pool, join2(&pd->jd, pd->tmpvers, "-", pd->tmprel)); else { fprintf(stderr, "Seen <release> but no <version>\n"); } } else if (pd->tmpvers) s->evr = makeevr(pd->pool, pd->tmpvers); /* just version, no release */ pd->tmpvers = solv_free((void *)pd->tmpvers); pd->tmprel = solv_free((void *)pd->tmprel); 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_VENDOR: s->vendor = pool_str2id(pd->pool, pd->content, 1); break; case STATE_NAME: s->name = pool_str2id(pd->pool, join2(&pd->jd, "product", ":", pd->content), 1); break; case STATE_VERSION: pd->tmpvers = solv_strdup(pd->content); break; case STATE_RELEASE: pd->tmprel = solv_strdup(pd->content); break; case STATE_ARCH: s->arch = pool_str2id(pd->pool, pd->content, 1); break; case STATE_PRODUCTLINE: repodata_set_str(pd->data, pd->handle, PRODUCT_PRODUCTLINE, pd->content); break; case STATE_UPDATEREPOKEY: /** obsolete **/ break; case STATE_SUMMARY: repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_SUMMARY, pd->tmplang, 1), pd->content); break; case STATE_SHORTSUMMARY: repodata_set_str(pd->data, pd->handle, PRODUCT_SHORTLABEL, pd->content); break; case STATE_DESCRIPTION: repodata_set_str(pd->data, pd->handle, pool_id2langid(pd->pool, SOLVABLE_DESCRIPTION, pd->tmplang, 1), pd->content); break; case STATE_URL: if (pd->urltype) { repodata_add_poolstr_array(pd->data, pd->handle, PRODUCT_URL, pd->content); repodata_add_idarray(pd->data, pd->handle, PRODUCT_URL_TYPE, pd->urltype); } break; case STATE_TARGET: repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_TARGET, pd->content); break; case STATE_REGRELEASE: repodata_set_str(pd->data, pd->handle, PRODUCT_REGISTER_RELEASE, pd->content); break; case STATE_CPEID: if (*pd->content) repodata_set_str(pd->data, pd->handle, SOLVABLE_CPEID, pd->content); default: break; } pd->state = pd->sbtab[pd->state]; pd->docontent = 0; #if 0 fprintf(stderr, "end: [%s] -> %d\n", name, pd->state); #endif }