diff options
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | ext/CMakeLists.txt | 7 | ||||
-rw-r--r-- | ext/libsolvext.ver | 2 | ||||
-rw-r--r-- | ext/repo_arch.c | 670 | ||||
-rw-r--r-- | ext/repo_arch.h | 12 | ||||
-rw-r--r-- | tools/CMakeLists.txt | 10 | ||||
-rw-r--r-- | tools/archpkgs2solv.c | 129 | ||||
-rw-r--r-- | tools/archrepo2solv.c | 68 | ||||
-rw-r--r-- | tools/mdk2solv.c | 2 |
9 files changed, 903 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4540fa6..34829bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ 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) +OPTION (ENABLE_ARCHREPO "Build with archlinux repository support?" OFF) OPTION (ENABLE_LZMA_COMPRESSION "Build with lzma/xz compression support?" OFF) @@ -89,6 +90,7 @@ IF (NOT ENABLE_RPMDB AND NOT ENABLE_SUSEREPO AND NOT ENABLE_HELIXREPO AND NOT ENABLE_MDKREPO AND + NOT ENABLE_ARCHREPO AND NOT ENABLE_DEBIAN) SET (ENABLE_RPMDB ON) SET (ENABLE_RPMDB_PUBKEY ON) @@ -136,7 +138,8 @@ 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_MDKREPO ENABLE_DEBIAN ENABLE_LZMA_COMPRESSION) + ENABLE_HELIXREPO ENABLE_MDKREPO ENABLE_ARCHREPO ENABLE_DEBIAN + ENABLE_LZMA_COMPRESSION) 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 9e4a6f0..025f9cd 100644 --- a/ext/CMakeLists.txt +++ b/ext/CMakeLists.txt @@ -57,6 +57,13 @@ IF (ENABLE_MDKREPO) repo_mdk.h) ENDIF (ENABLE_MDKREPO) +IF (ENABLE_ARCHREPO) + SET (libsolvext_SRCS ${libsolvext_SRCS} + repo_arch.c) + SET (libsolvext_HEADERS ${libsolvext_HEADERS} + repo_arch.h) +ENDIF (ENABLE_ARCHREPO) + 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 dadd339..e291f2c 100644 --- a/ext/libsolvext.ver +++ b/ext/libsolvext.ver @@ -1,6 +1,8 @@ SOLV_1.0 { global: pool_findfileconflicts; + repo_add_arch_pkg; + repo_add_arch_repo; repo_add_code11_products; repo_add_content; repo_add_comps; diff --git a/ext/repo_arch.c b/ext/repo_arch.c new file mode 100644 index 0000000..2777225 --- /dev/null +++ b/ext/repo_arch.c @@ -0,0 +1,670 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> + +#include "pool.h" +#include "repo.h" +#include "util.h" +#include "chksum.h" +#include "solv_xfopen.h" +#include "repo_arch.h" + +static long long parsenum(unsigned char *p, int cnt) +{ + long long x = 0; + if (!cnt) + return -1; + if (*p & 0x80) + { + /* binary format */ + x = *p & 0x40 ? (-1 << 8 | *p) : (*p ^ 0x80); + while (--cnt > 0) + x = (x << 8) | *p++; + return x; + } + while (cnt > 0 && (*p == ' ' || *p == '\t')) + cnt--, p++; + if (*p == '-') + return -1; + for (; cnt > 0 && *p >= '0' && *p < '8'; cnt--, p++) + x = (x << 3) | (*p - '0'); + return x; +} + +static int readblock(FILE *fp, unsigned char *blk) +{ + int r, l = 0; + while (l < 512) + { + r = fread(blk + l, 1, 512 - l, fp); + if (r <= 0) + return -1; + l += r; + } + return 0; +} + +struct tarhead { + FILE *fp; + unsigned char blk[512]; + int type; + long long length; + char *path; + int eof; + int ispax; + int off; + int end; +}; + +static char *getsentry(struct tarhead *th, char *s, int size) +{ + char *os = s; + if (th->eof || size <= 1) + return 0; + size--; /* terminating 0 */ + for (;;) + { + int i; + for (i = th->off; i < th->end; i++) + { + *s++ = th->blk[i]; + size--; + if (!size || th->blk[i] == '\n') + { + th->off = i + 1; + *s = 0; + return os; + } + } + th->off = i; + if (th->length <= 0) + return 0; + if (readblock(th->fp, th->blk)) + { + th->eof = 1; + return 0; + } + th->off = 0; + th->end = th->length > 512 ? 512 : th->length; + th->length -= th->end; + } +} + +static void skipentry(struct tarhead *th) +{ + for (; th->length > 0; th->length -= 512) + { + if (readblock(th->fp, th->blk)) + { + th->eof = 1; + th->length = 0; + return; + } + } + th->length = 0; + th->off = th->end = 0; +} + +static void inittarhead(struct tarhead *th, FILE *fp) +{ + memset(th, 0, sizeof(*th)); + th->fp = fp; +} + +static void freetarhead(struct tarhead *th) +{ + solv_free(th->path); +} + +static int gettarhead(struct tarhead *th) +{ + int l, type; + long long length; + + th->path = solv_free(th->path); + th->ispax = 0; + th->type = 0; + th->length = 0; + th->off = 0; + th->end = 0; + if (th->eof) + return 0; + for (;;) + { + int r = readblock(th->fp, th->blk); + if (r) + { + if (feof(th->fp)) + { + th->eof = 1; + return 0; + } + return -1; + } + if (th->blk[0] == 0) + { + th->eof = 1; + return 0; + } + length = parsenum(th->blk + 124, 12); + if (length < 0) + return -1; + type = 0; + switch (th->blk[156]) + { + case 'S': case '0': + type = 1; /* file */ + break; + case '1': + /* hard link, special length magic... */ + if (!th->ispax) + length = 0; + break; + case '5': + type = 2; /* dir */ + break; + case '2': case '3': case '4': case '6': + length = 0; + break; + case 'X': case 'x': case 'L': + { + char *data, *pp; + if (length < 1 || length >= 1024 * 1024) + return -1; + l = length; + data = pp = solv_malloc(l + 512); + for (; l > 0; l -= 512, pp += 512) + if (readblock(th->fp, (unsigned char *)pp)) + { + solv_free(data); + return -1; + } + type = 3; /* extension */ + if (th->blk[156] == 'L') + { + solv_free(th->path); + th->path = data; + length = 0; + break; + } + pp = data; + while (length > 0) + { + int ll = 0; + int l; + for (l = 0; l < length && pp[l] >= '0' && pp[l] <= '9'; l++) + ll = ll * 10 + (pp[l] - '0'); + if (l == length || pp[l] != ' ' || ll < 1 || ll > length || pp[ll - 1] != '\n') + { + solv_free(data); + return -1; + } + length -= ll; + pp += l + 1; + ll -= l + 1; + pp[ll - 1] = 0; + if (!strncmp(pp, "path=", 5)) + { + solv_free(th->path); + th->path = solv_strdup(pp + 5); + } + pp += ll; + } + solv_free(data); + th->ispax = 1; + length = 0; + break; + } + default: + type = 3; /* extension */ + break; + } + if ((type == 1 || type == 2) && !th->path) + { + char path[157]; + memcpy(path, th->blk, 156); + path[156] = 0; + if (!memcmp(th->blk + 257, "ustar\0\060\060", 8) && !th->path && th->blk[345]) + { + /* POSIX ustar with prefix */ + char prefix[156]; + memcpy(prefix, th->blk + 345, 155); + prefix[155] = 0; + l = strlen(prefix); + if (prefix[l - 1] == '/') + prefix[l - 1] = 0; + th->path = solv_dupjoin(prefix, "/", path); + } + else + th->path = solv_dupjoin(path, 0, 0); + } + if (type == 1 || type == 2) + { + l = strlen(th->path); + if (l && th->path[l - 1] == '/') + { + if (l > 1) + th->path[l - 1] = 0; + type = 2; + } + } + if (type != 3) + break; + while (length > 0) + { + r = readblock(th->fp, th->blk); + if (r) + return r; + length -= 512; + } + } + th->type = type; + th->length = length; + return 1; +} + +static Offset +adddep(Repo *repo, Offset olddeps, char *line) +{ + Pool *pool = repo->pool; + char *p; + Id id; + + while (*line == ' ' && *line == '\t') + line++; + p = line; + while (*p && *p != ' ' && *p != '\t' && *p != '<' && *p != '=' && *p != '>') + p++; + id = pool_strn2id(pool, line, p - line, 1); + while (*p == ' ' && *p == '\t') + p++; + if (*p == '<' || *p == '=' || *p == '>') + { + int flags = 0; + for (;; p++) + { + if (*p == '<') + flags |= REL_LT; + else if (*p == '=') + flags |= REL_EQ; + else if (*p == '>') + flags |= REL_GT; + else + break; + } + while (*p == ' ' && *p == '\t') + p++; + line = p; + while (*p && *p != ' ' && *p != '\t') + p++; + id = pool_rel2id(pool, id, pool_strn2id(pool, line, p - line, 1), flags, 1); + } + return repo_addid_dep(repo, olddeps, id, 0); +} + +Id +repo_add_arch_pkg(Repo *repo, const char *fn, int flags) +{ + Pool *pool = repo->pool; + Repodata *data; + FILE *fp; + struct tarhead th; + char line[4096]; + int ignoreline; + Solvable *s; + int l, fd; + struct stat stb; + void *pkgidhandle = 0; + + data = repo_add_repodata(repo, flags); + if ((fd = open(fn, O_RDONLY, 0)) < 0) + { + pool_debug(pool, SOLV_ERROR, "repo_add_arch_pkg: %s: %s\n", fn, strerror(errno)); + return 0; + } + if (fstat(fd, &stb)) + { + pool_debug(pool, SOLV_ERROR, "repo_add_arch_pkg: %s: fstat failed\n", fn); + close(fd); + return 0; + } + if (!(fp = solv_xfopen_fd(fn, fd, "r"))) + { + pool_debug(pool, SOLV_ERROR, "repo_add_arch_pkg: %s: fdopen failed\n", fn); + close(fd); + return 0; + } + s = 0; + inittarhead(&th, fp); + while (gettarhead(&th) > 0) + { + if (th.type != 1 || strcmp(th.path, ".PKGINFO") != 0) + { + skipentry(&th); + continue; + } + ignoreline = 0; + s = pool_id2solvable(pool, repo_add_solvable(repo)); + if (flags & ARCH_ADD_WITH_PKGID) + pkgidhandle = solv_chksum_create(REPOKEY_TYPE_MD5); + while (getsentry(&th, line, sizeof(line))) + { + l = strlen(line); + if (l == 0) + continue; + if (pkgidhandle) + solv_chksum_add(pkgidhandle, line, l); + if (line[l - 1] != '\n') + { + ignoreline = 1; + continue; + } + if (ignoreline) + { + ignoreline = 0; + continue; + } + line[--l] = 0; + if (l == 0 || line[0] == '#') + continue; + if (!strncmp(line, "pkgname = ", 10)) + s->name = pool_str2id(pool, line + 10, 1); + else if (!strncmp(line, "pkgver = ", 9)) + s->evr = pool_str2id(pool, line + 9, 1); + else if (!strncmp(line, "pkgdesc = ", 10)) + { + repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line + 10); + repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line + 10); + } + else if (!strncmp(line, "url = ", 6)) + repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line + 6); + else if (!strncmp(line, "builddate = ", 12)) + repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line + 12, 0, 10)); + else if (!strncmp(line, "packager = ", 11)) + repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line + 11); + else if (!strncmp(line, "size = ", 7)) + repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line + 7, 0, 10)); + else if (!strncmp(line, "arch = ", 7)) + s->arch = pool_str2id(pool, line + 7, 1); + else if (!strncmp(line, "license = ", 10)) + repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_LICENSE, line + 10); + else if (!strncmp(line, "replaces = ", 11)) + s->obsoletes = adddep(repo, s->obsoletes, line + 11); + else if (!strncmp(line, "group = ", 8)) + repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line + 8); + else if (!strncmp(line, "depend = ", 9)) + s->requires = adddep(repo, s->requires, line + 9); + else if (!strncmp(line, "optdepend = ", 12)) + { + char *p = strchr(line, ':'); + if (p) + *p = 0; + s->suggests = adddep(repo, s->suggests, line + 12); + } + else if (!strncmp(line, "conflict = ", 11)) + s->conflicts = adddep(repo, s->conflicts, line + 11); + else if (!strncmp(line, "provides = ", 11)) + s->provides = adddep(repo, s->provides, line + 11); + } + break; + } + freetarhead(&th); + fclose(fp); + if (s && !s->name) + { + repo_free_solvable_block(repo, s - pool->solvables, 1, 1); + s = 0; + } + if (s) + { + if (!s->arch) + s->arch = ARCH_NOARCH; + if (!s->evr) + s->evr = ID_EMPTY; + s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + repodata_set_location(data, s - pool->solvables, 0, 0, fn); + repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, (unsigned long long)stb.st_size); + if (pkgidhandle) + { + unsigned char pkgid[16]; + solv_chksum_free(pkgidhandle, pkgid); + repodata_set_bin_checksum(data, s - pool->solvables, SOLVABLE_PKGID, REPOKEY_TYPE_MD5, pkgid); + pkgidhandle = 0; + } + } + if (pkgidhandle) + solv_chksum_free(pkgidhandle, 0); + if (!(flags & REPO_NO_INTERNALIZE)) + repodata_internalize(data); + return s ? s - pool->solvables : 0; +} + +static char *getsentrynl(struct tarhead *th, char *s, int size) +{ + int l; + if (!getsentry(th, s, size)) + { + *s = 0; /* eof */ + return 0; + } + l = strlen(s); + if (!l) + return 0; + if (l && s[l - 1] == '\n') + { + s[l - 1] = 0; + return s; + } + while (getsentry(th, s, size)) + { + l = strlen(s); + if (!l || s[l - 1] == '\n') + return 0; + } + *s = 0; /* eof */ + return 0; +} + +int +repo_add_arch_repo(Repo *repo, FILE *fp, int flags) +{ + Pool *pool = repo->pool; + Repodata *data; + data = repo_add_repodata(repo, flags); + struct tarhead th; + char *lastdn = 0; + int l, lastdnlen = 0; + char line[4096]; + Solvable *s = 0; + int havesha256 = 0; + + inittarhead(&th, fp); + while (gettarhead(&th) > 0) + { + char *bn; + if (th.type != 1) + { + skipentry(&th); + continue; + } + bn = strrchr(th.path, '/'); + if (!bn || (strcmp(bn + 1, "desc") != 0 && strcmp(bn + 1, "depends") != 0)) + { + skipentry(&th); + continue; + } + if (!lastdn || (bn - th.path) != lastdnlen || strncmp(lastdn, th.path, lastdnlen) != 0) + { + if (s) + { + if (s && !s->name) + { + repo_free_solvable_block(repo, s - pool->solvables, 1, 1); + s = 0; + } + if (s) + { + if (!s->arch) + s->arch = ARCH_NOARCH; + if (!s->evr) + s->evr = ID_EMPTY; + s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + } + } + solv_free(lastdn); + lastdn = solv_strdup(th.path); + lastdnlen = bn - th.path; + s = pool_id2solvable(pool, repo_add_solvable(repo)); + havesha256 = 0; + } + while (getsentry(&th, line, sizeof(line))) + { + l = strlen(line); + if (l == 0 || line[l - 1] != '\n') + continue; + line[--l] = 0; + if (l <= 2 || line[0] != '%' || line[l - 1] != '%') + continue; + if (!strcmp(line, "%FILENAME%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_location(data, s - pool->solvables, 0, 0, line); + } + else if (!strcmp(line, "%NAME%")) + { + if (getsentrynl(&th, line, sizeof(line))) + s->name = pool_str2id(pool, line, 1); + } + else if (!strcmp(line, "%VERSION%")) + { + if (getsentrynl(&th, line, sizeof(line))) + s->evr = pool_str2id(pool, line, 1); + } + else if (!strcmp(line, "%DESC%")) + { + if (getsentrynl(&th, line, sizeof(line))) + { + repodata_set_str(data, s - pool->solvables, SOLVABLE_SUMMARY, line); + repodata_set_str(data, s - pool->solvables, SOLVABLE_DESCRIPTION, line); + } + } + else if (!strcmp(line, "%GROUPS%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_GROUP, line); + } + else if (!strcmp(line, "%CSIZE%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_num(data, s - pool->solvables, SOLVABLE_DOWNLOADSIZE, strtoull(line, 0, 10)); + } + else if (!strcmp(line, "%ISIZE%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_num(data, s - pool->solvables, SOLVABLE_INSTALLSIZE, strtoull(line, 0, 10)); + } + else if (!strcmp(line, "%MD5SUM%")) + { + if (getsentrynl(&th, line, sizeof(line)) && !havesha256) + repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, REPOKEY_TYPE_MD5, line); + } + else if (!strcmp(line, "%SHA256SUM%")) + { + if (getsentrynl(&th, line, sizeof(line))) + { + repodata_set_checksum(data, s - pool->solvables, SOLVABLE_CHECKSUM, REPOKEY_TYPE_SHA256, line); + havesha256 = 1; + } + } + else if (!strcmp(line, "%URL%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_str(data, s - pool->solvables, SOLVABLE_URL, line); + } + else if (!strcmp(line, "%LICENSE%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_str(data, s - pool->solvables, SOLVABLE_LICENSE, line); + } + else if (!strcmp(line, "%ARCH%")) + { + if (getsentrynl(&th, line, sizeof(line))) + s->arch = pool_str2id(pool, line, 1); + } + else if (!strcmp(line, "%BUILDDATE%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_num(data, s - pool->solvables, SOLVABLE_BUILDTIME, strtoull(line, 0, 10)); + } + else if (!strcmp(line, "%PACKAGER%")) + { + if (getsentrynl(&th, line, sizeof(line))) + repodata_set_poolstr(data, s - pool->solvables, SOLVABLE_PACKAGER, line); + } + else if (!strcmp(line, "%REPLACES%")) + { + while (getsentrynl(&th, line, sizeof(line)) && *line) + s->obsoletes = adddep(repo, s->obsoletes, line); + } + else if (!strcmp(line, "%DEPENDS%")) + { + while (getsentrynl(&th, line, sizeof(line)) && *line) + s->requires = adddep(repo, s->requires, line); + } + else if (!strcmp(line, "%CONFLICTS%")) + { + while (getsentrynl(&th, line, sizeof(line)) && *line) + s->conflicts = adddep(repo, s->conflicts, line); + } + else if (!strcmp(line, "%PROVIDES%")) + { + while (getsentrynl(&th, line, sizeof(line)) && *line) + s->provides = adddep(repo, s->provides, line); + } + else if (!strcmp(line, "%OPTDEPENDS%")) + { + while (getsentrynl(&th, line, sizeof(line)) && *line) + { + char *p = strchr(line, ':'); + if (p && p > line) + *p = 0; + s->suggests = adddep(repo, s->suggests, line); + } + } + while (*line) + getsentrynl(&th, line, sizeof(line)); + } + } + if (s) + { + if (s && !s->name) + { + repo_free_solvable_block(repo, s - pool->solvables, 1, 1); + s = 0; + } + if (s) + { + if (!s->arch) + s->arch = ARCH_NOARCH; + if (!s->evr) + s->evr = ID_EMPTY; + s->provides = repo_addid_dep(repo, s->provides, pool_rel2id(pool, s->name, s->evr, REL_EQ, 1), 0); + } + } + if (!(flags & REPO_NO_INTERNALIZE)) + repodata_internalize(data); + return 0; +} + diff --git a/ext/repo_arch.h b/ext/repo_arch.h new file mode 100644 index 0000000..65be8fe --- /dev/null +++ b/ext/repo_arch.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +#define ARCH_ADD_WITH_PKGID (1 << 8) + +extern Id repo_add_arch_pkg(Repo *repo, const char *fn, int flags); +extern Id repo_add_arch_repo(Repo *repo, FILE *fp, int flags); + diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 86f804d..d5173ae 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -69,6 +69,16 @@ TARGET_LINK_LIBRARIES (mdk2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIES} SET (tools_list ${tools_list} mdk2solv) ENDIF (ENABLE_MDKREPO) +IF (ENABLE_ARCHREPO) +ADD_EXECUTABLE (archpkgs2solv archpkgs2solv.c) +TARGET_LINK_LIBRARIES (archpkgs2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIES}) + +ADD_EXECUTABLE (archrepo2solv archrepo2solv.c) +TARGET_LINK_LIBRARIES (archrepo2solv toolstuff libsolvext libsolv ${SYSTEM_LIBRARIES}) + +SET (tools_list ${tools_list} archpkgs2solv archrepo2solv) +ENDIF (ENABLE_ARCHREPO) + ADD_EXECUTABLE (installcheck installcheck.c) TARGET_LINK_LIBRARIES (installcheck libsolvext libsolv ${SYSTEM_LIBRARIES}) diff --git a/tools/archpkgs2solv.c b/tools/archpkgs2solv.c new file mode 100644 index 0000000..d2e19c6 --- /dev/null +++ b/tools/archpkgs2solv.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * archpkgs2solv - create a solv file from multiple arch packages + * + */ + +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#include "util.h" +#include "pool.h" +#include "repo.h" +#include "repo_arch.h" +#include "repo_solv.h" +#include "common_write.h" + +static char * +fgets0(char *s, int size, FILE *stream) +{ + char *p = s; + int c; + + while (--size > 0) + { + c = getc(stream); + if (c == EOF) + { + if (p == s) + return 0; + c = 0; + } + *p++ = c; + if (!c) + return s; + } + *p = 0; + return s; +} + +int +main(int argc, char **argv) +{ + const char **pkgs = 0; + char *manifest = 0; + int manifest0 = 0; + int i, c, npkgs = 0; + Pool *pool = pool_create(); + Repo *repo; + FILE *fp; + char buf[4096], *p; + const char *basefile = 0; + int flags = 0; + + while ((c = getopt(argc, argv, "0b:m:i")) >= 0) + { + switch(c) + { + case 'b': + basefile = optarg; + break; + case 'm': + manifest = optarg; + break; + case '0': + manifest0 = 1; + break; + case 'i': + flags |= ARCH_ADD_WITH_PKGID; + break; + default: + exit(1); + } + } + if (manifest) + { + if (!strcmp(manifest, "-")) + fp = stdin; + else if ((fp = fopen(manifest, "r")) == 0) + { + perror(manifest); + exit(1); + } + for (;;) + { + if (manifest0) + { + if (!fgets0(buf, sizeof(buf), fp)) + break; + } + else + { + if (!fgets(buf, sizeof(buf), fp)) + break; + if ((p = strchr(buf, '\n')) != 0) + *p = 0; + } + pkgs = solv_extend(pkgs, npkgs, 1, sizeof(char *), 15); + pkgs[npkgs++] = strdup(buf); + } + if (fp != stdin) + fclose(fp); + } + while (optind < argc) + { + pkgs = solv_extend(pkgs, npkgs, 1, sizeof(char *), 15); + pkgs[npkgs++] = solv_strdup(argv[optind++]); + } + repo = repo_create(pool, "archpkgs2solv"); + repo_add_repodata(repo, 0); + for (i = 0; i < npkgs; i++) + repo_add_arch_pkg(repo, pkgs[i], REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE|flags); + repo_internalize(repo); + tool_write(repo, basefile, 0); + pool_free(pool); + for (c = 0; c < npkgs; c++) + solv_free((char *)pkgs[c]); + solv_free(pkgs); + exit(0); +} + diff --git a/tools/archrepo2solv.c b/tools/archrepo2solv.c new file mode 100644 index 0000000..e671c49 --- /dev/null +++ b/tools/archrepo2solv.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012, Novell Inc. + * + * This program is licensed under the BSD license, read LICENSE.BSD + * for further information + */ + +/* + * archrepo2solv.c + * + * parse archlinux repo file + * + * reads from stdin + * writes to stdout + */ + +#include <sys/types.h> +#include <limits.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> + +#include "pool.h" +#include "repo.h" +#include "repo_arch.h" +#include "solv_xfopen.h" +#include "common_write.h" + + +static void +usage(int status) +{ + fprintf(stderr, "\nUsage:\n" + "archrepo2solv\n" + " reads a repository from <stdin> and writes a .solv file to <stdout>\n" + " -h : print help & exit\n" + ); + exit(status); +} + +int +main(int argc, char **argv) +{ + Pool *pool; + Repo *repo; + int c; + + while ((c = getopt(argc, argv, "h")) >= 0) + { + switch(c) + { + case 'h': + usage(0); + break; + default: + usage(1); + break; + } + } + pool = pool_create(); + repo = repo_create(pool, "<stdin>"); + repo_add_arch_repo(repo, stdin, 0); + tool_write(repo, 0, 0); + pool_free(pool); + exit(0); +} diff --git a/tools/mdk2solv.c b/tools/mdk2solv.c index db6c97b..cec705e 100644 --- a/tools/mdk2solv.c +++ b/tools/mdk2solv.c @@ -49,7 +49,7 @@ main(int argc, char **argv) char *infofile; int c; - while ((c = getopt(argc, argv, "i:")) >= 0) + while ((c = getopt(argc, argv, "hi:")) >= 0) { switch(c) { |