/* Last edited on 2024-12-25 10:18:13 by stolfi */ #include #include #include #include #include #include #include #include /* Local prototypes: */ int main(int argc, char **argv); void error (char *msg); int main(int argc, char **argv) { int k; int listFiles = 1, listDirs = 1, listLinks = 1, listErrors = 1, listOthers = 1; int followLinks = 0, showType = 0, partialList = 0; /* Parse options: */ for (k=1; k < argc; k++) { char *op = argv[k]; if ((*op) == '\0') { } else if (strcmp(op, "-type") == 0) { if (partialList) { error("enum-dir: duplicate option"); } partialList = 1; k++; /* Parse type codes: */ listFiles = 0; listDirs = 0; listLinks = 0; listErrors = 0; listOthers = 0; if (k >= argc) { error("enum-dir: missing type codes"); } { char *tset = argv[k]; while ((*tset) != '\0') { if ((*tset) == 'f') listFiles = 1; else if ((*tset) == 'd') listDirs = 1; else if ((*tset) == 'l') listLinks = 1; else if ((*tset) == 'e') listErrors = 1; else if ((*tset) == 'o') listOthers = 1; else { error("enum-dir: bad entry type"); } tset++; } } } else if (strcmp(op, "-showType") == 0) { if (showType) { error("enum-dir: duplicate option"); } showType = 1; } else if (strcmp(op, "-followLinks") == 0) { if (followLinks) { error("enum-dir: duplicate option"); } followLinks = 1; } else if ((*op) == '-') { error("enum-dir: bad option"); } else { char *dir_path = argv[k]; int res; if (k != argc-1) error("enum-dir: too many arguments"); if ((*dir_path) == '\0') error("enum-dir: pathname is empty"); res = chdir(dir_path); if (res) { perror("enum-dir"); abort(); } } } /* Enumerate directory: */ { struct stat edata; struct dirent *ep; DIR *dirp = opendir("."); if (dirp == NULL) { perror("enum-dir"); abort(); } for (ep = readdir(dirp); ep != NULL; ep = readdir(dirp)) { char etype = '?'; int printIt = 0; if (partialList || showType) { /* Must determine entry type */ if ((strcmp(ep->d_name, ".") == 0) || (strcmp(ep->d_name, "..") == 0)) { etype = 'o'; printIt = listOthers; } else { int res; if (followLinks) { res = stat(ep->d_name, &edata); } else { res = lstat(ep->d_name, &edata); } if (res) { etype = 'e'; printIt = listErrors; } else if (S_ISDIR(edata.st_mode)) { etype = 'd'; printIt = listDirs; } else if (S_ISREG(edata.st_mode)) { etype = 'f'; printIt = listFiles; } else if (S_ISLNK(edata.st_mode)) { etype = 'l'; printIt = listLinks; } else { etype = 'o'; printIt = listOthers; } } } else { etype = '?'; printIt = 1; } if (printIt) { if (showType) { putc(etype, stdout); putc(' ', stdout); } printf("%s\n", ep->d_name); } } closedir (dirp); return (0); } } void error (char *msg) { fprintf (stderr, "%s\n", msg); exit(1); }