X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=aft.c;h=0aa9c6ba7ac4588f1889bf4dda8ec52d3b9cf4d7;hb=6f6d8eb1f8f88d9bc51530ae9c14089a20ad76ab;hp=b4d8c2dd359bbfbe143c8be75a89b016b0bfe505;hpb=07a2d4510f0adc6eff211400f16a0760409bc507;p=paraslash.git diff --git a/aft.c b/aft.c index b4d8c2dd..0aa9c6ba 100644 --- a/aft.c +++ b/aft.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -1906,6 +1907,53 @@ out_free: return send_ret; } +/* + * Call back once for each regular file below a directory. + * + * Traverse the given directory recursively and call the supplied callback for + * each regular file encountered. The first argument to the callback will be + * the path to the regular file and the second argument will be the data + * pointer. All file types except regular files and directories are ignored. In + * particular, symlinks are not followed. Subdirectories are ignored silently + * if the calling process has insufficient access permissions. + */ +static int for_each_file_in_dir(const char *dirname, + int (*func)(const char *, void *), void *data) +{ + int ret; + DIR *dir; + struct dirent *entry; + + dir = opendir(dirname); + if (!dir) + return errno == EACCES? 1 : -ERRNO_TO_PARA_ERROR(errno); + /* scan cwd recursively */ + while ((entry = readdir(dir))) { + char *tmp; + struct stat s; + + if (!strcmp(entry->d_name, ".")) + continue; + if (!strcmp(entry->d_name, "..")) + continue; + tmp = make_message("%s/%s", dirname, entry->d_name); + ret = 0; + if (lstat(tmp, &s) != -1) { + if (S_ISREG(s.st_mode)) + ret = func(tmp, data); + else if (S_ISDIR(s.st_mode)) + ret = for_each_file_in_dir(tmp, func, data); + } + free(tmp); + if (ret < 0) + goto out; + } + ret = 1; +out: + closedir(dir); + return ret; +} + static int com_add(struct command_context *cc, struct lls_parse_result *lpr) { int i, ret;