PERFORCE change 180781 for review

Ivan Voras ivoras at FreeBSD.org
Sun Jul 11 21:11:10 UTC 2010


http://p4web.freebsd.org/@@180781?ac=10

Change 180781 by ivoras at betelgeuse on 2010/07/11 21:10:41

	Read the PKGPATCHINDEX

Affected files ...

.. //depot/projects/soc2010/pkg_patch/src/patch/Makefile#24 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.c#14 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.h#14 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#23 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#23 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/main.c#24 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#22 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#22 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.c#7 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.h#6 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#22 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/support.c#21 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/updateweb.c#2 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/updateweb.h#2 edit

Differences ...

==== //depot/projects/soc2010/pkg_patch/src/patch/Makefile#24 (text+ko) ====

@@ -8,6 +8,9 @@
 WARNS?=	4
 WFORMAT?=	1
 
-LDADD=	-lmd -pthread
+LDADD=	-lmd -lfetch -pthread
+
+#CFLAGS+=-g
+#LDADD+=-g
 
 .include <bsd.prog.mk>

==== //depot/projects/soc2010/pkg_patch/src/patch/applypatch.c#14 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/applypatch.h#14 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#23 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#23 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/main.c#24 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#22 (text+ko) ====

@@ -48,7 +48,6 @@
 	struct filelist *fl;
 	unsigned n_changed_files;
 	FILE *fp;
-	time_t tm;
 	
 	if (realpath(file_old, fold) == NULL)
 		err(1, "Error resolving path: %s", file_old);
@@ -172,9 +171,8 @@
 	fp = fopen(tmp, "w");
 	if (fp == NULL)
 		err(1, "Cannot open file for writing: %s", tmp);
-	time(&tm);
 	fprintf(fp, "# FreeBSD package patch archive created on %s\n",
-		ctime(&tm));
+		time_ctime(-1));
 	fprintf(fp, "@version %d.%d\n", PKGPATCH_VERSION_MAJOR,
 	    PKGPATCH_VERSION_MINOR);
 	parse_package_name(fold, tmp, tmp2, NULL);

==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#22 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.c#7 (text+ko) ====

@@ -80,6 +80,9 @@
 		    dnew);
 	if (filelist_intersect_pkg(&fl_old, &fl_new, &pkglist) != 0)
 		errx(1, "Error matching packages");
+	fprintf(fpl, "# Created by mkpatchdir at %s\n", time_ctime(-1));
+	fprintf(fpl, "@version %d.%d\n", PKGPATCH_VERSION_MAJOR,
+	    PKGPATCH_VERSION_MINOR);
 	
 	SLIST_FOREACH(pl, &pkglist, linkage) {
 		char pname[PATH_MAX];

==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatchdir.h#6 (text+ko) ====


==== //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#22 (text+ko) ====

@@ -29,6 +29,12 @@
 #ifndef _PATH_BSPATCH
 #define _PATH_BSPATCH	"/usr/bin/bspatch"
 #endif
+#ifndef _PATH_GZIP
+#define	_PATH_GZIP	"/usr/bin/gzip"
+#endif
+#ifndef _PATH_BZIP2
+#define	_PATH_BZIP2	"/usr/bin/bzip2"
+#endif
 #ifndef _PATH_PKG_CREATE
 #define _PATH_PKG_CREATE	"/usr/sbin/pkg_create"
 #endif
@@ -43,6 +49,10 @@
 #define PKG_FORMAT_EXT	"tbz"
 #endif
 
+#ifndef PKGNAME_MAX
+#define	PKGNAME_MAX	200
+#endif
+
 #define PKGPATCH_FNAME		"+PKGPATCH"
 #define PKGPATCH_VERSION_MAJOR	1
 #define PKGPATCH_VERSION_MINOR	0
@@ -82,8 +92,8 @@
 
 SLIST_HEAD(pkgjoinlist_head, pkgjoinlist);
 struct pkgjoinlist {
-	char		name1[PATH_MAX];
-	char		name2[PATH_MAX];
+	char		name1[PKGNAME_MAX];
+	char		name2[PKGNAME_MAX];
 	SLIST_ENTRY(pkgjoinlist)	linkage;
 };
 
@@ -118,7 +128,7 @@
 
 #endif
 
-
+int strendswith(const char *bigstr, const char *end);
 int rm_rf(char *dir);
 int cp(char *from, char *to);
 int pkgxjob_start(struct pkgxjob *job, char *dir, char *filename);
@@ -142,5 +152,6 @@
 unsigned int pplist_count(struct pplist_head *ppl);
 char *time_to_iso8601(time_t t);
 time_t iso8601_to_time(char *t);
+char *time_ctime(time_t t);
 
 #endif

==== //depot/projects/soc2010/pkg_patch/src/patch/support.c#21 (text+ko) ====

@@ -38,6 +38,23 @@
 
 
 /*
+ * Tests if the given string ends with the other string. The return value is
+ * analogous to strcmp().
+ */
+int
+strendswith(const char *base, const char *end)
+{
+	int base_len, end_len;
+	
+	base_len = strlen(base);
+	end_len = strlen(end);
+	if (base_len < end_len)
+		return -1;
+	return strncmp(base + (base_len - end_len), end, end_len);
+}
+
+
+/*
  * Removes a directory hierarchy.
  */
 int
@@ -261,8 +278,8 @@
 filelist_intersect_pkg(struct filelist_head *flist1, struct filelist_head *flist2,
     struct pkgjoinlist_head *pkgisect)
 {
-	char basename1[PATH_MAX], version1[PATH_MAX], suffix1[20];
-	char basename2[PATH_MAX], version2[PATH_MAX], suffix2[20];
+	char basename1[PKGNAME_MAX], version1[PKGNAME_MAX], suffix1[20];
+	char basename2[PKGNAME_MAX], version2[PKGNAME_MAX], suffix2[20];
 	struct filelist *fl1, *fl2;
 	struct pkgjoinlist *pi;
 	int found;
@@ -272,15 +289,15 @@
 		parse_package_name(fl1->filename, basename1, version1, suffix1);
 		SLIST_FOREACH(fl2, flist2, linkage) {
 			parse_package_name(fl2->filename, basename2, version2, suffix2);
-			if (strncmp(basename1, basename2, PATH_MAX) == 0) {
+			if (strncmp(basename1, basename2, PKGNAME_MAX) == 0) {
 				found = 1;
 				break;
 			}
 		}
 		if (found) {
 			pi = calloc(1, sizeof(*pi));
-			strncpy(pi->name1, fl1->filename, PATH_MAX);
-			strncpy(pi->name2, fl2->filename, PATH_MAX);
+			strncpy(pi->name1, fl1->filename, PKGNAME_MAX);
+			strncpy(pi->name2, fl2->filename, PKGNAME_MAX);
 			SLIST_INSERT_HEAD(pkgisect, pi, linkage);
 		}
 	}
@@ -601,3 +618,13 @@
 		return (0);
 	return timegm(&tms);
 }
+
+
+/* Convert given time_t to asctime */
+char *
+time_ctime(time_t t)
+{
+	if (t == -1)
+		t = time(NULL);
+	return (ctime(&t));
+}

==== //depot/projects/soc2010/pkg_patch/src/patch/updateweb.c#2 (text+ko) ====

@@ -27,32 +27,183 @@
 #include <unistd.h>
 #include <assert.h>
 #include <err.h>
+#include <fetch.h>
 
 #include <pkg.h>
 #include "pkg_patch.h"
 #include "updateweb.h"
 #include "hashjob.h"
 
+
+STAILQ_HEAD(patchrec_list, patchrec);
+struct patchrec {
+	char 	source[PKGNAME_MAX];
+	char 	target[PKGNAME_MAX];
+	char 	patch_name[PATH_MAX];
+	time_t 	patch_timestamp;
+	STAILQ_ENTRY(patchrec)	linkage;
+};
+
+static int
+read_pkgpatchindex_file(struct patchrec_list *prlist, char *fname)
+{
+	char line[4*PKGNAME_MAX];
+	char *cmd, *param;
+	FILE *f;
+	char *p;
+	
+	f = fopen(fname, "r");
+	if (f == NULL)
+		return (-1);
+	
+	while (fgets(line, sizeof(line), f) != NULL) {
+		int vmajor, vminor;
+		
+		p = strchr(line, '#');
+		if (p != NULL)
+			*p = '\0';
+		while (line[strlen(line)-1] == '\n' || line[strlen(line)-1] == ' ')
+			line[strlen(line)-1] = '\0';
+		if (line[0] == '\0')
+			continue;
+		if (line[0] != '@') {
+			warn("Line is not a command: %s", line);
+			break;
+		}
+		cmd = line + 1;
+		p = strchr(cmd, ' ');
+		*p = '\0';
+		param = p + 1;
+		if (strcmp(cmd, "version") == 0) {
+			if (sscanf(param, "%d.%d", &vmajor, &vminor) != 2) {
+				warnx("Cannot parse version: %s", param);
+				break;
+			}
+			if (vmajor != PKGPATCH_VERSION_MAJOR) {
+				warnx("Major version mismatch: got %d expected %d",
+				    vmajor, PKGPATCH_VERSION_MAJOR);
+				break;
+			}
+			if (vminor > PKGPATCH_VERSION_MINOR) {
+				warnx("Minor version cannot be handled: %d",
+				    vminor);
+				break;
+			}
+		} else if (strcmp(cmd, "havepatch") == 0) {
+			char src[PKGNAME_MAX], tgt[PKGNAME_MAX],
+			    patch[PATH_MAX], tstamp[PKGNAME_MAX];
+			struct patchrec *pr;
+			
+			if (sscanf(param, "%s %s %s %s", src, tgt, patch,
+			    tstamp) != 4) {
+				warnx("Cannot parse havepatch line: %s", line);
+				break;
+			}
+			pr = calloc(1, sizeof(*pr));
+			strncpy(pr->source, src, PKGNAME_MAX);
+			strncpy(pr->target, tgt, PKGNAME_MAX);
+			strncpy(pr->patch_name, patch, PATH_MAX);
+			pr->patch_timestamp = iso8601_to_time(tstamp);
+			STAILQ_INSERT_TAIL(prlist, pr, linkage);
+		}
+	}
+	fclose(f);
+	return (0);
+}
+
+
+static void
+split_filename(char *path, char *fname, int len)
+{
+	strncpy(fname, strrchr(path, '/')+1, len);
+}
+
+
+static int
+download_file(char *url, char *fname)
+{
+	FILE *fin, *fout;
+	size_t bs = 128*1024;
+	char *buf;
+	int er;
+	
+	fout = fopen(fname, "w");
+	if (fout == NULL)
+		return (-1);
+	fin = fetchGetURL(url, "");
+	if (fin == NULL)
+		return (-1);
+	buf = malloc(bs);
+	while (bs > 0) {
+		bs = fread(buf, 1, bs, fin);
+		if (bs > 0)
+			fwrite(buf, 1, bs, fout);
+	}
+	free(buf);
+	er = ferror(fin);
+	fclose(fin);
+	fclose(fout);
+	if (er) {
+		warn("Error reading %s", url);
+		return (-1);
+	}
+	return (0);
+}
+
+
 void
-perform_updateweb(const char *aurl)
+perform_updateweb(const char *in_url)
 {
-	char url_base[PATH_MAX], url_index[PATH_MAX];
+	char url_base[PATH_MAX], url_index[PATH_MAX], index_fname[PATH_MAX];
+	char local_index[PATH_MAX];
+	struct patchrec_list prlist;
+	struct patchrec *pr;
 	
-	if (aurl == NULL)
-		aurl = PKGPATCH_SITE_URL;
+	if (in_url == NULL)
+		in_url = PKGPATCH_SITE_URL;
 	
-	if (strlen(aurl) > strlen(PKGPATCHINDEX_FNAME) &&
-	    strncmp(aurl + (strlen(aurl) - strlen(PKGPATCHINDEX_FNAME)),
-	    PKGPATCHINDEX_FNAME, strlen(PKGPATCHINDEX_FNAME)) == 0) {
-		/* We have been given a URL ending with PKGPATCH_SITE_URL */
-		strncpy(url_base, aurl, strlen(aurl) - strlen(PKGPATCHINDEX_FNAME));
-	} else
-		strncpy(url_base, aurl, PATH_MAX);
-
-	if (url_base[strlen(url_base)-1] == '/')
-		url_base[strlen(url_base)-1] = '\0';
-	snprintf(url_index, PATH_MAX, "%s/%s", url_base, PKGPATCHINDEX_FNAME);
+	if (strendswith(in_url, PKGPATCHINDEX_FNAME) == 0) {
+		/* We have been given an URL ending with PKGPATCHINDEX_FNAME.
+		 * Technically this is an error, but we'll just strip it and
+		 * continue as we would with only the base url. */
+		strncpy(url_base, in_url, strlen(in_url) - 
+		    strlen(PKGPATCHINDEX_FNAME));
+		strncpy(url_index, in_url, PATH_MAX);
+	} else {
+		strncpy(url_base, in_url, PATH_MAX);
+		if (url_base[strlen(url_base)-1] == '/')
+			url_base[strlen(url_base)-1] = '\0';
+		snprintf(url_index, PATH_MAX, "%s/%s", url_base,
+			PKGPATCHINDEX_FNAME);
+	}
 	
 	if (Verbose > 1)
-		printf("Patching from %s (%s)\n", url_base, url_index);
+		printf("Patching from %s (index file: %s)\n", url_base, url_index);
+	
+	split_filename(url_index, index_fname, PATH_MAX);
+	snprintf(local_index, PATH_MAX, "%s/%s", my_tmp, index_fname);
+	if (Verbose > 2)
+		printf("Downloading pkgpatchindex to %s\n", local_index);
+	if (download_file(url_index, local_index) != 0)
+		err(1, "Cannot download %s to %s", url_index, local_index);
+	
+	if (strendswith(local_index, ".gz") == 0) {
+		vsystem("%s -d %s", _PATH_GZIP, local_index);
+		local_index[strlen(local_index)-3] = '\0';
+		if (Verbose > 2)
+			printf("Decompressed index to: %s\n", local_index);
+	}
+	if (strendswith(local_index, ".bz2") == 0) {
+		vsystem("%s -d %s", _PATH_BZIP2, local_index);
+		local_index[strlen(local_index)-4] = '\0';
+		if (Verbose > 2)
+			printf("Decompressed index to: %s\n", local_index);
+	}
+	STAILQ_INIT(&prlist);
+	if (read_pkgpatchindex_file(&prlist, local_index) != 0)
+		err(1, "Cannot read pkgpatchindex: %s", local_index);
+	if (Verbose > 2)
+		STAILQ_FOREACH(pr, &prlist, linkage)
+			printf("Patch available: %s to %s via %s\n", pr->source,
+			    pr->target, pr->patch_name);
 }

==== //depot/projects/soc2010/pkg_patch/src/patch/updateweb.h#2 (text+ko) ====



More information about the p4-projects mailing list