diff options
Diffstat (limited to 'src/package.c')
-rw-r--r-- | src/package.c | 129 |
1 files changed, 110 insertions, 19 deletions
diff --git a/src/package.c b/src/package.c index 6f41fc58..d41e1d85 100644 --- a/src/package.c +++ b/src/package.c @@ -24,39 +24,45 @@ #include <stdlib.h> #include <limits.h> #include <fcntl.h> -#include <unistd.h> #include <string.h> -#include "list.h" -#include "package.h" -#include "db.h" +#include <libtar.h> +#include <zlib.h> #include "util.h" -#include "pacsync.h" -#include "pacman.h" - -extern tartype_t gztype; +#include "package.h" pkginfo_t* load_pkg(char *pkgfile, unsigned short output) { char *expath; - char *descfile; int i; + int config = 0; + int filelist = 0; TAR *tar; pkginfo_t *info = NULL; PMList *backup = NULL; PMList *lp; + tartype_t gztype = { + (openfunc_t) gzopen_frontend, + (closefunc_t)gzclose, + (readfunc_t) gzread, + (writefunc_t)gzwrite + }; info = newpkg(); - descfile = strdup("/tmp/pacman_XXXXXX"); if(tar_open(&tar, pkgfile, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { perror("could not open package"); return(NULL); } - vprint("load_pkg: loading filelist from package...\n"); for(i = 0; !th_read(tar); i++) { + if(config && filelist) { + /* we have everything we need */ + break; + } if(!strcmp(th_get_pathname(tar), ".PKGINFO")) { + char *descfile; + /* extract this file into /tmp. it has info for us */ - vprint("load_pkg: found package description file.\n"); + descfile = strdup("/tmp/pacman_XXXXXX"); mkstemp(descfile); tar_extract_file(tar, descfile); /* parse the info file */ @@ -74,14 +80,43 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output) info->backup = list_add(info->backup, lp->data); } } + config = 1; + FREE(descfile); continue; - } - if(!strcmp(th_get_pathname(tar), "._install")) { + } else if(!strcmp(th_get_pathname(tar), "._install") || !strcmp(th_get_pathname(tar), ".INSTALL")) { info->scriptlet = 1; + } else if(!strcmp(th_get_pathname(tar), ".FILELIST")) { + /* Build info->files from the filelist */ + FILE *fp; + char *fn; + char *str; + + MALLOC(str, PATH_MAX); + fn = strdup("/tmp/pacman_XXXXXX"); + mkstemp(fn); + tar_extract_file(tar, fn); + fp = fopen(fn, "r"); + while(!feof(fp)) { + if(fgets(str, PATH_MAX, fp) == NULL) { + continue; + } + trim(str); + info->files = list_add(info->files, strdup(str)); + } + FREE(str); + fclose(fp); + if(unlink(fn)) { + fprintf(stderr, "warning: could not remove tempfile %s\n", fn); + } + FREE(fn); + filelist = 1; } else { - expath = strdup(th_get_pathname(tar)); - /* add the path to the list */ - info->files = list_add(info->files, expath); + if(!filelist) { + /* no .FILELIST present in this package.. build the filelist the */ + /* old-fashioned way, one at a time */ + expath = strdup(th_get_pathname(tar)); + info->files = list_add(info->files, expath); + } } if(TH_ISREG(tar) && tar_skip_regfile(tar)) { @@ -93,9 +128,8 @@ pkginfo_t* load_pkg(char *pkgfile, unsigned short output) expath = NULL; } tar_close(tar); - FREE(descfile); - if(!strlen(info->name) || !strlen(info->version)) { + if(!config) { fprintf(stderr, "load_pkg: missing package info file in %s\n", pkgfile); return(NULL); } @@ -147,6 +181,8 @@ int parse_descfile(char *descfile, pkginfo_t *info, PMList **backup, int output) strncpy(info->version, ptr, sizeof(info->version)); } else if(!strcmp(key, "PKGDESC")) { strncpy(info->desc, ptr, sizeof(info->desc)); + } else if(!strcmp(key, "URL")) { + strncpy(info->url, ptr, sizeof(info->url)); } else if(!strcmp(key, "BUILDDATE")) { strncpy(info->builddate, ptr, sizeof(info->builddate)); } else if(!strcmp(key, "INSTALLDATE")) { @@ -188,6 +224,7 @@ pkginfo_t* newpkg() pkg->name[0] = '\0'; pkg->version[0] = '\0'; pkg->desc[0] = '\0'; + pkg->url[0] = '\0'; pkg->builddate[0] = '\0'; pkg->installdate[0] = '\0'; pkg->packager[0] = '\0'; @@ -227,4 +264,58 @@ int pkgcmp(const void *p1, const void *p2) return(strcmp(pkg1[0]->name, pkg2[0]->name)); } +/* Test for existence of a package in a PMList* + * of pkginfo_t* + * + * returns: 0 for no match + * 1 for identical match + * -1 for name-only match (version mismatch) + */ +int is_pkgin(pkginfo_t *needle, PMList *haystack) +{ + PMList *lp; + pkginfo_t *info; + + for(lp = haystack; lp; lp = lp->next) { + info = (pkginfo_t*)lp->data; + if(info && !strcmp(info->name, needle->name)) { + if(!strcmp(info->version, needle->version)) { + return(1); + } + return(-1); + } + } + return(0); +} + +/* Display the content of a package + */ +void dump_pkg(pkginfo_t *info) +{ + PMList *pm; + + if(info == NULL) { + return; + } + + printf("Name : %s\n", info->name); + printf("Version : %s\n", info->version); + printf("Packager : %s\n", info->packager); + printf("URL: : %s\n", info->url); + printf("Size : %ld\n", info->size); + printf("Build Date : %s %s\n", info->builddate, strlen(info->builddate) ? "UTC" : ""); + printf("Install Date : %s %s\n", info->installdate, strlen(info->installdate) ? "UTC" : ""); + printf("Install Script: %s\n", (info->scriptlet ? "yes" : "no")); + pm = list_sort(info->depends); + list_display("Depends On : ", pm); + FREE(pm); + pm = list_sort(info->requiredby); + list_display("Required By : ", pm); + FREE(pm); + pm = list_sort(info->conflicts); + list_display("Conflicts With: ", pm); + FREE(pm); + printf("Description : %s\n", info->desc); +} + /* vim: set ts=2 sw=2 noet: */ |