/* MAT 4370 poor man "ls" This example serves as an exceedingly brief and simplified version of how one might implement the UNIX ls command. Notice how the recursive nature of the file system lends itself to a recursive tree traversal. */ #include #include #include #include #include void listdir(const char *pathname); void *safe_malloc(size_t size); int main(int argc, char *argv[]) { if (argc == 2) /* traverse the filesystem at a specified point */ listdir(argv[1]); else /* traverse the filesystem rooted at the current working directory */ listdir("."); return 0; } /* recursively list the contents of a directory, given its path name */ void listdir(const char *pathname) { DIR *dir; struct dirent *entry; /* one directory entry */ char *subdir_pathname; /* the pathname for a child subdirectory */ struct stat statbuf; /* status for a given directory entry */ /* open this directory, if possible */ if ((dir = opendir(pathname)) == NULL) return; /* read the first directory entry, if any */ if ((entry = readdir(dir)) == NULL) return; /* process this entry, then try to read another */ do { /* omit the current and parent directory entries */ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; /* extend the path name by appending this entry name */ subdir_pathname = safe_malloc(strlen(pathname) + strlen(entry->d_name) + 2); strcpy(subdir_pathname, pathname); strcat(subdir_pathname, "/"); strcat(subdir_pathname, entry->d_name); /* ask the OS about this file/directory */ stat(subdir_pathname, &statbuf); if (S_ISDIR(statbuf.st_mode)) { /* directory : display the name and contents */ printf("%s\n", subdir_pathname); listdir(subdir_pathname); } else /* regular file : display the size and name */ printf("%10d %s\n", (int) statbuf.st_size, entry->d_name); free(subdir_pathname); /* avoid memory leaks! */ } while ((entry = readdir(dir)) != NULL); closedir(dir); } /* safely allocate a block of storage, aborting program if not possible */ void *safe_malloc(size_t size) { void *p; p = malloc(size); if (p == NULL) { fprintf(stderr, "error - out of space!"); exit(EXIT_FAILURE); } else return p; }