#include #include #include #include #include #include #include #include #include /* The C Programming Language: 2nd Edition * * Exercise 8-5: Modify the fsize program to print the other information * contained in the inode entry. * * Notes: The supplied header file examples don't really work well on a * GNU/Linux system in 2022. :) This makes 8-5 the only exercise in the book * that's broken enough to nearly require the standard library to complete. * Despite lacking the homegrown headers, this exercise is still a good example * of callbacks. * * Not all of the information within the stat struct is displayed by this * program; this is mostly due to the information not being terribly useful * on all systems. Modification time and permission information is relevant * to all platforms. */ void fsize(char *); void dirwalk(char *, void (*fcn)(char *)); int main(int argc, char **argv) { if (argc == 1) { fsize("."); } else { while (--argc > 0) { fsize(*++argv); } } return 0; } void fsize(char *name) { struct stat stbuf; if (stat(name, &stbuf) == -1) { fprintf(stderr, "fsize: can't access %s\n", name); return; } if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { dirwalk(name, fsize); } /* * Size, Mode, UID, GID, ModifiedTime, FileName */ printf("%8ld %6o %d %d %ld %s\n", stbuf.st_size, stbuf.st_mode, stbuf.st_uid, stbuf.st_gid, stbuf.st_mtime, name); } void dirwalk(char *dir, void (*fcn)(char *)) { char name[PATH_MAX]; struct dirent *dp; DIR *dfd; if ((dfd = opendir(dir)) == NULL) { fprintf(stderr, "dirwalk: can't open %s\n", dir); return; } while ((dp = readdir(dfd)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { continue; } if (strlen(dir)+strlen(dp->d_name)+2 > sizeof (name)) { fprintf(stderr, "dirwalk: name %s/%s too long\n", dir, dp->d_name); } else { sprintf(name, "%s/%s", dir, dp->d_name); (*fcn)(name); } } closedir(dfd); }