fileops files changed
[eleutheria.git] / fileops / listdir_recursive.c
blob61c3cc0fe2a0ee4923a2dad829f9134cbf90985a
1 /*
2 * Compile with:
3 * gcc listdir_recursive.c -o listdir_recursive -Wall -W -Wextra -ansi -pedantic
4 */
6 #include <dirent.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
13 * Since listdir() uses a static variable to keep track of the call depth,
14 * it is not safe to use it in a multi threading environment. If this is the
15 * case, then you need to pass 'dirdepth' as an argument to listdir().
17 int listdir(const char *path)
19 struct dirent *pdent;
20 DIR *pdir;
21 char *newpath = NULL;
22 static unsigned int dirdepth = 0;
23 unsigned int i;
26 * Open directory named by path, associate a directory stream
27 * with it and return a pointer to it
29 if ((pdir = opendir(path)) == NULL) {
30 perror("opendir");
31 return -1;
34 /* Get all directory entries */
35 while((pdent = readdir(pdir)) != NULL) {
36 /* Indent according to the depth we are */
37 for (i = 0; i < dirdepth; i++)
38 printf(" ");
40 /* Print current entry, or [entry] if it's a directory */
41 if (pdent->d_type == DT_DIR)
42 printf("[%s]\n", pdent->d_name);
43 else
44 printf("%s\n", pdent->d_name);
46 /* Is it a directory ? If yes, list it */
47 if (pdent->d_type == DT_DIR
48 && strcmp(pdent->d_name, ".")
49 && strcmp(pdent->d_name, "..")) {
50 dirdepth++;
52 /* Allocate memory for new path (don't forget +1 for the '\0') */
53 if ((newpath = malloc(strlen(path) + strlen(pdent->d_name) + 2)) == NULL) {
54 perror("malloc");
55 return -1;
58 /* Construct new path */
59 strcpy(newpath, path);
60 strcat(newpath, "/");
61 strcat(newpath, pdent->d_name);
63 /* To iterate is human, to recurse, divine */
64 if (listdir(newpath) == -1) {
65 closedir(pdir);
66 free(newpath);
67 return -1;
72 closedir(pdir);
73 if (newpath != NULL)
74 free(newpath);
76 dirdepth--;
77 return 1;
80 int main(int argc, char *argv[])
82 /* Check argument count */
83 if (argc != 2) {
84 fprintf(stderr, "Usage: %s directory\n", argv[0]);
85 exit(EXIT_FAILURE);
88 (void)listdir(argv[1]);
90 return EXIT_SUCCESS;