Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 21 Jun 2010 00:45:42 GMT
From:      Ivan Voras <ivoras@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 180026 for review
Message-ID:  <201006210045.o5L0jgZ3009138@repoman.freebsd.org>

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

Change 180026 by ivoras@betelgeuse on 2010/06/21 00:45:03

	Finished most of +CONTENTS reading code, still a few things to go
	and certainly edge-cases resulting from the uglyness and adhockery
	of the format.

Affected files ...

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

Differences ...

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


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

@@ -47,7 +47,7 @@
 };
 
 
-struct pkgpatch {
+struct pkg_patch {
 	short int		version_major;
 	short int		version_minor;
 	char			source[PATH_MAX];
@@ -60,7 +60,7 @@
 
 
 static void
-read_pkgpatch_file(char *filename, struct pkgpatch *pp)
+read_pkgpatch_file(char *filename, struct pkg_patch *pp)
 {
 	FILE *fp;
 	char line[PATH_MAX], *p, *p2, *p3, *cmd;
@@ -166,7 +166,8 @@
 {
 	char fpatch[PATH_MAX], dpatch[PATH_MAX], tmp[PATH_MAX];
 	struct pkgxjob xpatch;
-	struct pkgpatch pp;
+	struct pkg_patch pp;
+	struct pkg_metadata pkg_live;
 	
 	if (argc < 1)
 		errx(1, "Expecting argument: patch filename");
@@ -180,7 +181,7 @@
 	if (mkdir(dpatch, 0700) != 0)
 		err(1, "Cannot create directory: %s", dpatch);
 	if (pkgxjob_start(&xpatch, dpatch, fpatch) != 0)
-		err(1, "Canot extract package %s to %s (start)", fpatch,
+		err(1, "Cannot extract package %s to %s (start)", fpatch,
 		    dpatch);
 	if (pkgxjob_finish(&xpatch) != 0)
 		err(1, "Cannot extract package %s to %s (finish)", fpatch,
@@ -201,5 +202,9 @@
 		    pp.version_major, pp.version_minor, pp.source, pp.target);
 	
 	/* Step 2 - read the existing (live system) package data */
+	if (read_package_by_name(pp.source, &pkg_live) != 0)
+		err(1, "Cannot read package information for %s", pp.source);
+	
+	dump_package_info(&pkg_live);
 	
 }

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


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


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


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


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


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


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

@@ -32,10 +32,6 @@
 #define PKGPATCH_VERSION_MINOR	0
 #define PKGPATCH_VERSION 	"1.0"
 
-#ifndef PKG_DBDIR
-/* So much cruft... */
-#define PKG_DBDIR 	LOG_DIR
-#endif
 
 enum PP_OP { PP_NONE, PP_MKPATCH, PP_APPLY };
 
@@ -51,19 +47,37 @@
 	SLIST_ENTRY(filelist) 	linkage;
 };
 
+
+SLIST_HEAD(pathlist_head, pathlist);
+struct pathlist {
+	char		path[PATH_MAX];
+	SLIST_ENTRY(pathlist)	linkage;
+};
+
+
 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;
 };
+#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;
 };
 
 
@@ -91,6 +105,8 @@
 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(char *name, struct pkg_metadata *pkg);
+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);
 
 #endif

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

@@ -340,28 +340,122 @@
 
 
 /*
- * 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.
+ * Parse the comment as if it were stand-alone, adding to package metadata.
+ * Destructive on cmt.
+ */
+static void
+parse_pkg_comment(struct pkg_metadata *pkg, char *cmt)
+{
+	char *v;
+	struct pathlist *plcmt;
+	
+	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);
+}
+
+
+/*
+ * Parse the comment and assign it to plist (if possible). Destructive on cmt.
  */
+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(char *name, struct pkg_metadata *pkg)
+read_package_by_name(char *name, struct pkg_metadata *pkg)
 {
-	char pfilename[PATH_MAX], line[PATH_MAX];
+	char pfilename[PATH_MAX];
 	FILE *fp;
-	struct pkg_plist *pl;
-	int llen, rval;
+	int rval;
 	
-	snprintf(pfilename, PATH_MAX, "%s/%s/%s", PKG_DBDIR, name,
+	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);
+		warn("Cannot access %s for reading", pfilename);
 		return (-errno);
 	}
 	fp = fopen(pfilename, "r");
-	if (fp == NULL)
+	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);
 	
 	rval = 0;
 	while (fgets(line, PATH_MAX, fp) != NULL) {
@@ -374,27 +468,93 @@
 		}
 		if (line[0] == '\0')
 			continue;
+		/*printf("%s\n", line);*/
 		if (line[0] == CMD_CHAR) {
 			cmd = line + 1;
 			p = strchr(line, ' ');
-			if (p == NULL) {
-				rval = -1;
-				goto error;
-			}
+			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) {
+				/*
+				 * Apparently, "ignore" is similar to
+				 * "comment" in that it can apply to
+				 * the preceeding item.
+				 */
+				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);
 		}
 	}
-	
 	return (0);
-error:
-	if (fp != NULL)
-		fclose(fp);
-	return (rval);
 }
 
+
+/*
+ * 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?201006210045.o5L0jgZ3009138>