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