From owner-p4-projects@FreeBSD.ORG Sun Jul 11 21:11:10 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DE5E11065687; Sun, 11 Jul 2010 21:11:09 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8ACE81065673 for ; Sun, 11 Jul 2010 21:11:09 +0000 (UTC) (envelope-from ivoras@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 782C48FC24 for ; Sun, 11 Jul 2010 21:11:09 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o6BLB9T2009887 for ; Sun, 11 Jul 2010 21:11:09 GMT (envelope-from ivoras@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o6BLB9Tn009885 for perforce@freebsd.org; Sun, 11 Jul 2010 21:11:09 GMT (envelope-from ivoras@FreeBSD.org) Date: Sun, 11 Jul 2010 21:11:09 GMT Message-Id: <201007112111.o6BLB9Tn009885@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to ivoras@FreeBSD.org using -f From: Ivan Voras To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 180781 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Jul 2010 21:11:10 -0000 http://p4web.freebsd.org/@@180781?ac=10 Change 180781 by ivoras@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 ==== //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 #include #include +#include #include #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) ====