[Pkg-shadow-commits] r1514 - in upstream/trunk: . libmisc

nekral-guest at alioth.debian.org nekral-guest at alioth.debian.org
Thu Dec 27 23:23:51 UTC 2007


Author: nekral-guest
Date: 2007-12-27 23:23:51 +0000 (Thu, 27 Dec 2007)
New Revision: 1514

Modified:
   upstream/trunk/ChangeLog
   upstream/trunk/libmisc/copydir.c
Log:
libmisc/copydir.c cleanup
	* libmisc/copydir.c: Split copy_tree() in more maintainable functions:
	copy_entry(), copy_dir(), copy_symlink(), copy_hardlink(),
	copy_special(), and copy_file().
	* libmisc/copydir.c: -1 is used to indicate an error, directly set err
	to -1, instead of incrementing it, and checking if not nul at the
	end.


Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog	2007-12-27 21:56:45 UTC (rev 1513)
+++ upstream/trunk/ChangeLog	2007-12-27 23:23:51 UTC (rev 1514)
@@ -1,5 +1,15 @@
 2007-12-27  Nicolas François  <nicolas.francois at centraliens.net>
 
+	libmisc/copydir.c cleanup
+	* libmisc/copydir.c: Split copy_tree() in more maintainable functions:
+	copy_entry(), copy_dir(), copy_symlink(), copy_hardlink(),
+	copy_special(), and copy_file().
+	* libmisc/copydir.c: -1 is used to indicate an error, directly set err
+	to -1, instead of incrementing it, and checking if not nul at the
+	end.
+
+2007-12-27  Nicolas François  <nicolas.francois at centraliens.net>
+
 	gpasswd cleanup
 	* src/gpasswd.c: Add argument name to the internal function
 	prototypes.

Modified: upstream/trunk/libmisc/copydir.c
===================================================================
--- upstream/trunk/libmisc/copydir.c	2007-12-27 21:56:45 UTC (rev 1513)
+++ upstream/trunk/libmisc/copydir.c	2007-12-27 23:23:51 UTC (rev 1514)
@@ -54,6 +54,25 @@
 };
 static struct link_name *links;
 
+static int copy_entry (const char *src, const char *dst,
+                       uid_t uid, gid_t gid);
+static int copy_dir (const char *src, const char *dst,
+                     const struct stat *statp, const struct timeval mt[2],
+                     uid_t uid, gid_t gid);
+#ifdef	S_IFLNK
+static int copy_symlink (const char *src, const char *dst,
+                         const struct stat *statp, const struct timeval mt[2],
+                         uid_t uid, gid_t gid);
+#endif
+static int copy_hardlink (const char *src, const char *dst,
+                          struct link_name *lp);
+static int copy_special (const char *src, const char *dst,
+                         const struct stat *statp, const struct timeval mt[2],
+                         uid_t uid, gid_t gid);
+static int copy_file (const char *src, const char *dst,
+                      const struct stat *statp, const struct timeval mt[2],
+                      uid_t uid, gid_t gid);
+
 #ifdef WITH_SELINUX
 static int selinux_file_context (const char *dst_name)
 {
@@ -77,7 +96,6 @@
 /*
  * remove_link - delete a link from the link list
  */
-
 static void remove_link (struct link_name *ln)
 {
 	struct link_name *lp;
@@ -146,16 +164,9 @@
 {
 	char src_name[1024];
 	char dst_name[1024];
-	char buf[1024];
-	int ifd;
-	int ofd;
 	int err = 0;
-	int cnt;
 	int set_orig = 0;
 	struct DIRECT *ent;
-	struct stat sb;
-	struct link_name *lp;
-	struct timeval mt[2];
 	DIR *dir;
 
 	/*
@@ -200,7 +211,7 @@
 
 		if (strlen (src_root) + strlen (ent->d_name) + 2 >
 		    sizeof src_name) {
-			err++;
+			err = -1;
 			break;
 		}
 		snprintf (src_name, sizeof src_name, "%s/%s", src_root,
@@ -208,15 +219,34 @@
 
 		if (strlen (dst_root) + strlen (ent->d_name) + 2 >
 		    sizeof dst_name) {
-			err++;
+			err = -1;
 			break;
 		}
 		snprintf (dst_name, sizeof dst_name, "%s/%s", dst_root,
 			  ent->d_name);
 
-		if (LSTAT (src_name, &sb) == -1)
-			continue;
+		err = copy_entry (src_name, dst_name, uid, gid);
+	}
+	closedir (dir);
 
+	if (set_orig) {
+		src_orig = 0;
+		dst_orig = 0;
+	}
+	return err;
+}
+
+static int copy_entry (const char *src, const char *dst,
+                       uid_t uid, gid_t gid)
+{
+	int err = 0;
+	struct stat sb;
+	struct link_name *lp;
+	struct timeval mt[2];
+
+	if (LSTAT (src, &sb) == -1) {
+		/* If we cannot stat the file, do not care. */
+	} else {
 #if  defined(_BSD_SOURCE) || defined(_SVID_SOURCE)
 		mt[0].tv_sec  = sb.st_atim.tv_sec;
 		mt[0].tv_usec = sb.st_atim.tv_nsec / 1000;
@@ -230,78 +260,16 @@
 #endif
 
 		if (S_ISDIR (sb.st_mode)) {
+			err = copy_dir (src, dst, &sb, mt, uid, gid);
+		}
 
-			/*
-			 * Create a new target directory, make it owned by
-			 * the user and then recursively copy that directory.
-			 */
-
-#ifdef WITH_SELINUX
-			selinux_file_context (dst_name);
-#endif
-			if (mkdir (dst_name, sb.st_mode)
-			    || chown (dst_name,
-				      uid == (uid_t) - 1 ? sb.st_uid : uid,
-				      gid == (gid_t) - 1 ? sb.st_gid : gid)
-			    || chmod (dst_name, sb.st_mode)
-			    || copy_tree (src_name, dst_name, uid, gid)
-			    || utimes (dst_name, mt)) {
-				err++;
-				break;
-			}
-
-			continue;
-		}
 #ifdef	S_IFLNK
 		/*
 		 * Copy any symbolic links
 		 */
 
-		if (S_ISLNK (sb.st_mode)) {
-			char oldlink[1024];
-			char dummy[1024];
-			int len;
-
-			/*
-			 * Get the name of the file which the link points
-			 * to.  If that name begins with the original
-			 * source directory name, that part of the link
-			 * name will be replaced with the original
-			 * destinateion directory name.
-			 */
-
-			if ((len =
-			     readlink (src_name, oldlink,
-				       sizeof (oldlink) - 1)) < 0) {
-				err++;
-				break;
-			}
-			oldlink[len] = '\0';	/* readlink() does not NUL-terminate */
-			if (!strncmp (oldlink, src_orig, strlen (src_orig))) {
-				snprintf (dummy, sizeof dummy, "%s%s",
-					  dst_orig,
-					  oldlink + strlen (src_orig));
-				strcpy (oldlink, dummy);
-			}
-#ifdef WITH_SELINUX
-			selinux_file_context (dst_name);
-#endif
-			if (symlink (oldlink, dst_name)
-			    || lchown (dst_name,
-				    uid == (uid_t) - 1 ? sb.st_uid : uid,
-				    gid == (gid_t) - 1 ? sb.st_gid : gid)) {
-				err++;
-				break;
-			}
-
-			/* 2007-10-18: We don't care about
-			 *  exit status of lutimes because
-			 *  it returns ENOSYS on many system
-			 *  - not implemented
-			 */
-			lutimes (dst_name, mt);
-
-			continue;
+		else if (S_ISLNK (sb.st_mode)) {
+			err = copy_symlink (src, dst, &sb, mt, uid, gid);
 		}
 #endif
 
@@ -309,19 +277,8 @@
 		 * See if this is a previously copied link
 		 */
 
-		if ((lp = check_link (src_name, &sb))) {
-			if (link (lp->ln_name, dst_name)) {
-				err++;
-				break;
-			}
-			if (unlink (src_name)) {
-				err++;
-				break;
-			}
-			if (--lp->ln_count <= 0)
-				remove_link (lp);
-
-			continue;
+		else if ((lp = check_link (src, &sb))) {
+			err = copy_hardlink (src, dst, lp);
 		}
 
 		/*
@@ -330,21 +287,8 @@
 		 * would be nice to copy everything ...
 		 */
 
-		if (!S_ISREG (sb.st_mode)) {
-#ifdef WITH_SELINUX
-			selinux_file_context (dst_name);
-#endif
-			if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev)
-			    || chown (dst_name,
-				      uid == (uid_t) - 1 ? sb.st_uid : uid,
-				      gid == (gid_t) - 1 ? sb.st_gid : gid)
-			    || chmod (dst_name, sb.st_mode & 07777)
-			    || utimes (dst_name, mt)) {
-				err++;
-				break;
-			}
-
-			continue;
+		else if (!S_ISREG (sb.st_mode)) {
+			err = copy_special (src, dst, &sb, mt, uid, gid);
 		}
 
 		/*
@@ -352,55 +296,174 @@
 		 * file will be owned by the provided UID and GID values.
 		 */
 
-		if ((ifd = open (src_name, O_RDONLY)) < 0) {
-			err++;
-			break;
+		else {
+			err = copy_file (src, dst, &sb, mt, uid, gid);
 		}
+	}
+
+	return err;
+}
+
+static int copy_dir (const char *src, const char *dst,
+                     const struct stat *statp, const struct timeval mt[2],
+                     uid_t uid, gid_t gid)
+{
+	int err = 0;
+
+	/*
+	 * Create a new target directory, make it owned by
+	 * the user and then recursively copy that directory.
+	 */
+
 #ifdef WITH_SELINUX
-		selinux_file_context (dst_name);
+	selinux_file_context (dst);
 #endif
-		if ((ofd =
-		     open (dst_name, O_WRONLY | O_CREAT | O_TRUNC, 0)) < 0
-		    || chown (dst_name,
-			      uid == (uid_t) - 1 ? sb.st_uid : uid,
-			      gid == (gid_t) - 1 ? sb.st_gid : gid)
-		    || chmod (dst_name, sb.st_mode & 07777)) {
-			close (ifd);
-			err++;
-			break;
-		}
+	if (mkdir (dst, statp->st_mode)
+	    || chown (dst,
+	              uid == (uid_t) - 1 ? statp->st_uid : uid,
+	              gid == (gid_t) - 1 ? statp->st_gid : gid)
+	    || chmod (dst, statp->st_mode)
+	    || copy_tree (src, dst, uid, gid)
+	    || utimes (dst, mt)) {
+		err = -1;
+	}
 
-		while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
-			if (write (ofd, buf, cnt) != cnt) {
-				cnt = -1;
-				break;
-			}
-		}
+	return err;
+}
 
+#ifdef	S_IFLNK
+static int copy_symlink (const char *src, const char *dst,
+                         const struct stat *statp, const struct timeval mt[2],
+                         uid_t uid, gid_t gid)
+{
+	char oldlink[1024];
+	char dummy[1024];
+	int len;
+	int err = 0;
+
+	/*
+	 * Get the name of the file which the link points
+	 * to.  If that name begins with the original
+	 * source directory name, that part of the link
+	 * name will be replaced with the original
+	 * destination directory name.
+	 */
+
+	if ((len =
+	     readlink (src, oldlink,
+		       sizeof (oldlink) - 1)) < 0) {
+		return -1;
+	}
+	oldlink[len] = '\0';	/* readlink() does not NUL-terminate */
+	if (!strncmp (oldlink, src_orig, strlen (src_orig))) {
+		snprintf (dummy, sizeof dummy, "%s%s",
+		          dst_orig,
+		          oldlink + strlen (src_orig));
+		strcpy (oldlink, dummy);
+	}
+#ifdef WITH_SELINUX
+	selinux_file_context (dst);
+#endif
+	if (symlink (oldlink, dst)
+	    || lchown (dst,
+	               uid == (uid_t) - 1 ? statp->st_uid : uid,
+	               gid == (gid_t) - 1 ? statp->st_gid : gid)) {
+		return -1;
+	}
+
+	/* 2007-10-18: We don't care about
+	 *  exit status of lutimes because
+	 *  it returns ENOSYS on many system
+	 *  - not implemented
+	 */
+	lutimes (dst, mt);
+
+	return err;
+}
+#endif
+
+static int copy_hardlink (const char *src, const char *dst,
+                          struct link_name *lp)
+{
+	/* TODO: selinux needed? */
+
+	if (link (lp->ln_name, dst)) {
+		return -1;
+	}
+	if (unlink (src)) {
+		return -1;
+	}
+	if (--lp->ln_count <= 0)
+		remove_link (lp);
+
+	return 0;
+}
+
+static int copy_special (const char *src, const char *dst,
+                         const struct stat *statp, const struct timeval mt[2],
+                         uid_t uid, gid_t gid)
+{
+	int err = 0;
+
+#ifdef WITH_SELINUX
+	selinux_file_context (dst);
+#endif
+
+	if (mknod (dst, statp->st_mode & ~07777, statp->st_rdev)
+	    || chown (dst,
+	              uid == (uid_t) - 1 ? statp->st_uid : uid,
+	              gid == (gid_t) - 1 ? statp->st_gid : gid)
+	    || chmod (dst, statp->st_mode & 07777)
+	    || utimes (dst, mt)) {
+		err = -1;
+	}
+
+	return err;
+}
+
+static int copy_file (const char *src, const char *dst,
+                      const struct stat *statp, const struct timeval mt[2],
+                      uid_t uid, gid_t gid)
+{
+	int err = 0;
+	int ifd;
+	int ofd;
+	char buf[1024];
+	int cnt;
+
+	if ((ifd = open (src, O_RDONLY)) < 0) {
+		return -1;
+	}
+#ifdef WITH_SELINUX
+	selinux_file_context (dst);
+#endif
+	if ((ofd =
+	     open (dst, O_WRONLY | O_CREAT | O_TRUNC, 0)) < 0
+	    || chown (dst,
+	              uid == (uid_t) - 1 ? statp->st_uid : uid,
+	              gid == (gid_t) - 1 ? statp->st_gid : gid)
+	    || chmod (dst, statp->st_mode & 07777)) {
 		close (ifd);
+		return -1;
+	}
 
-		if (futimes (ofd, mt) != 0) {
-			err++;
-			break;
+	while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
+		if (write (ofd, buf, cnt) != cnt) {
+			return -1;
 		}
+	}
 
-		if (close (ofd) != 0) {
-			err++;
-			break;
-		}
+	close (ifd);
 
-		if (cnt == -1) {
-			err++;
-			break;
-		}
+	if (futimes (ofd, mt) != 0) {
+		return -1;
 	}
-	closedir (dir);
 
-	if (set_orig) {
-		src_orig = 0;
-		dst_orig = 0;
+	if (close (ofd) != 0) {
+		return -1;
 	}
-	return err ? -1 : 0;
+
+	return err;
 }
 
 /*
@@ -451,7 +514,7 @@
 		 */
 
 		if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) {
-			err++;
+			err = -1;
 			break;
 		}
 		snprintf (new_name, sizeof new_name, "%s/%s", root,
@@ -466,11 +529,11 @@
 			 */
 
 			if (remove_tree (new_name)) {
-				err++;
+				err = -1;
 				break;
 			}
 			if (rmdir (new_name)) {
-				err++;
+				err = -1;
 				break;
 			}
 			continue;
@@ -479,5 +542,5 @@
 	}
 	closedir (dir);
 
-	return err ? -1 : 0;
+	return err;
 }




More information about the Pkg-shadow-commits mailing list