So the fseek/ftell method seems more reliable than stat.st_size (for acquiring file size) albeit much slower.
...except i get irregular results calling on mounted dvd's (burnt by me on redhat7). Sometimes this is a null pointer from fopen, but usually the program completes without reporting an error, but also without collecting any file sizes. I haven't had any other problems with the dvd's.
Here's the code -- it works almost exactly like du -h DIR (the code for which I haven't looked at). du b/t/w does work where this doesn't:
Code:#include <stdio.h> #include <dirent.h> #include <string.h> #include <errno.h> #include <unistd.h> int sw1=0; float totalsize; // kb count int dodir (char *doname) { long int bytes, testbytes; // "testbytes" is needed float dividit; // for the return value error check char nextfile[256]; // since "bytes" is += struct dirent *dcon; FILE *fh; if (sw1 != 0) printf ("\t%s ", doname); DIR *dir = opendir (doname); if (dir == NULL ) { printf ("For Directory %s ERROR: %s\n", doname, strerror(errno)); exit(1); } bytes = 0; while (dcon = readdir(dir)) { if (dcon->d_type == DT_REG) { strcpy(nextfile, doname); strcat(nextfile, "/"); strcat(nextfile, dcon->d_name); fh = fopen (nextfile, "r"); if (fh == NULL) printf ("\t\tFor regular file %s ERROR: %s\n", nextfile, strerror(errno)); if ((fseek(fh,0,SEEK_END)) != 0) printf ("\t\tfseek ERROR (%s)\n", nextfile); if ((testbytes = ftell(fh)) == -1) printf ("ftell ERROR (%s)\n", nextfile); else bytes += testbytes; fclose(fh); } } dividit = bytes; dividit /= 1024; // gives kb totalsize += dividit; if (sw1 == 0) printf (" (%.2f kb):\n", dividit); else if (sw1 >= 1) printf ("\t%.2f kb\n", dividit); sw1++; rewinddir(dir); while (dcon = readdir(dir)) { if ((strcmp (dcon->d_name, "..")) == 0 || (strcmp(dcon->d_name, ".")) == 0) continue; strcpy(nextfile, doname); strcat(nextfile, "/"); strcat(nextfile, dcon->d_name); if (dcon->d_type == DT_DIR) dodir(nextfile); } closedir(dir); } int main (int argc, char *argv[]) { char unit[6]; if (argc < 2) puts ("Directory pathname required on command-line."); strcpy(unit, "kb"); printf ("In %s", argv[1]); dodir(argv[1]); if (totalsize >= 1024) { totalsize /= 1024; strcpy(unit, "Mb"); } if (totalsize >= 1024) { totalsize /= 1024; strcpy(unit, "GB"); } printf ("Total size of regular files: %.2f %s\n", totalsize,unit); }



LinkBack URL
About LinkBacks


