Example #1
0
void
repo_free_solvable(Repo *repo, Id p, int reuseids)
{
  repo_free_solvable_block(repo, p, 1, reuseids);
}
Example #2
0
int
repo_add_content(Repo *repo, FILE *fp, int flags)
{
    Pool *pool = repo->pool;
    char *line, *linep;
    int aline;
    Solvable *s;
    struct parsedata pd;
    Repodata *data;
    Id handle = 0;
    int contentstyle = 0;
    char *descrdir = 0;
    char *datadir = 0;
    char *defvendor = 0;

    int i = 0;

    /* architectures
       we use the first architecture in BASEARCHS or noarch
       for the product. At the end we create (clone) the product
       for each one of the remaining architectures
       we allow max 4 archs
    */
    unsigned int numotherarchs = 0;
    Id *otherarchs = 0;

    memset(&pd, 0, sizeof(pd));
    line = solv_malloc(1024);
    aline = 1024;

    pd.repo = repo;
    linep = line;
    s = 0;

    data = repo_add_repodata(repo, flags);

    for (;;)
    {
        char *key, *value;

        /* read line into big-enough buffer */
        if (linep - line + 16 > aline)
        {
            aline = linep - line;
            line = solv_realloc(line, aline + 512);
            linep = line + aline;
            aline += 512;
        }
        if (!fgets(linep, aline - (linep - line), fp))
            break;
        linep += strlen(linep);
        if (linep == line || linep[-1] != '\n')
            continue;
        while ( --linep > line && ( linep[-1] == ' ' ||  linep[-1] == '\t' ) )
            ; /* skip trailing ws */
        *linep = 0;
        linep = line;

        /* expect "key value" lines */
        value = line;
        key = splitword(&value);

        if (key)
        {
#if 0
            fprintf (stderr, "key %s, value %s\n", key, value);
#endif

#define istag(x) (!strcmp (key, x))
#define code10 (contentstyle == 10)
#define code11 (contentstyle == 11)


            if (istag ("CONTENTSTYLE"))
            {
                if (contentstyle)
                    pool_debug(pool, SOLV_ERROR, "repo_content: 'CONTENTSTYLE' must be first line of 'content'\n");
                contentstyle = atoi(value);
                continue;
            }
            if (!contentstyle)
                contentstyle = 10;

            /* repository tags */
            /* we also replicate some of them into the product solvables
             * to be backward compatible */

            if (istag ("REPOID"))
            {
                repodata_add_poolstr_array(data, SOLVID_META, REPOSITORY_REPOID, value);
                continue;
            }

            if (istag ("DESCRDIR"))
            {
                if (descrdir)
                    free(descrdir);
                else
                    repodata_set_str(data, SOLVID_META, SUSETAGS_DESCRDIR, value);
                if (s)
                    repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, value);
                descrdir = solv_strdup(value);
                continue;
            }
            if (istag ("DATADIR"))
            {
                if (datadir)
                    free(datadir);
                else
                    repodata_set_str(data, SOLVID_META, SUSETAGS_DATADIR, value);
                if (s)
                    repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, value);
                datadir = solv_strdup(value);
                continue;
            }
            if (istag ("VENDOR"))
            {
                if (defvendor)
                    free(defvendor);
                else
                    repodata_set_poolstr(data, SOLVID_META, SUSETAGS_DEFAULTVENDOR, value);
                if (s)
                    s->vendor = pool_str2id(pool, value, 1);
                defvendor = solv_strdup(value);
                continue;
            }

            if (istag ("META") || istag ("HASH") || istag ("KEY"))
            {
                char *checksumtype, *checksum;
                Id fh, type;
                int l;

                if ((checksumtype = splitword(&value)) == 0)
                    continue;
                if ((checksum = splitword(&value)) == 0)
                    continue;
                if (!*value)
                    continue;
                type = solv_chksum_str2type(checksumtype);
                if (!type)
                {
                    fprintf(stderr, "Unknown checksum type: %s: %s\n", value, checksumtype);
                    continue;
                }
                l = solv_chksum_len(type);
                if (strlen(checksum) != 2 * l)
                {
                    fprintf(stderr, "Invalid checksum length: %s: for %s\n", value, checksum);
                    continue;
                }
                fh = repodata_new_handle(data);
                repodata_set_poolstr(data, fh, SUSETAGS_FILE_TYPE, key);
                repodata_set_str(data, fh, SUSETAGS_FILE_NAME, value);
                repodata_set_checksum(data, fh, SUSETAGS_FILE_CHECKSUM, type, checksum);
                repodata_add_flexarray(data, SOLVID_META, SUSETAGS_FILE, fh);
                continue;
            }

            /* product tags */

            if ((code10 && istag ("PRODUCT"))
                    || (code11 && istag ("NAME")))
            {
                if (s && !s->name)
                {
                    /* this solvable was created without seeing a
                       PRODUCT entry, just set the name and continue */
                    s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1);
                    continue;
                }
                if (s)
                {
                    /* finish old solvable */
                    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(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
                    if (code10)
                        s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);
                }
                /* create new solvable */
                s = pool_id2solvable(pool, repo_add_solvable(repo));
                repodata_extend(data, s - pool->solvables);
                handle = s - pool->solvables;
                s->name = pool_str2id(pool, join(&pd, "product", ":", value), 1);
                if (datadir)
                    repodata_set_str(data, s - pool->solvables, SUSETAGS_DATADIR, datadir);
                if (descrdir)
                    repodata_set_str(data, s - pool->solvables, SUSETAGS_DESCRDIR, descrdir);
                if (defvendor)
                    s->vendor = pool_str2id(pool, defvendor, 1);
                continue;
            }

            /* Sometimes PRODUCT/NAME is not the first entry, but we need a solvable
               from here on.  */
            if (!s)
            {
                s = pool_id2solvable(pool, repo_add_solvable(repo));
                repodata_extend(data, s - pool->solvables);
                handle = s - pool->solvables;
            }

            if (istag ("VERSION"))
                pd.tmpvers = solv_strdup(value);
            else if (istag ("RELEASE"))
                pd.tmprel = solv_strdup(value);
            else if (code11 && istag ("DISTRIBUTION"))
                repodata_set_str(data, s - pool->solvables, SOLVABLE_DISTRIBUTION, value);
            else if (istag ("UPDATEURLS"))
                add_multiple_urls(data, handle, value, pool_str2id(pool, "update", 1));
            else if (istag ("EXTRAURLS"))
                add_multiple_urls(data, handle, value, pool_str2id(pool, "extra", 1));
            else if (istag ("OPTIONALURLS"))
                add_multiple_urls(data, handle, value, pool_str2id(pool, "optional", 1));
            else if (istag ("RELNOTESURL"))
                add_multiple_urls(data, handle, value, pool_str2id(pool, "releasenotes", 1));
            else if (istag ("SHORTLABEL"))
                repodata_set_str(data, s - pool->solvables, PRODUCT_SHORTLABEL, value);
            else if (istag ("LABEL")) /* LABEL is the products SUMMARY. */
                repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, value);
            else if (!strncmp (key, "LABEL.", 6))
                repodata_set_str(data, s - pool->solvables, pool_id2langid(pool, SOLVABLE_SUMMARY, key + 6, 1), value);
            else if (istag ("FLAGS"))
                add_multiple_strings(data, handle, PRODUCT_FLAGS, value);
            else if (istag ("VENDOR"))	/* actually already handled above */
                s->vendor = pool_str2id(pool, value, 1);
            else if (istag ("BASEARCHS"))
            {
                char *arch;

                if ((arch = splitword(&value)) != 0)
                {
                    s->arch = pool_str2id(pool, arch, 1);
                    while ((arch = splitword(&value)) != 0)
                    {
                        otherarchs = solv_extend(otherarchs, numotherarchs, 1, sizeof(Id), 7);
                        otherarchs[numotherarchs++] = pool_str2id(pool, arch, 1);
                    }
                }
            }

            /*
             * Every tag below is Code10 only
             *
             */

            if (code10 && istag ("DISTPRODUCT"))
                /* DISTPRODUCT is for registration and Yast, not for the solver. */
                repodata_set_str(data, s - pool->solvables, PRODUCT_DISTPRODUCT, value);
            else if (code10 && istag ("DISTVERSION"))
                /* DISTVERSION is for registration and Yast, not for the solver. */
                repodata_set_str(data, s - pool->solvables, PRODUCT_DISTVERSION, value);
            else if (code10 && istag ("ARCH"))
                /* Theoretically we want to have the best arch of the given
                   modifiers which still is compatible with the system
                   arch.  We don't know the latter here, though.  */
                s->arch = ARCH_NOARCH;
            else if (code10 && istag ("PREREQUIRES"))
                s->requires = adddep(pool, &pd, s->requires, value, SOLVABLE_PREREQMARKER);
            else if (code10 && istag ("REQUIRES"))
                s->requires = adddep(pool, &pd, s->requires, value, -SOLVABLE_PREREQMARKER);
            else if (code10 && istag ("PROVIDES"))
                s->provides = adddep(pool, &pd, s->provides, value, 0);
            else if (code10 && istag ("CONFLICTS"))
                s->conflicts = adddep(pool, &pd, s->conflicts, value, 0);
            else if (code10 && istag ("OBSOLETES"))
                s->obsoletes = adddep(pool, &pd, s->obsoletes, value, 0);
            else if (code10 && istag ("RECOMMENDS"))
                s->recommends = adddep(pool, &pd, s->recommends, value, 0);
            else if (code10 && istag ("SUGGESTS"))
                s->suggests = adddep(pool, &pd, s->suggests, value, 0);
            else if (code10 && istag ("SUPPLEMENTS"))
                s->supplements = adddep(pool, &pd, s->supplements, value, 0);
            else if (code10 && istag ("ENHANCES"))
                s->enhances = adddep(pool, &pd, s->enhances, value, 0);
            /* FRESHENS doesn't seem to exist.  */
            else if (code10 && istag ("TYPE"))
                repodata_set_str(data, s - pool->solvables, PRODUCT_TYPE, value);

            /* XXX do something about LINGUAS and ARCH?
                * <ma>: Don't think so. zypp does not use or propagate them.
                */
#undef istag
        }
        else
            pool_debug(pool, SOLV_ERROR, "repo_content: malformed line: %s\n", line);
    }

    if (datadir)
        free(datadir);
    if (descrdir)
        free(descrdir);
    if (defvendor)
        free(defvendor);

    if (s && !s->name)
    {
        pool_debug(pool, SOLV_FATAL, "repo_content: 'content' incomplete, no product solvable created!\n");
        repo_free_solvable_block(repo, s - pool->solvables, 1, 1);
        s = 0;
    }
    if (s)
    {
        if (pd.tmprel)
            s->evr = makeevr(pool, join(&pd, pd.tmpvers, "-", pd.tmprel));
        else
            s->evr = makeevr(pool, pd.tmpvers);
        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(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0);
        if (code10)
            s->supplements = repo_fix_supplements(repo, s->provides, s->supplements, 0);

        /* now for every other arch, clone the product except the architecture */
        for (i = 0; i < numotherarchs; ++i)
        {
            Solvable *p = pool_id2solvable(pool, repo_add_solvable(repo));
            repodata_extend(data, p - pool->solvables);
            p->name = s->name;
            p->evr = s->evr;
            p->vendor = s->vendor;
            p->arch = otherarchs[i];

            /* self provides */
            if (s->name && p->arch != ARCH_SRC && p->arch != ARCH_NOSRC)
                p->provides = repo_addid_dep(repo, p->provides, pool_rel2id(pool, p->name, p->evr, REL_EQ, 1), 0);

            /* now merge the attributes */
            repodata_merge_attrs(data, p - pool->solvables, s - pool->solvables);
        }
    }

    if (pd.tmp)
        solv_free(pd.tmp);
    solv_free(line);
    solv_free(otherarchs);
    join_freemem();
    if (!(flags & REPO_NO_INTERNALIZE))
        repodata_internalize(data);
    return 0;
}