/*
* Author: dearvoid at gmail.com
*
* $Date: 2006-06-14 09:01:52 +0800 (Wed, 14 Jun 2006) $
* $HeadURL: svn://svnserver/clark/void/trunk/c/ls-R.c $
* $Revision: 554 $
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
bool
isDir(const char * path, const struct dirent * ent)
{
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
/*
* On Mac OS X 10.3.x (PPC) the struct dirent does not
* has the d_type field.
*/
return ent->d_type == DT_DIR;
#else
char buf[1024]; // FIXME
struct stat fstat;
sprintf(buf, "%s/%s", path, ent->d_name);
if (stat(buf, &fstat) < 0) {
perror("stat()");
exit(1);
} else {
return S_ISDIR(fstat.st_mode);
}
#endif
}
int
ls_R(char * path)
{
int i;
int nEntries;
char buf[1024]; // FIXME
struct dirent ** list;
nEntries = scandir(path, &list, NULL, NULL);
if (nEntries < 0) {
printf("scandir('%s'): %s\n", path, strerror(errno));
return 1;
}
printf("%s:\n", path);
for (i = 0; i < nEntries; ++i) {
printf("\t%s\n", list[i]->d_name);
if (!isDir(path, list[i]) || !strcmp(list[i]->d_name, ".")
|| !strcmp(list[i]->d_name, "..")) {
free(list[i]);
list[i] = NULL;
}
}
printf("\n");
for (i = 0; i < nEntries; ++i) {
if (list[i]) {
sprintf(buf, "%s/%s", path, list[i]->d_name);
ls_R(buf);
}
}
for (i = 0; i < nEntries; ++i) {
free(list[i]);
}
free(list);
return 0;
}
int
main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage:\n");
printf(" %s /your/dir\n", argv[0]);
exit(1);
}
ls_R(argv[1]);
return 0;
}