/* prsize5.c James S. Plank Fall, 1996 CS360 Latest tweaks to keep it up to date: February, 2021. */ /* We build the file name, which includes the directory, for the stat() call. */ #include #include #include #include #include long get_size(const char *fn) { DIR *d; /* Return value of opendir(). */ struct dirent *de; /* Return value of each readdir() call. */ struct stat buf; /* The information about each file returned by stat() */ int exists; /* Return value of stat on each file. */ long total_size; /* The total size of all files. */ int fn_size; /* This is the length of fn -- so we can build the filename. */ char *dir_fn; /* This will be the filename including the directory. */ int dir_fn_size; /* This is the bytes in dir_fn is, in case we need to make it bigger. */ int sz; /* Initialize */ d = opendir(fn); if (d == NULL) { perror(fn); exit(1); } total_size = 0; /* Start building the directory + files. We'll start by setting dir_fn_size to fn_size+10, and we'll make it bigger as we need to. It will be more efficient to use a number bigger than 10 for this, but 10 will let us debug the code if there's a problem. I'm also setting up dir_fn to hold the directory name and a slash. */ fn_size = strlen(fn); dir_fn_size = fn_size + 10; dir_fn = (char *) malloc(sizeof(char) * dir_fn_size); if (dir_fn == NULL) { perror("malloc dir_fn"); exit(1); } strcpy(dir_fn, fn); strcat(dir_fn + fn_size, "/"); /* Run through the directory and run stat() on each file, keeping track of the total size of all of the files. */ for (de = readdir(d); de != NULL; de = readdir(d)) { /* First, we need to build dir_fn. First check to see if it's big enough, and if not, we'll call realloc() to reallocate space. Then we put the filename after the slash. */ sz = strlen(de->d_name); if (dir_fn_size < fn_size + sz + 2) { /* The +2 is for the slash and null character. */ dir_fn_size = fn_size + sz + 10; dir_fn = realloc(dir_fn, dir_fn_size); } strcpy(dir_fn + fn_size + 1, de->d_name); exists = stat(dir_fn, &buf); if (exists < 0) { fprintf(stderr, "Couldn't stat %s\n", dir_fn); exit(1); } total_size += buf.st_size; /* If the file is a directory, and not . or .. make a recursive call to get_size(): */ if (S_ISDIR(buf.st_mode) && strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) { total_size += get_size(dir_fn); } } closedir(d); free(dir_fn); return total_size; } int main() { long total_size; total_size = get_size("."); printf("%ld\n", total_size); return 0; }