John Vandenberg wrote:
On 9/15/05, Dean Roehrich <[EMAIL PROTECTED]> wrote:

On Wed, Sep 14, 2005 at 04:39:01PM +0100, Gary V. Vaughan wrote:

Andreas Gruenbacher wrote:

How about nuking nftw instead, and implementing the few lines of useful
code that it performs by hand?

Okay, that sounds much easier.  Actually, I think I already wrote that
code for libltdl, so I'll see if I can cannibalise it now :-D

Check Joe's patches first.  I know he did something in this area.  Maybe this
work is already done?

Thanks, I've attached my dirent based file tree walk which really is *much* simpler than all the workarounds needed to patch up ftw/nftw/alt_ftw/fts for portability.

He has these touching backup-files.c, and most of them are specific to
ftw/nftw issues:

http://zeroj.hda0.net/quilt-patches/backup-files-touchup.diff
http://zeroj.hda0.net/quilt-patches/import_alt_ftw.diff
http://zeroj.hda0.net/quilt-patches/mingw-backup-files.diff
http://zeroj.hda0.net/quilt-patches/sun-backup-files.diff

and it looks like some others covering tests for this stuff.

The configury is over-complicated, and some of these patches contain
several changes.  I've dropped the parts that are no longer necessary,
and broken the last few into small self-contained patches that I'll
post in a separate thread.

Cheers,
        Gary.
--
Gary V. Vaughan      ())_.  [EMAIL PROTECTED],gnu.org}
Research Scientist   ( '/   http://tkd.kicks-ass.net
GNU Hacker           / )=   http://www.gnu.org/software/libtool
Technical Author   `(_~)_   http://sources.redhat.com/autobook
Although Mac OS X 10.4 (I'm running 10.4.2) has nftw and ftw compatibility
functions, and code that uses them seems to build and link properly: the
resulting calls do nothing, which breaks `quilt pop' at least.

This patch reimplements the file tree walk manually with dirent, which is
fully supported even on old host architectures.

 lib/backup-files.c |  109 +++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 90 insertions(+), 19 deletions(-)

Index: quilt-HEAD/lib/backup-files.c
===================================================================
--- quilt-HEAD.orig/lib/backup-files.c
+++ quilt-HEAD/lib/backup-files.c
@@ -1,7 +1,7 @@
 /*
   File: backup-files.c
 
-  Copyright (C) 2003 Andreas Gruenbacher <[EMAIL PROTECTED]>
+  Copyright (C) 2003, 2005 Andreas Gruenbacher <[EMAIL PROTECTED]>
   SuSE Labs, SuSE Linux AG
 
   This program is free software; you can redistribute it and/or
@@ -37,7 +37,7 @@
 #include <errno.h>
 #include <string.h>
 #include <alloca.h>
-#include <ftw.h>
+#include <dirent.h>
 
 const char *progname;
 
@@ -107,7 +107,7 @@ remove_parents(char *filename)
 			*g = '/';
 		g = f;
 		*f= '\0';
-		
+
 		rmdir(filename);
 	}
 	if (g != NULL)
@@ -184,7 +184,7 @@ ensure_nolinks(const char *filename)
 		from_fd = open(filename, O_RDONLY);
 		if (from_fd == -1)
 			goto fail;
-		
+
 		/* Temp file name is "path/to/.file.XXXXXX" */
 		strcpy(tmpname, filename);
 		strcat(tmpname, ".XXXXXX");
@@ -195,7 +195,7 @@ ensure_nolinks(const char *filename)
 			c++;
 		memmove(c + 1, c, strlen(c) + 1);
 		*c = '.';
-		
+
 		to_fd = mkstemp(tmpname);
 		if (to_fd == -1)
 			goto fail;
@@ -312,18 +312,85 @@ process_file(const char *file)
 }
 
 int
-walk(const char *path, const struct stat *stat, int flag, struct FTW *ftw)
+searchdir_p (const char *path, int complain)
+{
+	struct stat st;
+
+	/* ignore missing files */
+	if (stat(path, &st) != 0) {
+		if (complain) perror (path);
+		return 0;
+	}
+	/* and non-directories */
+	if (!S_ISDIR(st.st_mode)) {
+		if (complain)
+			fprintf(stderr, "%s: not a directory\n", path);
+		return 0;
+	}
+	/* no access permission */
+	if (access(path, R_OK|X_OK) != 0) {
+		if (complain) perror (path);
+		return 0;
+	}
+
+	return 1;
+}
+
+int
+foreachdir (const char *root, int(*walk)(const char *))
+{
+	int errors = 0;
+	DIR *dir;
+
+	if (!searchdir_p(root, 1))
+		return 0;
+
+        dir = opendir(root);
+	if (dir) {
+		struct dirent *dp = 0;
+
+		while ((dp = readdir(dir))) {
+			if (strcmp(dp->d_name, ".")
+			    && strcmp(dp->d_name, "..")) {
+				char *path = alloca (2+ strlen (root) +
+						     strlen (dp->d_name));
+				sprintf (path, "%s/%s", root, dp->d_name);
+				if (searchdir_p (path, 0)) {
+					/* depth first recurse */
+					errors += foreachdir(path, walk);
+				} else {
+					struct stat st;
+					if (stat(path, &st) != 0) {
+						/* ignore missing files */
+						continue;
+					}
+					if (S_ISREG(st.st_mode)) {
+						/* process regular files */
+						errors += walk(path);
+					}
+				}
+			}
+			if (errors > 0) {
+				break;
+			}
+		}
+	}
+
+	if (closedir(dir) !=0) {
+		++errors;
+		perror(root);
+	}
+
+	return errors;
+}
+
+int
+ftwalk(const char *path)
 {
 	size_t prefix_len=strlen(opt_prefix), suffix_len=strlen(opt_suffix);
 	size_t len = strlen(path);
 	char *p;
 
-	if (flag == FTW_DNR) {
-		perror(path);
-		return 1;
-	}
-	if (!S_ISREG(stat->st_mode))
-		return 0;
 	if (strncmp(opt_prefix, path, prefix_len))
 		return 0;  /* prefix does not match */
 	if (len < suffix_len || strcmp(opt_suffix, path + len - suffix_len))
@@ -332,6 +399,7 @@ walk(const char *path, const struct stat
 	p = alloca(len - prefix_len - suffix_len + 1);
 	memcpy(p, path + prefix_len, len - prefix_len - suffix_len);
 	p[len - prefix_len - suffix_len] = '\0';
+
 	return process_file(p);
 }
 
@@ -339,7 +407,7 @@ int
 main(int argc, char *argv[])
 {
 	int opt, status=0;
-	
+
 	progname = argv[0];
 
 	while ((opt = getopt(argc, argv, "brxB:z:f:shLt")) != -1) {
@@ -359,7 +427,7 @@ main(int argc, char *argv[])
 			case 'B':
 				opt_prefix = optarg;
 				break;
-				
+
 			case 'f':
 				opt_file = optarg;
 				break;
@@ -413,7 +481,7 @@ main(int argc, char *argv[])
 				*(l-1) = '\0';
 			if (*line == '\0')
 				continue;
-				
+
 			if ((status = process_file(line)) != 0)
 				return status;
 		}
@@ -424,13 +492,16 @@ main(int argc, char *argv[])
 	}
 	for (; optind < argc; optind++) {
 		if (strcmp(argv[optind], "-") == 0) {
-			char *dir = strdup(opt_prefix), *d = strrchr(dir, '/');
+			char *dir, *d;
+
+			dir = strdup(opt_prefix);
+			d = strrchr(dir, '/');
 			if (d)
-				*(d+1) = '\0';
+				*d = '\0';
 			else
 				d = ".";
-			status = nftw(dir, walk, 0, 0);
-			free(dir);
+
+			foreachdir (dir, ftwalk);
 		} else
 			status = process_file(argv[optind]);
 		if (status)

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Quilt-dev mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/quilt-dev

Reply via email to