diff options
author | Andreas Gruenbacher <agruen@suse.de> | 2006-01-21 23:45:37 +0000 |
---|---|---|
committer | Andreas Gruenbacher <agruen@suse.de> | 2006-01-21 23:45:37 +0000 |
commit | 91a883abd8138ea0c864cc34b46a7359d4505a21 (patch) | |
tree | c964a64ce76dba87a1d1010feef0b60a788055dc | |
parent | 7650e642f6405339620b850ec12fd53238fc55d4 (diff) | |
download | quilt-91a883abd8138ea0c864cc34b46a7359d4505a21.tar.gz |
- Add fallback ftw implementation for systems that don't have it.
-rw-r--r-- | Makefile.in | 12 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | lib/ftw.c | 116 | ||||
-rw-r--r-- | lib/ftw.h | 23 | ||||
-rw-r--r-- | quilt.changes | 5 |
5 files changed, 156 insertions, 5 deletions
diff --git a/Makefile.in b/Makefile.in index 2831b29..3bb9da1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -43,6 +43,11 @@ LDFLAGS += @LDFLAGS@ LIBS := @LIBS@ EXEEXT := @EXEEXT@ +LIBOBJS := $(patsubst %,lib/%,@LIBOBJS@) +ifneq ($(LIBOBJS),) +CFLAGS += -Ilib +endif + COMPAT_SYMLINKS := @COMPAT_SYMLINKS@ COMPAT_PROGRAMS := @COMPAT_PROGRAMS@ @@ -81,9 +86,9 @@ SRC += $(wildcard compat/*.in) $(wildcard compat/*.sh) DIRT += $(patsubst %.in,%,$(wildcard compat/*.in)) COMPAT := $(COMPAT_PROGRAMS:%=compat/%) $(COMPAT_SYMLINKS:%=compat/%) -LIB_SRC := backup-files.c +LIB_SRC := backup-files.c ftw.c LIB := backup-files$(EXEEXT) -SRC += $(LIB_SRC:%=lib/%) +SRC += $(LIB_SRC:%=lib/%) lib/ftw.h DIRT += lib/backup-files$(EXEEXT) $(LIB_SRC:%.c=lib/%.o) DOC_IN := README @@ -122,8 +127,7 @@ export QUILT_DIR QUILT_LIB QUILTRC all : scripts compat $(DOC:%=doc/%) $(MAN1) mofiles -$(LIB:%=lib/%) : $(LIB_SRC:%.c=lib/%.o) - $(CC) -o $@ $(LDFLAGS) $^ $(LIBS) +lib/backup-files :: $(LIBOBJS) ifeq ($(USE_NLS),yes) mofiles : $(LINGUAS:%=po/%.mo) diff --git a/configure.ac b/configure.ac index c32ab80..c677f47 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT([quilt],[0.42],[quilt-dev@nongnu.org]) AC_CONFIG_AUX_DIR(config) AC_PREREQ(2.53) -AC_REVISION ($Revision: 1.63 $) +AC_REVISION ($Revision: 1.64 $) PACKAGE_RELEASE=1 AC_SUBST(PACKAGE_RELEASE) @@ -17,6 +17,9 @@ AC_CHECK_FUNCS([strerror]) AC_C_CONST AC_FUNC_STAT +AC_CONFIG_LIBOBJ_DIR(lib) +AC_REPLACE_FUNCS(ftw) + if test "$ac_compiler_gnu" = "yes"; then CFLAGS="$CFLAGS -Wall" fi diff --git a/lib/ftw.c b/lib/ftw.c new file mode 100644 index 0000000..8762194 --- /dev/null +++ b/lib/ftw.c @@ -0,0 +1,116 @@ +/* + * Written by Jesper Juhl <jj@dif.dk> - released under the terms of the GPL + * + * Credit should be given to : + * R. Stevens author of "Advanced Programming in the UNIX Environment" + * since I have made heavy use of some of his example code. + * + */ + +/* To compile the test code: gcc -DTEST_FTW ftw.c */ + +#include "ftw.h" + +static int depth; +static char *path; + +static int trawl(char *path, ftw_func *f, int d) { + int retval; + struct stat sb; + struct dirent *dir; + DIR *dp; + char *p; + + if (depth == d) + return(0); + + if (lstat(path, &sb) == -1) + return(f(path, &sb, FTW_NS)); + + if (!S_ISDIR(sb.st_mode)) + return(f(path, &sb, FTW_F)); + + if ((retval = f(path, &sb, FTW_D)) != 0) + return(retval); + + p = path + strlen(path); + *p++ = '/'; + *p = '\0'; + + if ((dp = opendir(path)) == NULL) + return(f(path, &sb, FTW_DNR)); + + while ((dir = readdir(dp)) != NULL) { + if ((strncmp(dir->d_name, ".", 1) == 0) || + (strncmp(dir->d_name, "..", 2) == 0)) + continue; + + strcpy(p, dir->d_name); + depth++; + if ((retval = trawl(path, f, d)) != 0) + break; + depth--; + } + + p[-1] = '\0'; + + closedir(dp); + return(retval); +} + +int ftw(const char *directory, ftw_func *f, int d) { + int retval; + + if ((path = (char *)malloc(sysconf(_PC_PATH_MAX)+1)) == NULL) + return(-1); + + strcpy(path, directory); + depth = 0; + retval = trawl(path, f, d); + + free(path); + return(retval); +} + +#ifdef TEST_FTW +int foo(const char *file, struct stat *sb, int flag) { + + switch (flag) { + case FTW_F : + if (S_ISREG(sb->st_mode)) printf("%s is a regular file\n\n", file); + else if (S_ISBLK(sb->st_mode)) printf("%s is a block dev\n\n", file); + else if (S_ISCHR(sb->st_mode)) printf("%s is a char dev\n\n", file); + else if (S_ISFIFO(sb->st_mode)) printf("%s is a fifo\n\n", file); + else if (S_ISLNK(sb->st_mode)) printf("%s is a link\n\n", file); + break; + case FTW_D : + printf("%s is a directory\n\n", file); + break; + case FTW_NS : + printf("stat failed on %s\n\n", file); + break; + case FTW_DNR : + printf("%s is a directory which can't be read\n\n", file); + break; + default : + printf("%s is unknown\n\n", file); + break; + } + return(0); +} + +int main(int argc, char *argv[]) { + + if (argc == 2) { + ftw(argv[1], foo, 1); + exit(0); + } else if (argc > 2) { + ftw(argv[1], foo, atoi(argv[2])); + exit(0); + } else { + printf("usage %s <dirname> [depth]\n", argv[0]); + exit(1); + } +} +#endif + diff --git a/lib/ftw.h b/lib/ftw.h new file mode 100644 index 0000000..5e8f0cf --- /dev/null +++ b/lib/ftw.h @@ -0,0 +1,23 @@ +#ifndef _FTW_H_ +#define _FTW_H_ + +#include <stdio.h> +#include <stdlib.h> +#include <dirent.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <limits.h> + +#define FTW_F 1 +#define FTW_D 2 +#define FTW_DNR 3 +#define FTW_NS 4 + +/* This is a replacement for the FTW file traversal utility */ + +typedef int ftw_func(const char *file, const struct stat *sb, int flag); + +int ftw(const char *directory, ftw_func *f, int d); + +#endif /* _FTW_H_ */ diff --git a/quilt.changes b/quilt.changes index abe4ce7..9e70f1f 100644 --- a/quilt.changes +++ b/quilt.changes @@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Sun Jan 22 00:44:27 CET 2006 - agruen@suse.de + +- Add fallback ftw implementation for systems that don't have it. + +------------------------------------------------------------------- Sat Jan 21 23:37:24 CET 2006 - agruen@suse.de - Use ftw instead of nftw (some platforms don't have nftw). |