Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Jun 2010 16:12:15 GMT
From:      Ivan Voras <ivoras@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 180110 for review
Message-ID:  <201006221612.o5MGCFxW034865@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@180110?ac=10

Change 180110 by ivoras@betelgeuse on 2010/06/22 16:12:02

	Remove custom parsing of +CONTENTS, start working on applying the patch

Affected files ...

.. //depot/projects/soc2010/pkg_patch/src/patch/Makefile#16 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.c#6 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/applypatch.h#6 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#15 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#15 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/main.c#16 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#14 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#14 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#14 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/support.c#13 edit

Differences ...

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


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

@@ -36,128 +36,67 @@
 #include "hashjob.h"
 
 
-enum PPMETHOD { PPMETHOD_UNKNOWN, PPMETHOD_CP, PPMETHOD_BSDIFF };
+/*
+ * Create a backup package (pkg_create -b) for the given package (identified
+ * by its full name, e.g. "apache-2.2.13").
+ */
+static int
+pkg_backup(char *name)
+{
+	char pkg_file[PATH_MAX];
+	
+	if (!isinstalledpkg(name)) {
+		warnx("Package not installed: %s", name);
+		return (-1);
+	}
+	if (access(PKGPATCH_BACKUP_DIR, F_OK) != 0) {
+		if (mkdir(PKGPATCH_BACKUP_DIR, 0644) != 0) {
+			warnx("Cannot mkdir: %s", PKGPATCH_BACKUP_DIR);
+			return (-1);
+		}
+	}
+	snprintf(pkg_file, PATH_MAX, "%s/%s.%s", PKGPATCH_BACKUP_DIR, name,
+	    PKG_FORMAT_EXT);
+	if (vsystem("%s -b %s %s", _PATH_PKG_CREATE, name, pkg_file) != 0) {
+		warnx("pkg_create -b %s %s failed", name, pkg_file);
+		return (-1);
+	}
+	if (Verbose)
+		printf("Created backup package: %s\n", pkg_file);
+	return (0);
+}
 
 
-STAILQ_HEAD(pplist_head, pplist);
-struct pplist {
-	char 			filename[PATH_MAX];
-	enum PPMETHOD		method;
-	STAILQ_ENTRY(pplist)	linkage;
-};
+/*
+ * Read the given +CONTENTS file.
+ */
+static int
+read_package_contents_file(char *pfilename, Package *pkg)
+{
+	FILE *fp;
+	
+	fp = fopen(pfilename, "r");
+	if (fp == NULL) {
+		warnx("Cannot open file: %s", pfilename);
+		return (-1);
+	}
+	read_plist(pkg, fp);
+	return (0);
+}
 
 
-struct pkg_patch {
-	short int		version_major;
-	short int		version_minor;
-	char			source[PATH_MAX];
-	char			target[PATH_MAX];
-	struct pplist_head	pp_add;
-	struct pplist_head	pp_remove;
-	struct pplist_head	pp_rmdir;
-	struct pplist_head	pp_patch;
-};
-
-
-static void
-read_pkgpatch_file(char *filename, struct pkg_patch *pp)
+/*
+ * Read live/installed package metadata. The package is identified by its full
+ * name (e.g. "apache-2.2.13").
+ */
+static int
+read_package_by_name(char *name, Package *pkg)
 {
-	FILE *fp;
-	char line[PATH_MAX], *p, *p2, *p3, *cmd;
-	int llen;
-	struct pplist *pl;
+	char pfilename[PATH_MAX];
 	
-	fp = fopen(filename, "r");
-	if (fp == NULL)
-		err(1, "Cannot open file: %s", filename);
-	memset(pp, 0, sizeof(*pp));
-	STAILQ_INIT(&pp->pp_add);
-	STAILQ_INIT(&pp->pp_remove);
-	STAILQ_INIT(&pp->pp_rmdir);
-	STAILQ_INIT(&pp->pp_patch);
-	
-	while (fgets(line, PATH_MAX, fp) != NULL) {
-		llen = strlen(line);
-		if (line[llen-1] == '\n') {
-			line[llen-1] = '\0';	/* strip newline */
-			llen--;
-		}
-		p = strchr(line, '#'); 	/* skip comments */
-		if (p != NULL)
-			*p = '\0';
-		if (line[0] == '\0')	/* skip empty lines */
-			continue;
-		cmd = line;
-		p = strchr(line, ' ');
-		if (p == NULL)
-			errx(1, "Invalid command format in %s", PKGPATCH_FNAME);
-		*p++ = '\0';
-		if (strcmp(cmd, "@version") == 0) {
-			p2 = strchr(p, '.');
-			if (p2 == NULL)
-				errx(1, "Invalid version format in %s",
-				    PKGPATCH_FNAME);
-			*p2++ = '\0';
-			pp->version_major = atoi(p);
-			pp->version_minor = atoi(p2);
-		} else if (strcmp(cmd, "@source") == 0) {
-			strlcpy(pp->source, p, PATH_MAX);
-		} else if (strcmp(cmd, "@target") == 0) {
-			strlcpy(pp->target, p, PATH_MAX);
-		} else if (strcmp(cmd, "@add") == 0) {
-			pl = calloc(1, sizeof(*pl));
-			strlcpy(pl->filename, p, PATH_MAX);
-			STAILQ_INSERT_TAIL(&pp->pp_add, pl, linkage);
-		} else if (strcmp(cmd, "@remove") == 0) {
-			pl = calloc(1, sizeof(*pl));
-			strlcpy(pl->filename, p, PATH_MAX);
-			STAILQ_INSERT_TAIL(&pp->pp_remove, pl, linkage);
-		} else if (strcmp(cmd, "@rmdir") == 0) {
-			pl = calloc(1, sizeof(*pl));
-			strlcpy(pl->filename, p, PATH_MAX);
-			STAILQ_INSERT_TAIL(&pp->pp_rmdir, pl, linkage);
-		} else if (strcmp(cmd, "@patch") == 0) {
-			pl = calloc(1, sizeof(*pl));
-			p2 = strchr(p, '[');
-			if (p2 != NULL) {
-				/*
-				 * Parse options block of the form
-				 * \[name=value[,name=value...]\]
-				 */
-				char m[100], *pm, *p4, *p5;
-				
-				pm = m;
-				p3 = strchr(p2, ']');
-				assert(p3-p2 < (int)sizeof(m));
-				strlcpy(m, p2 + 1, p3 - p2);
-				p3++;
-				while (*p3 == ' ')
-					p3++;
-				strlcpy(pl->filename, p3, PATH_MAX);
-				while ((p4 = strsep(&pm, ",")) != NULL) {
-					p5 = strchr(p4, '=');
-					if (p5 != NULL)
-						*p5++ = '\0';
-					if (strcmp(p4, "method") == 0) {
-						if (p5 == NULL)
-							errx(1, "patch option "
-							    "error");
-						if (strcmp(p5, "bsdiff") == 0)
-							pl->method = 
-							    PPMETHOD_BSDIFF;
-					}
-				}
-			} else {
-				/* Default options */
-				strlcpy(pl->filename, p, PATH_MAX);
-				pl->method = PPMETHOD_CP;
-			}
-			STAILQ_INSERT_TAIL(&pp->pp_patch, pl, linkage);
-		} else
-			errx(1, "Unknown command: %s", cmd);
-		
-	}
-	fclose(fp);
+	snprintf(pfilename, PATH_MAX, "%s/%s/%s", LOG_DIR, name,
+	    CONTENTS_FNAME);
+	return (read_package_contents_file(pfilename, pkg));
 }
 
 
@@ -167,7 +106,9 @@
 	char fpatch[PATH_MAX], dpatch[PATH_MAX], tmp[PATH_MAX];
 	struct pkgxjob xpatch;
 	struct pkg_patch pp;
-	struct pkg_metadata pkg_live;
+	Package pkg_live, pkg_new;
+	struct pplist *pl;
+	unsigned int err_count = 0;
 	
 	if (argc < 1)
 		errx(1, "Expecting argument: patch filename");
@@ -198,13 +139,43 @@
 		errx(1, "Invalid patch data format minor version number: %d\n",
 			pp.version_minor);
 	if (Verbose)
-		printf("Read patch data, version %d.%d for '%s' to '%s'\n",
+		printf("Parsed patch version %d.%d for '%s' to '%s'\n",
 		    pp.version_major, pp.version_minor, pp.source, pp.target);
 	
-	/* Step 2 - read the existing (live system) package data */
+	if (Verbose > 1)
+		printf("New files: %u, removed: %u, changed: %u, rmdirs: %u\n",
+		    pplist_count(&pp.pp_add), pplist_count(&pp.pp_remove),
+		    pplist_count(&pp.pp_patch), pplist_count(&pp.pp_rmdir));
+		
+	if (!isinstalledpkg(pp.source))
+		errx(1, "The patch file applies to package '%s' which doesn't "
+		    "appear to be installed.", pp.source);
+		
+	/*
+	 * Step 2 - read the existing (live system) package data and the new
+	 * package data.
+	 */
 	if (read_package_by_name(pp.source, &pkg_live) != 0)
 		err(1, "Cannot read package information for %s", pp.source);
+	snprintf(tmp, PATH_MAX, "%s/%s", dpatch, CONTENTS_FNAME);
+	if (read_package_contents_file(tmp, &pkg_new) != 0)
+		err(1, "Cannot read package information from %s", tmp);
 	
-	dump_package_info(&pkg_live);
+	/* Step 3 - verify that the live system and the patch file agree */
+	if (Verbose > 1)
+		printf("Verifying live system and patch data consistency...\n");
+	/* Check that files to be added don't exist already. */
+	STAILQ_FOREACH(pl, &pp.pp_add, linkage) {
+		snprintf(tmp, PATH_MAX, "%s/%s", PREFIX, pl->filename);
+		if (access(tmp, F_OK) == 0) {
+			warnx("File exists but shouldn't: %s", tmp);
+			err_count++;
+		}
+	}
+	if (err_count != 0)
+		errx(1, "Found %u errors. Cannot continue.", err_count);
 	
+	/* Step 4 - backup the existing package */
+	if (pkg_backup(pp.source) != 0)
+		err(1, "Cannot backup package: %s", pp.source);
 }

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


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


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


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


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

@@ -178,7 +178,8 @@
 	time(&tm);
 	fprintf(fp, "# FreeBSD package patch archive created on %s\n",
 		ctime(&tm));
-	fprintf(fp, "@version %s\n", PKGPATCH_VERSION);
+	fprintf(fp, "@version %d.%d\n", PKGPATCH_VERSION_MAJOR,
+	    PKGPATCH_VERSION_MINOR);
 	parse_package_name(fold, tmp, tmp2, NULL);
 	fprintf(fp, "@source %s-%s\n", tmp, tmp2);
 	parse_package_name(fnew, tmp, tmp2, NULL);

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


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

@@ -26,12 +26,26 @@
 #ifndef _PATH_BSDIFF
 #define _PATH_BSDIFF 	"/usr/bin/bsdiff"
 #endif
+#ifndef _PATH_PKG_CREATE
+#define _PATH_PKG_CREATE	"/usr/sbin/pkg_create"
+#endif
+
+#ifndef PKG_FORMAT_EXT
+#define PKG_FORMAT_EXT	"tbz"
+#endif
 
 #define PKGPATCH_FNAME		"+PKGPATCH"
 #define PKGPATCH_VERSION_MAJOR	1
 #define PKGPATCH_VERSION_MINOR	0
-#define PKGPATCH_VERSION 	"1.0"
+
+#define	PKGPATCH_BACKUP_DIR_ENV		"PKG_BACKUPDIR"
+#define PKGPATCH_BACKUP_DIR_DEFAULT	"/var/backups/pkg"
+#define PKGPATCH_BACKUP_DIR		(getenv(PKGPATCH_BACKUP_DIR_ENV) ? \
+    getenv(PKGPATCH_BACKUP_DIR_ENV) : PKGPATCH_BACKUP_DIR_DEFAULT) 
 
+#define PREFIX_ENV	"PREFIX"
+#define PREFIX_DEFAULT	"/usr/local"
+#define PREFIX		(getenv(PREFIX_ENV) ? getenv(PREFIX_ENV) : PREFIX_DEFAULT)
 
 enum PP_OP { PP_NONE, PP_MKPATCH, PP_APPLY };
 
@@ -47,37 +61,30 @@
 	SLIST_ENTRY(filelist) 	linkage;
 };
 
-
 SLIST_HEAD(pathlist_head, pathlist);
 struct pathlist {
 	char		path[PATH_MAX];
 	SLIST_ENTRY(pathlist)	linkage;
 };
 
+enum PPMETHOD { PPMETHOD_UNKNOWN, PPMETHOD_CP, PPMETHOD_BSDIFF };
 
-STAILQ_HEAD(pkg_plist_head, pkg_plist);
-struct pkg_plist {
-	char		name[PATH_MAX];
-	union {
-		char	md5[33];
-		char	deporigin[PATH_MAX];
-	} param;
-	plist_t		type;
-	unsigned	flags;
-	STAILQ_ENTRY(pkg_plist)	linkage;
+STAILQ_HEAD(pplist_head, pplist);
+struct pplist {
+	char 			filename[PATH_MAX];
+	enum PPMETHOD		method;
+	STAILQ_ENTRY(pplist)	linkage;
 };
-#define PLIST_FLAG_IGNORE	1
 
-struct pkg_metadata {
-	char		name[PATH_MAX];
-	char		origin[PATH_MAX];
-	char		pkg_format_revision[16];
-	char		prefix[PATH_MAX];
-	char		display[PATH_MAX];
-	char		mtree[PATH_MAX];
-	struct pkg_plist_head	plist;
-	struct pathlist_head	conflicts;
-	struct pathlist_head	unknown_comments;
+struct pkg_patch {
+	short int		version_major;
+	short int		version_minor;
+	char			source[PATH_MAX];
+	char			target[PATH_MAX];
+	struct pplist_head	pp_add;
+	struct pplist_head	pp_remove;
+	struct pplist_head	pp_rmdir;
+	struct pplist_head	pp_patch;
 };
 
 
@@ -91,6 +98,7 @@
 
 #endif
 
+
 int rm_rf(char *dir);
 int pkgxjob_start(struct pkgxjob *job, char *dir, char *filename);
 int pkgxjob_finish(struct pkgxjob *job);
@@ -105,8 +113,7 @@
 int copy_file_absolute(char *from, char *to);
 int copy_file_attrs(char *from, struct stat *st_from, char *to);
 int replicate_dirtree(char *from, char *to);
-int read_package(FILE *fp, struct pkg_metadata *pkg);
-int read_package_by_name(char *name, struct pkg_metadata *pkg);
-void dump_package_info(struct pkg_metadata *pkg);
+void read_pkgpatch_file(char *filename, struct pkg_patch *pp);
+unsigned int pplist_count(struct pplist_head *ppl);
 
 #endif

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

@@ -340,221 +340,122 @@
 
 
 /*
- * Parse the comment as if it were stand-alone, adding to package metadata.
- * Destructive on cmt.
+ * Counts the elements in the given pplist.
  */
-static void
-parse_pkg_comment(struct pkg_metadata *pkg, char *cmt)
+unsigned int
+pplist_count(struct pplist_head *ppl)
 {
-	char *v;
-	struct pathlist *plcmt;
+	unsigned int count = 0;
+	struct pplist *pl;
 	
-	if ((v = strchr(cmt, ':')) == NULL)
-		goto unknown_comment;
-	*v++ = '\0';
-	if (strcmp(cmt, "PKG_FORMAT_REVISION") == 0)
-		strncpy(pkg->pkg_format_revision, v, 
-		    sizeof(pkg->pkg_format_revision));
-	else if (strcmp(cmt, "ORIGIN") == 0)
-		strncpy(pkg->origin, v, sizeof(pkg->origin));
-	else {
-		*(--v) = ':';
-		goto unknown_comment;
-	}
-	return;
-unknown_comment:
-	plcmt = calloc(1, sizeof(*plcmt));
-	strncpy(plcmt->path, cmt, sizeof(plcmt->path));
-	SLIST_INSERT_HEAD(&pkg->unknown_comments, plcmt, linkage);
+	STAILQ_FOREACH(pl, ppl, linkage)
+		count++;
+	return (count);
 }
 
 
 /*
- * Parse the comment and assign it to plist (if possible). Destructive on cmt.
+ * Reads the given file into struct pkg_patch.
  */
-static void
-parse_plist_comment(struct pkg_metadata *pkg, struct pkg_plist *pl, char *cmt)
-{
-	char *v;
-	struct pathlist *plcmt;
-	
-	if ((v = strchr(cmt, ':')) == NULL)
-		goto unknown_comment;
-	*v++ = '\0';
-	if (strcmp(cmt, "MD5") == 0)
-		strncpy(pl->param.md5, v, sizeof(pl->param.md5));
-	else if (strcmp(cmt, "DEPORIGIN") == 0) {
-		if (pl->type != PLIST_PKGDEP) {
-			warnx("DEPORIGIN not set on @pkgdep? (%s:%s)", cmt, v);
-			return;
-		}
-		strncpy(pl->param.deporigin, v, sizeof(pl->param.deporigin));
-	} else {
-		*(--v) = ':';
-		goto unknown_comment;
-	}
-	return;
-unknown_comment:
-	plcmt = calloc(1, sizeof(*plcmt));
-	strncpy(plcmt->path, cmt, sizeof(plcmt->path));
-	SLIST_INSERT_HEAD(&pkg->unknown_comments, plcmt, linkage);
-}
-
-
-/* Parse @conflicts */
-static void
-parse_pkg_conflicts(struct pkg_metadata *pkg, char *cfl)
-{
-	struct pathlist *pcfl;
-	
-	pcfl = calloc(1, sizeof(*pcfl));
-	strncpy(pcfl->path, cfl, sizeof(pcfl->path));
-	SLIST_INSERT_HEAD(&pkg->conflicts, pcfl, linkage);
-}
-
-
-/*
- * Reads the package +CONTENTS file into the struct pkg_metadata.
- */ 
-int
-read_package_by_name(char *name, struct pkg_metadata *pkg)
+void
+read_pkgpatch_file(char *filename, struct pkg_patch *pp)
 {
-	char pfilename[PATH_MAX];
 	FILE *fp;
-	int rval;
+	char line[PATH_MAX], *p, *p2, *p3, *cmd;
+	int llen;
+	struct pplist *pl;
 	
-	snprintf(pfilename, PATH_MAX, "%s/%s/%s", LOG_DIR, name,
-	    CONTENTS_FNAME);
-	if (access(pfilename, R_OK) != 0) {
-		warn("Cannot access %s for reading", pfilename);
-		return (-errno);
-	}
-	fp = fopen(pfilename, "r");
-	if (fp == NULL) {
-		warn("Cannot open filename: %s", pfilename);
-		return (-errno);
-	}
-	rval = read_package(fp, pkg);
-	fclose(fp);
-	return (rval);
-}
-
-
-/*
- * Reads the package metadata for the given package name in the package database
- * structure. The name is a full package name, e.g. "sqlite3-3.6.19".
- * Hopefully, one day, someone will make a canonical way to do this instead
- * of reinwenting the wheel. The actual format of +CONTENTS is very lame.
- */
-int
-read_package(FILE *fp, struct pkg_metadata *pkg)
-{
-	char line[PATH_MAX];
-	struct pkg_plist *pl = NULL;
-	int llen, rval;
-	
-	STAILQ_INIT(&pkg->plist);
-	SLIST_INIT(&pkg->conflicts);
-	SLIST_INIT(&pkg->unknown_comments);
+	fp = fopen(filename, "r");
+	if (fp == NULL)
+		err(1, "Cannot open file: %s", filename);
+	memset(pp, 0, sizeof(*pp));
+	STAILQ_INIT(&pp->pp_add);
+	STAILQ_INIT(&pp->pp_remove);
+	STAILQ_INIT(&pp->pp_rmdir);
+	STAILQ_INIT(&pp->pp_patch);
 	
-	rval = 0;
 	while (fgets(line, PATH_MAX, fp) != NULL) {
-		char *p, *cmd;
-		
 		llen = strlen(line);
 		if (line[llen-1] == '\n') {
 			line[llen-1] = '\0';	/* strip newline */
 			llen--;
 		}
-		if (line[0] == '\0')
+		p = strchr(line, '#'); 	/* skip comments */
+		if (p != NULL)
+			*p = '\0';
+		if (line[0] == '\0')	/* skip empty lines */
 			continue;
-		/*printf("%s\n", line);*/
-		if (line[0] == CMD_CHAR) {
-			cmd = line + 1;
-			p = strchr(line, ' ');
-			if (p == NULL)
-				p = line + llen;
-			*p++ = '\0';
-			if (strcmp(cmd, "comment") == 0) {
-				if (pl != NULL)
-					/* Comment on a plist entry? */
-					parse_plist_comment(pkg, pl, p);
-				else
-					/* Comment on the package? */
-					parse_pkg_comment(pkg, p);
-			} else if (strcmp(cmd, "name") == 0) {
-				strncpy(pkg->name, p, sizeof(pkg->name));
-				pl = NULL;
-			} else if (strcmp(cmd, "cwd") == 0) {
-				if (strcmp(p, ".") != 0) {
-					strncpy(pkg->prefix, p, sizeof(pkg->prefix));
-					pl = NULL;
-				}
-			} else if (strcmp(cmd, "display") == 0) {
-				strncpy(pkg->display, p, sizeof(pkg->display));
-				/*pl = NULL;*/
-			} else if (strcmp(cmd, "mtree") == 0) {
-				strncpy(pkg->mtree, p, sizeof(pkg->mtree));
-				/*pl = NULL;*/
-			} else if (strcmp(cmd, "pkgdep") == 0) {
-				pl = calloc(1, sizeof(*pl));
-				pl->type = PLIST_PKGDEP;
-				strncpy(pl->name, p, sizeof(pl->name));
-				STAILQ_INSERT_TAIL(&pkg->plist, pl, linkage);
-			} else if (strcmp(cmd, "conflicts") == 0) {
-				parse_pkg_conflicts(pkg, p);
-				pl = NULL;
-			} else if (strcmp(cmd, "exec") == 0) {
-				pl = calloc(1, sizeof(*pl));
-				pl->type = PLIST_CMD;
-				strncpy(pl->name, p, sizeof(pl->name));
-				STAILQ_INSERT_TAIL(&pkg->plist, pl, linkage);
-			} else if (strcmp(cmd, "unexec") == 0) {
-				pl = calloc(1, sizeof(*pl));
-				pl->type = PLIST_UNEXEC;
-				strncpy(pl->name, p, sizeof(pl->name));
-				STAILQ_INSERT_TAIL(&pkg->plist, pl, linkage);
-			} else if (strcmp(cmd, "dirrm") == 0) {
-				pl = calloc(1, sizeof(*pl));
-				pl->type = PLIST_DIR_RM;
-				strncpy(pl->name, p, sizeof(pl->name));
-				STAILQ_INSERT_TAIL(&pkg->plist, pl, linkage);
-			} else if (strcmp(cmd, "ignore") == 0) {
+		cmd = line;
+		p = strchr(line, ' ');
+		if (p == NULL)
+			errx(1, "Invalid command format in %s", PKGPATCH_FNAME);
+		*p++ = '\0';
+		if (strcmp(cmd, "@version") == 0) {
+			p2 = strchr(p, '.');
+			if (p2 == NULL)
+				errx(1, "Invalid version format in %s",
+				    PKGPATCH_FNAME);
+			*p2++ = '\0';
+			pp->version_major = atoi(p);
+			pp->version_minor = atoi(p2);
+		} else if (strcmp(cmd, "@source") == 0) {
+			strlcpy(pp->source, p, PATH_MAX);
+		} else if (strcmp(cmd, "@target") == 0) {
+			strlcpy(pp->target, p, PATH_MAX);
+		} else if (strcmp(cmd, "@add") == 0) {
+			pl = calloc(1, sizeof(*pl));
+			strlcpy(pl->filename, p, PATH_MAX);
+			STAILQ_INSERT_TAIL(&pp->pp_add, pl, linkage);
+		} else if (strcmp(cmd, "@remove") == 0) {
+			pl = calloc(1, sizeof(*pl));
+			strlcpy(pl->filename, p, PATH_MAX);
+			STAILQ_INSERT_TAIL(&pp->pp_remove, pl, linkage);
+		} else if (strcmp(cmd, "@rmdir") == 0) {
+			pl = calloc(1, sizeof(*pl));
+			strlcpy(pl->filename, p, PATH_MAX);
+			STAILQ_INSERT_TAIL(&pp->pp_rmdir, pl, linkage);
+		} else if (strcmp(cmd, "@patch") == 0) {
+			pl = calloc(1, sizeof(*pl));
+			p2 = strchr(p, '[');
+			if (p2 != NULL) {
 				/*
-				 * Apparently, "ignore" is similar to
-				 * "comment" in that it can apply to
-				 * the preceeding item.
+				 * Parse options block of the form
+				 * \[name=value[,name=value...]\]
 				 */
-				if (pl == NULL)
-					errx(1, "@ignore on non-plist");
-				pl->flags |= PLIST_FLAG_IGNORE;
-			} else
-				warnx("Unknown command: '%s'", cmd);
-		} else {
-			pl = calloc(1, sizeof(*pl));
-			pl->type = PLIST_FILE;
-			strncpy(pl->name, line, sizeof(pl->name));
-			STAILQ_INSERT_TAIL(&pkg->plist, pl, linkage);
-		}
+				char m[100], *pm, *p4, *p5;
+				
+				pm = m;
+				p3 = strchr(p2, ']');
+				assert(p3-p2 < (int)sizeof(m));
+				strlcpy(m, p2 + 1, p3 - p2);
+				p3++;
+				while (*p3 == ' ')
+					p3++;
+				strlcpy(pl->filename, p3, PATH_MAX);
+				while ((p4 = strsep(&pm, ",")) != NULL) {
+					p5 = strchr(p4, '=');
+					if (p5 != NULL)
+						*p5++ = '\0';
+					if (strcmp(p4, "method") == 0) {
+						if (p5 == NULL)
+							errx(1, "patch option "
+							    "error");
+						if (strcmp(p5, "bsdiff") == 0)
+							pl->method = 
+							    PPMETHOD_BSDIFF;
+					}
+				}
+			} else {
+				/* Default options */
+				strlcpy(pl->filename, p, PATH_MAX);
+				pl->method = PPMETHOD_CP;
+			}
+			STAILQ_INSERT_TAIL(&pp->pp_patch, pl, linkage);
+		} else
+			errx(1, "Unknown command: %s", cmd);
+		
 	}
-	return (0);
+	fclose(fp);
 }
 
 
-/*
- * Debugging function - dump human-readable info on the given
- * package.
- */
-void
-dump_package_info(struct pkg_metadata *pkg)
-{
-	struct pkg_plist *pl;
-	
-	printf("name:\t%s\n", pkg->name);
-	printf("origin:\t%s\n", pkg->origin);
-	printf("format:\t%s\n", pkg->pkg_format_revision);
-	printf("prefix:\t%s\n", pkg->prefix);
-	STAILQ_FOREACH(pl, &pkg->plist, linkage) {
-		printf("plist:\t%s\n", pl->name);
-	}
-}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006221612.o5MGCFxW034865>