1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/* Copyright (C) 2005 Free Software Foundation, Inc.
* Written by Yoann Vandoorselaere <yoann@prelude-ids.org>
*
* The file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include "ftw_.h"
#include "pathmax.h"
static int get_path_infos(const char *path, struct stat *st, int *flag)
{
int ret;
ret = stat(path, st);
if ( ret < 0 ) {
*flag = FTW_NS;
return -1;
}
if ( S_ISREG(st->st_mode) )
*flag = FTW_F;
else if ( S_ISDIR(st->st_mode) )
*flag = FTW_D;
else if ( S_ISLNK(st->st_mode) )
*flag = FTW_SL;
return ret;
}
int ftw(const char *dir,
int (*fn)(const char *file, const struct stat *sb, int flag), int nopenfd)
{
DIR *d;
size_t len;
struct stat st;
struct dirent *de;
int flag, ret = 0;
char filename[PATH_MAX];
ret = get_path_infos(dir, &st, &flag);
if ( ret < 0 )
return -1;
d = opendir(dir);
if ( ! d )
return (errno == EACCES) ? fn(dir, &st, FTW_DNR) : -1;
ret = fn(dir, &st, flag);
if ( ret < 0 ) {
closedir(d);
return ret;
}
while ( (de = readdir(d)) ) {
len = snprintf(filename, sizeof(filename), "%s/%s", dir, de->d_name);
if ( len < 0 || len >= sizeof(filename) ) {
errno = ENAMETOOLONG;
return -1;
}
ret = get_path_infos(filename, &st, &flag);
if ( ret < 0 )
break;
if ( flag == FTW_D ) {
if ( strcmp(de->d_name, "..") == 0 || strcmp(de->d_name, ".") == 0 )
continue;
ret = ftw(filename, fn, nopenfd);
if ( ret < 0 )
break;
continue;
}
ret = fn(filename, (flag == FTW_NS) ? NULL : &st, flag);
if ( ret < 0 )
break;
}
closedir(d);
return ret;
}
|