PERFORCE change 179160 for review
Ivan Voras
ivoras at FreeBSD.org
Fri Jun 4 00:00:52 UTC 2010
http://p4web.freebsd.org/@@179160?ac=10
Change 179160 by ivoras at betelgeuse on 2010/06/04 00:00:32
Milestone 1 (basic patch file creation) completed.
Affected files ...
.. //depot/projects/soc2010/pkg_patch/src/patch/Makefile#9 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#8 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#8 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/main.c#9 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#7 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#7 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#7 edit
.. //depot/projects/soc2010/pkg_patch/src/patch/support.c#6 edit
Differences ...
==== //depot/projects/soc2010/pkg_patch/src/patch/Makefile#9 (text+ko) ====
==== //depot/projects/soc2010/pkg_patch/src/patch/hashjob.c#8 (text+ko) ====
==== //depot/projects/soc2010/pkg_patch/src/patch/hashjob.h#8 (text+ko) ====
==== //depot/projects/soc2010/pkg_patch/src/patch/main.c#9 (text+ko) ====
==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.c#7 (text+ko) ====
@@ -67,13 +67,13 @@
if (access(fnew, R_OK) != 0)
err(1, "Access error reading file: %s", fnew);
- sprintf(dold, "%s/old", my_tmp);
+ snprintf(dold, PATH_MAX, "%s/old", my_tmp);
if (mkdir(dold, 0700) != 0)
err(1, "Cannot create directory: %s", dold);
- sprintf(dnew, "%s/new", my_tmp);
+ snprintf(dnew, PATH_MAX, "%s/new", my_tmp);
if (mkdir(dnew, 0700) != 0)
err(1, "Cannot create directory: %s", dnew);
- sprintf(dpatch, "%s/patch", my_tmp);
+ snprintf(dpatch, PATH_MAX, "%s/patch", my_tmp);
if (mkdir(dpatch, 0700) != 0)
err(1, "Cannot create directory: %s", dpatch);
@@ -163,10 +163,9 @@
printf("Found %d changed files.\n", filelist_count(&flchanged));
/*
- * XXX: Possibly reimplement with libarchive. If I finally get how it
- * stores directories.
+ * XXX: Possibly reimplement with libarchive.
*/
- sprintf(tmp, "%s/%s", dpatch, PKGPATCH_FNAME);
+ snprintf(tmp, PATH_MAX, "%s/%s", dpatch, PKGPATCH_FNAME);
fp = fopen(tmp, "w");
if (fp == NULL)
err(1, "Cannot open file for writing: %s", tmp);
@@ -181,17 +180,22 @@
SLIST_FOREACH(fl, &fldiff_new_old, linkage)
fprintf(fp, "@add %s\n", fl->filename);
SLIST_FOREACH(fl, &fldiff_old_new, linkage)
- fprintf(fp, "@remove %s\n", fl->filename);
+ if (!S_ISDIR(fl->st.st_mode))
+ fprintf(fp, "@remove %s\n", fl->filename);
+ SLIST_FOREACH(fl, &fldiff_old_new, linkage)
+ if (S_ISDIR(fl->st.st_mode))
+ fprintf(fp, "@rmdir %s\n", fl->filename);
SLIST_FOREACH(fl, &flchanged, linkage)
- fprintf(fp, "@patch [method=cp] %s\n", fl->filename);
+ if (fl->filename[0] != '+')
+ fprintf(fp, "@patch [method=cp] %s\n", fl->filename);
if (fclose(fp) != 0)
err(1, "Cannot close %s", PKGPATCH_FNAME);
/* Include all metadata files from the new package. */
SLIST_FOREACH(fl, &flnew, linkage) {
if (fl->filename[0] == '+') {
- sprintf(tmp, "%s/%s", dnew, fl->filename);
- sprintf(tmp2, "%s/%s", dpatch, fl->filename);
+ snprintf(tmp, PATH_MAX, "%s/%s", dnew, fl->filename);
+ snprintf(tmp2, PATH_MAX, "%s/%s", dpatch, fl->filename);
if (copy_file_absolute(tmp, tmp2) != 0)
err(1, "Cannot copy file: %s to file: %s",
tmp, tmp2);
@@ -199,16 +203,27 @@
}
/* Simply copy the directory hierarchy of the new package. */
- replicate_dirtree(dnew, dpatch);
+ if (replicate_dirtree(dnew, dpatch) != 0)
+ err(1, "replicate_dirtree(%s,%s) failed", dnew, dpatch);
+
+ /* Copy files to add */
+ SLIST_FOREACH(fl, &fldiff_new_old, linkage) {
+ snprintf(tmp, PATH_MAX, "%s/%s", dnew, fl->filename);
+ snprintf(tmp2, PATH_MAX, "%s/%s", dpatch, fl->filename);
+ if (copy_file_absolute(tmp, tmp2) != 0)
+ err(1, "Cannot copy file: %s to file: %s", tmp, tmp2);
+ }
+ /* Copy changed files */
SLIST_FOREACH(fl, &flchanged, linkage) {
- sprintf(tmp, "%s/%s", dnew, fl->filename);
- sprintf(tmp2, "%s/%s", dpatch, fl->filename);
+ snprintf(tmp, PATH_MAX, "%s/%s", dnew, fl->filename);
+ snprintf(tmp2, PATH_MAX, "%s/%s", dpatch, fl->filename);
if (copy_file_absolute(tmp, tmp2) != 0)
err(1, "Cannot copy file: %s to file: %s", tmp, tmp2);
}
- sprintf(tmp, "%s -c -j -C %s -f %s *", _PATH_TAR, dpatch, fpatch);
+ chdir(dpatch);
+ snprintf(tmp, PATH_MAX, "%s -c -j -f %s *", _PATH_TAR, fpatch);
fp = popen(tmp, "r+");
if (fp == NULL)
err(1, "Final tar execution failed for: %s", fpatch);
==== //depot/projects/soc2010/pkg_patch/src/patch/mkpatch.h#7 (text+ko) ====
==== //depot/projects/soc2010/pkg_patch/src/patch/pkg_patch.h#7 (text+ko) ====
==== //depot/projects/soc2010/pkg_patch/src/patch/support.c#6 (text+ko) ====
@@ -26,17 +26,20 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <assert.h>
#include <fcntl.h>
#include <paths.h>
#include <errno.h>
#include <err.h>
#include <fts.h>
-#include <regex.h>
#include <pkg.h>
#include "pkg_patch.h"
+static int copy_file_attrs(char *from, struct stat *st_from, char *to);
+
+
int
rm_rf(char *dir)
{
@@ -85,7 +88,7 @@
return (-1);
dir_len = strlen(dir);
- while ( (fe = fts_read(fts)) != NULL) {
+ while ((fe = fts_read(fts)) != NULL) {
struct filelist *fl;
if (fe->fts_info == FTS_D || fe->fts_info == FTS_F ||
@@ -200,7 +203,45 @@
/*
- * File copy, preserving attributes: ownership, mtime, mode. Knows how to handle
+ * Copy generic file attributes.
+ * TODO: See if there is any need to take care of ACLs (tar apparently doesn't).
+ */
+static int
+copy_file_attrs(char *from, struct stat *st_from, char *to)
+{
+ struct stat *st, st2;
+ struct timeval tv[2];
+
+ if (st_from != NULL)
+ st = st_from;
+ else {
+ assert(from != NULL);
+ if (lstat(from, &st2) < 0) {
+ warn("copy_file_attrs: lstat(%s) failed", from);
+ return (errno);
+ }
+ st = &st2;
+ }
+ if (chown(to, st->st_uid, st->st_gid) < 0) {
+ warn("copy_file_attrs: chown() failed");
+ return (errno);
+ }
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+ tv[0].tv_sec = tv[1].tv_sec = st->st_mtime;
+ if (lutimes(to, tv) < 0) {
+ warn("copy_file_attrs: lutimes(%s,%d) failed", to, st->st_mtime);
+ return (errno);
+ }
+ if (lchmod(to, st->st_mode) < 0) {
+ warn("copy_file_attrs: lchmod(%o) failed", st->st_mode);
+ return (errno);
+ }
+ return (0);
+}
+
+
+/*
+ * File copy, preserving generic file attributes. Knows how to handle
* (re-create) symlinks.
*/
int
@@ -211,7 +252,6 @@
ssize_t bs;
int fdfrom, fdto;
struct stat st;
- struct timeval tv;
if (lstat(from, &st) != 0)
return (errno);
@@ -249,13 +289,7 @@
close(fdto);
close(fdfrom);
- if (chown(to, st.st_uid, st.st_gid) < 0)
- return (errno);
- tv.tv_usec = 0;
- tv.tv_sec = st.st_mtime;
- if (lutimes(to, &tv) < 0)
- return (errno);
- if (lchmod(to, st.st_mode) < 0)
+ if (copy_file_attrs(from, &st, to) != 0)
return (errno);
return (0);
}
@@ -267,8 +301,40 @@
* mode, mtime.
*/
int
-replicate_dirtree(char __unused *from, char __unused *to)
+replicate_dirtree(char *from, char __unused *to)
{
- /* XXX: todo */
- return (0);
+ FTS *fts;
+ FTSENT *fe;
+ char *path_argv[] = { from, NULL };
+ size_t from_len;
+ int rval;
+
+ rval = 0;
+ from_len = strlen(from);
+ fts = fts_open(path_argv, FTS_NOCHDIR | FTS_PHYSICAL | FTS_XDEV, NULL);
+ if (fts == NULL)
+ return (-1);
+ while ((fe = fts_read(fts)) != NULL) {
+ char new_dir[PATH_MAX];
+
+ if (fe->fts_info == FTS_D) {
+ snprintf(new_dir, PATH_MAX, "%s%s", to,
+ fe->fts_path + from_len);
+ if (access(new_dir, F_OK) == 0)
+ continue;
+ if (mkdir(new_dir, 0700) < 0) {
+ rval = errno;
+ goto end;
+ }
+ if (copy_file_attrs(fe->fts_path, fe->fts_statp,
+ new_dir) != 0) {
+ rval = errno;
+ goto end;
+ }
+ }
+ }
+end:
+ if (fts_close(fts) < 0)
+ return (-1);
+ return (rval);
}
More information about the p4-projects
mailing list