summaryrefslogtreecommitdiffstats
path: root/src/package.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/package.c')
-rw-r--r--src/package.c129
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: */