Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 4 Jun 2010 00:00:51 GMT
From:      Ivan Voras <ivoras@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 179160 for review
Message-ID:  <201006040000.o5400pdQ063195@repoman.freebsd.org>

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

Change 179160 by ivoras@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);
 }



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