PERFORCE change 180110 for review
Ivan Voras
ivoras at FreeBSD.org
Tue Jun 22 16:12:16 UTC 2010
http://p4web.freebsd.org/@@180110?ac=10
Change 180110 by ivoras at 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);
- }
-}
More information about the p4-projects
mailing list