PERFORCE change 180026 for review
Ivan Voras
ivoras at FreeBSD.org
Mon Jun 21 00:45:43 UTC 2010
http://p4web.freebsd.org/@@180026?ac=10
Change 180026 by ivoras at 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);
+ }
+}
More information about the p4-projects
mailing list