From e79529f1de8172e0a7f8c78fa3ad8866c9f008d0 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Thu, 22 Mar 2012 18:17:35 +0100 Subject: [PATCH] - add M&M synthesis file parser, add mkd2solv tool --- CMakeLists.txt | 4 +- ext/CMakeLists.txt | 7 ++ ext/libsolvext.ver | 1 + ext/repo_mdk.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++ ext/repo_mdk.h | 9 ++ tools/CMakeLists.txt | 7 ++ tools/mdk2solv.c | 38 ++++++++ 7 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 ext/repo_mdk.c create mode 100644 ext/repo_mdk.h create mode 100644 tools/mdk2solv.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 70ecf72..217361c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ OPTION (ENABLE_SUSEREPO "Build with suse repository support?" OFF) OPTION (ENABLE_COMPS "Build with fedora comps support?" OFF) OPTION (ENABLE_HELIXREPO "Build with helix repository support?" OFF) OPTION (ENABLE_DEBIAN "Build with debian database/repository support?" OFF) +OPTION (ENABLE_MDKREPO "Build with mandriva/mageia repository support?" OFF) #IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERISION} GREATER 2.4) #ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERISION} GREATER 2.4) @@ -85,6 +86,7 @@ IF (NOT ENABLE_RPMDB AND NOT ENABLE_RPMMD AND NOT ENABLE_SUSEREPO AND NOT ENABLE_HELIXREPO AND + NOT ENABLE_MDKREPO AND NOT ENABLE_DEBIAN) SET (ENABLE_RPMDB ON) SET (ENABLE_RPMDB_PUBKEY ON) @@ -132,7 +134,7 @@ TEST_BIG_ENDIAN (WORDS_BIGENDIAN) # should create config.h with #cmakedefine instead... FOREACH (VAR HAVE_STRCHRNUL HAVE_FOPENCOOKIE HAVE_FUNOPEN WORDS_BIGENDIAN ENABLE_RPMDB ENABLE_RPMDB_PUBKEY ENABLE_RPMMD ENABLE_SUSEREPO ENABLE_COMPS - ENABLE_HELIXREPO ENABLE_DEBIAN) + ENABLE_HELIXREPO ENABLE_MDKREPO ENABLE_DEBIAN) IF(${VAR}) ADD_DEFINITIONS (-D${VAR}=1) SET (SWIG_FLAGS ${SWIG_FLAGS} -D${VAR}) diff --git a/ext/CMakeLists.txt b/ext/CMakeLists.txt index ab2ba90..9e4a6f0 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -50,6 +50,13 @@ IF (ENABLE_HELIXREPO) repo_helix.h) ENDIF (ENABLE_HELIXREPO) +IF (ENABLE_MDKREPO) + SET (libsolvext_SRCS ${libsolvext_SRCS} + repo_mdk.c) + SET (libsolvext_HEADERS ${libsolvext_HEADERS} + repo_mdk.h) +ENDIF (ENABLE_MDKREPO) + SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") SET (CMAKE_SHARED_LINKER_FLAGS "${LINK_FLAGS} -Wl,--version-script=${CMAKE_SOURCE_DIR}/ext/libsolvext.ver") diff --git a/ext/libsolvext.ver b/ext/libsolvext.ver index cc28d75..de8a0f8 100644 --- a/ext/libsolvext.ver +++ b/ext/libsolvext.ver @@ -10,6 +10,7 @@ SOLV_1.0 { repo_add_debs; repo_add_deltainfoxml; repo_add_helix; + repo_add_mdk; repo_add_products; repo_add_pubkeys; repo_add_releasefile_products; diff --git a/ext/repo_mdk.c b/ext/repo_mdk.c new file mode 100644 index 0000000..6e44c98 --- /dev/null +++ b/ext/repo_mdk.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#include +#include +#include +#include +#include +#include + +#include "pool.h" +#include "repo.h" +#include "util.h" +#include "chksum.h" +#include "repo_mdk.h" + +static Offset +parse_deps(Solvable *s, char *bp, Id marker) +{ + Pool *pool = s->repo->pool; + Offset deps = 0; + char *nbp, *ebp; + for (; bp; bp = nbp) + { + int ispre = 0; + Id id, evr = 0; + int flags = 0; + + nbp = strchr(bp, '@'); + if (!nbp) + ebp = bp + strlen(bp); + else + { + ebp = nbp; + *nbp++ = 0; + } + if (ebp[-1] == ']') + { + char *sbp = ebp - 1; + while (sbp >= bp && *sbp != '[') + sbp--; + if (sbp >= bp && sbp[1] != '*') + { + char *fbp; + for (fbp = sbp + 1;; fbp++) + { + if (*fbp == '>') + flags |= REL_GT; + else if (*fbp == '=') + flags |= REL_EQ; + else if (*fbp == '<') + flags |= REL_LT; + else + break; + } + if (*fbp == ' ') + fbp++; + evr = pool_strn2id(pool, fbp, ebp - 1 - fbp, 1); + ebp = sbp; + } + } + if (ebp[-1] == ']' && ebp >= bp + 3 && !strncmp(ebp - 3, "[*]", 3)) + { + ispre = 1; + ebp -= 3; + } + id = pool_strn2id(pool, bp, ebp - bp, 1); + if (evr) + id = pool_rel2id(pool, id, evr, flags, 1); + deps = repo_addid_dep(s->repo, deps, id, ispre ? marker : 0); + bp = nbp; + } + return deps; +} + +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)) + { + unsigned long filesize = strtoul(buf + 10, 0, 10); + repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned int)((filesize + 1023) / 1024)); + } + 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; + unsigned long size; + *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); + } + size = strtoul(sizestr, 0, 10); + repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, (unsigned int)((size + 1023) / 1024)); + } + } + 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_block(s->repo, s - pool->solvables, 1, 1); + } + solv_free(buf); + if (!(flags & REPO_NO_INTERNALIZE)) + repodata_internalize(data); + return 0; +} diff --git a/ext/repo_mdk.h b/ext/repo_mdk.h new file mode 100644 index 0000000..7a04b38 --- /dev/null +++ b/ext/repo_mdk.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +extern int repo_add_mdk(Repo *repo, FILE *fp, int flags); + diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 79ef605..86f804d 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -62,6 +62,13 @@ TARGET_LINK_LIBRARIES (comps2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIE SET (tools_list ${tools_list} comps2solv) ENDIF (ENABLE_COMPS) +IF (ENABLE_MDKREPO) +ADD_EXECUTABLE (mdk2solv mdk2solv.c) +TARGET_LINK_LIBRARIES (mdk2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIES}) + +SET (tools_list ${tools_list} mdk2solv) +ENDIF (ENABLE_MDKREPO) + ADD_EXECUTABLE (installcheck installcheck.c) TARGET_LINK_LIBRARIES (installcheck libsolvext libsolv ${SYSTEM_LIBRARIES}) diff --git a/tools/mdk2solv.c b/tools/mdk2solv.c new file mode 100644 index 0000000..769b5ba --- /dev/null +++ b/tools/mdk2solv.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * comps2solv.c + * + * parse Mandriva/Mageie synthesis file + * + * reads from stdin + * writes to stdout + */ + +#include +#include +#include +#include +#include +#include + +#include "pool.h" +#include "repo.h" +#include "repo_mdk.h" +#include "common_write.h" + +int +main(int argc, char **argv) +{ + Pool *pool = pool_create(); + Repo *repo = repo_create(pool, ""); + repo_add_mdk(repo, stdin, 0); + tool_write(repo, 0, 0); + pool_free(pool); + exit(0); +} -- 2.7.4