static unsigned int makedeps(Repo *repo, char *deps, unsigned int olddeps, Id marker) { Pool *pool = repo->pool; char *p; Id id; while ((p = strchr(deps, ',')) != 0) { *p = 0; olddeps = makedeps(repo, deps, olddeps, marker); *p = ','; deps = p + 1; } id = parseonedep(pool, deps); if (!id) return olddeps; return repo_addid_dep(repo, olddeps, id, marker); }
int repo_add_cudf(Repo *repo, Repo *installedrepo, FILE *fp, Queue *job, int flags) { Pool *pool = repo->pool; char *buf, *p; int bufa, bufl, c; Solvable *s; int instanza = 0; int inrequest = 0; int isinstalled = 0; int keep = 0; Repo *xrepo; xrepo = repo ? repo : installedrepo; if (!xrepo) return -1; buf = solv_malloc(4096); bufa = 4096; 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; c = getc(fp); if (c == ' ' || c == '\t') { /* continuation line */ buf[bufl++] = ' '; continue; } if (c != EOF) ungetc(c, fp); bufl = 0; if (*buf == '#') continue; if (!*buf) { if (s && !repo && !isinstalled) { repo_free_solvable(repo, s - pool->solvables, 1); s = 0; } if (s) finishpackage(pool, s, keep, job); s = 0; keep = 0; instanza = 0; inrequest = 0; continue; } p = strchr(buf, ':'); if (!p) continue; /* hmm */ *p++ = 0; while (*p == ' ' || *p == '\t') p++; if (!instanza) { instanza = 1; inrequest = 0; if (!strcmp(buf, "request")) { inrequest = 1; continue; } if (!strcmp(buf, "package")) { s = pool_id2solvable(pool, repo_add_solvable(xrepo)); isinstalled = 0; keep = 0; } } if (inrequest) { if (!job) continue; if (!strcmp(buf, "install")) { Id id, *idp; Offset off = makedeps(xrepo, p, 0, 0); for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++) queue_push2(job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, id); } else if (!strcmp(buf, "remove")) { Id id, *idp; Offset off = makedeps(xrepo, p, 0, 0); for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++) queue_push2(job, SOLVER_ERASE|SOLVER_SOLVABLE_PROVIDES, id); } else if (!strcmp(buf, "upgrade")) { Id id, *idp; Offset off = makedeps(xrepo, p, 0, 0); for (idp = xrepo->idarraydata + off; (id = *idp) != 0; idp++) queue_push2(job, SOLVER_INSTALL|SOLVER_ORUPDATE|SOLVER_SOLVABLE_PROVIDES, id); } continue; } if (!s) continue; /* we ignore the preamble for now */ switch (buf[0]) { case 'c': if (!strcmp(buf, "conflicts")) { s->conflicts = makedeps(s->repo, p, s->conflicts, 0); continue; } case 'd': if (!strcmp(buf, "depends")) { s->requires = makedeps(s->repo, p, s->requires, 0); continue; } break; case 'k': if (!strcmp(buf, "keep")) { if (!job) continue; if (!strcmp(p, "version")) keep = KEEP_VERSION; else if (!strcmp(p, "package")) keep = KEEP_PACKAGE; else if (!strcmp(p, "feature")) keep = KEEP_FEATURE; continue; } break; case 'i': if (!strcmp(buf, "installed")) { if (!strcmp(p, "true")) { isinstalled = 1; if (!installedrepo) { repo_free_solvable(repo, s - pool->solvables, 1); s = 0; } else if (s->repo != installedrepo) { copysolvabledata(pool, s, installedrepo); s->repo->nsolvables--; s->repo = installedrepo; if (s - pool->solvables < s->repo->start) s->repo->start = s - pool->solvables; if (s - pool->solvables >= s->repo->end) s->repo->end = s - pool->solvables + 1; s->repo->nsolvables++; } } continue; } break; case 'p': if (!strcmp(buf, "package")) { s->name = pool_str2id(pool, p, 1); continue; } if (!strcmp(buf, "provides")) { s->provides = makedeps(s->repo, p, s->provides, 0); continue; } break; case 'r': if (!strcmp(buf, "depends")) { s->recommends = makedeps(s->repo, p, s->recommends, 0); continue; } break; case 'v': if (!strcmp(buf, "version")) { s->evr = pool_str2id(pool, p, 1); continue; } break; } } if (s && !repo && !isinstalled) { repo_free_solvable(repo, s - pool->solvables, 1); s = 0; } if (s) finishpackage(pool, s, keep, job); solv_free(buf); return 0; }
/* warning: does inplace changes */ static void control2solvable(Solvable *s, Repodata *data, char *control) { Repo *repo = s->repo; Pool *pool = repo->pool; char *p, *q, *end, *tag; int x, l; int havesource = 0; char checksum[32 * 2 + 1]; Id checksumtype = 0; Id newtype; p = control; while (*p) { p = strchr(p, '\n'); if (!p) break; if (p[1] == ' ' || p[1] == '\t') { char *q; /* continuation line */ q = p - 1; while (q >= control && *q == ' ' && *q == '\t') q--; l = q + 1 - control; if (l) memmove(p + 1 - l, control, l); control = p + 1 - l; p[1] = '\n'; p += 2; continue; } end = p - 1; if (*p) *p++ = 0; /* strip trailing space */ while (end >= control && (*end == ' ' || *end == '\t')) *end-- = 0; tag = control; control = p; q = strchr(tag, ':'); if (!q || q - tag < 4) continue; *q++ = 0; while (*q == ' ' || *q == '\t') q++; x = '@' + (tag[0] & 0x1f); x = (x << 8) + '@' + (tag[1] & 0x1f); switch(x) { case 'A' << 8 | 'R': if (!strcasecmp(tag, "architecture")) s->arch = pool_str2id(pool, q, 1); break; case 'B' << 8 | 'R': if (!strcasecmp(tag, "breaks")) s->conflicts = makedeps(repo, q, s->conflicts, 0); break; case 'C' << 8 | 'O': if (!strcasecmp(tag, "conflicts")) s->conflicts = makedeps(repo, q, s->conflicts, 0); break; case 'D' << 8 | 'E': if (!strcasecmp(tag, "depends")) s->requires = makedeps(repo, q, s->requires, -SOLVABLE_PREREQMARKER); else if (!strcasecmp(tag, "description")) { char *ld = strchr(q, '\n'); if (ld) { *ld++ = 0; repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, ld); } else repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, q); repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, q); } break; case 'E' << 8 | 'N': if (!strcasecmp(tag, "enhances")) s->enhances = makedeps(repo, q, s->enhances, 0); break; case 'F' << 8 | 'I': if (!strcasecmp(tag, "filename")) repodata_set_location(data, s - pool->solvables, 0, 0, q); break; case 'H' << 8 | 'O': if (!strcasecmp(tag, "homepage")) repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, q); break; case 'I' << 8 | 'N': if (!strcasecmp(tag, "installed-size")) repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(q, 0, 10) << 10); break; case 'M' << 8 | 'D': if (!strcasecmp(tag, "md5sum") && !checksumtype && strlen(q) == 16 * 2) { strcpy(checksum, q); checksumtype = REPOKEY_TYPE_MD5; } break; case 'P' << 8 | 'A': if (!strcasecmp(tag, "package")) s->name = pool_str2id(pool, q, 1); break; case 'P' << 8 | 'R': if (!strcasecmp(tag, "pre-depends")) s->requires = makedeps(repo, q, s->requires, SOLVABLE_PREREQMARKER); else if (!strcasecmp(tag, "provides")) s->provides = makedeps(repo, q, s->provides, 0); break; case 'R' << 8 | 'E': if (!strcasecmp(tag, "replaces")) s->obsoletes = makedeps(repo, q, s->obsoletes, 0); else if (!strcasecmp(tag, "recommends")) s->recommends = makedeps(repo, q, s->recommends, 0); break; case 'S' << 8 | 'H': newtype = solv_chksum_str2type(tag); if (!newtype || solv_chksum_len(newtype) * 2 != strlen(q)) break; if (!checksumtype || (newtype == REPOKEY_TYPE_SHA1 && checksumtype != REPOKEY_TYPE_SHA256) || newtype == REPOKEY_TYPE_SHA256) { strcpy(checksum, q); checksumtype = newtype; } break; case 'S' << 8 | 'O': if (!strcasecmp(tag, "source")) { char *q2; /* ignore version for now */ for (q2 = q; *q2; q2++) if (*q2 == ' ' || *q2 == '\t') { *q2 = 0; break; } if (s->name && !strcmp(q, pool_id2str(pool, s->name))) repodata_set_void(data, s - pool->solvables, SOLVABLE_SOURCENAME); else repodata_set_id(data, s - pool->solvables, SOLVABLE_SOURCENAME, pool_str2id(pool, q, 1)); havesource = 1; } break; case 'S' << 8 | 'T': if (!strcasecmp(tag, "status")) repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_INSTALLSTATUS, q); break; case 'S' << 8 | 'U': if (!strcasecmp(tag, "suggests")) s->suggests = makedeps(repo, q, s->suggests, 0); break; case 'V' << 8 | 'E': if (!strcasecmp(tag, "version")) s->evr = pool_str2id(pool, q, 1); break; } } if (checksumtype) repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, checksumtype, checksum); if (!s->arch) s->arch = ARCH_ALL; if (!s->evr) s->evr = ID_EMPTY; if (s->name) s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); if (s->name && !havesource) repodata_set_void(data, s - pool->solvables, SOLVABLE_SOURCENAME); if (s->obsoletes) { /* obsoletes only count when the packages also conflict */ /* XXX: should not transcode here */ int i, j, k; Id d, cid; for (i = j = s->obsoletes; (d = repo->idarraydata[i]) != 0; i++) { if (!s->conflicts) continue; for (k = s->conflicts; (cid = repo->idarraydata[k]) != 0; k++) { if (repo->idarraydata[k] == cid) break; if (ISRELDEP(cid)) { Reldep *rd = GETRELDEP(pool, cid); if (rd->flags < 8 && rd->name == d) break; /* specialize obsoletes */ } } if (cid) repo->idarraydata[j++] = cid; } repo->idarraydata[j] = 0; if (j == s->obsoletes) s->obsoletes = 0; } }