chiark / gitweb /
Merge branch 'master' into merge-141006
[chiark-utils.git] / cprogs / acctdump.c
index e1b76746efa514255b95dbe30c38f8b0a6a5c010..98fab9c55d4f96d0d782500894c99a5c1f62b4d1 100644 (file)
@@ -96,12 +96,16 @@ static void scandev(const char *basename, int levelsleft) {
   
   if (levelsleft==0) return;
 
-  dir= opendir(basename); if (!dir) return;
+  dir= opendir(basename); 
+  if (!dir) {
+    fprintf(stderr, "%s: opendir: %s\n", basename, strerror(errno));
+    return;
+  }
   fnbufalloc= 0;
   fnbuf= 0;
   basel= strlen(basename);
 
-  while ((de= readdir(dir))) {
+  while ((errno=0, de= readdir(dir))) {
     fnbufreq= basel+1+strlen(de->d_name)+1;
     if (fnbufalloc<fnbufreq) {
       fnbufalloc= fnbufreq+10;
@@ -111,6 +115,10 @@ static void scandev(const char *basename, int levelsleft) {
     }
     sprintf(fnbuf,"%s/%s",basename,de->d_name);
     r= lstat(fnbuf,&stab);
+    if (r) {
+      fprintf(stderr, "%s: %s\n", fnbuf, strerror(errno));
+      continue;
+    }
     if (S_ISCHR(stab.st_mode)) {
       if (de_used >= de_allocd) {
        nallocd= (de_allocd+10)<<1;
@@ -127,6 +135,8 @@ static void scandev(const char *basename, int levelsleft) {
       scandev(fnbuf,levelsleft-1);
     }
   }
+  if (errno)
+      fprintf(stderr, "%s: readdir: %s\n", basename, strerror(errno));
   closedir(dir);
   free(fnbuf);
 }
@@ -271,6 +281,7 @@ static void printrecord(const struct_acct *as, const char *filename) {
 
 static void processfile(FILE *file, const char *filename) {
   struct_acct as;
+  long pos;
   int r;
   
   if (forwards) {
@@ -280,14 +291,17 @@ static void processfile(FILE *file, const char *filename) {
   } else {
     long seekdist= -(long)sizeof(as);
     r= fseek(file,0,SEEK_END); if (r) { perror(filename); exit(8); }
+    pos= ftell(file); if (pos==-1) { perror(filename); exit(8); }
+    if (pos % sizeof(as)) { 
+      fprintf(stderr, "%s: File size is not an integral number "
+             "of accounting records", filename);
+      exit(8);
+    }
     for (;;) {
-      r= fseek(file,seekdist,SEEK_CUR);
-      if (r) {
-       if (errno=EINVAL) break;
-       perror(filename); exit(8);
-      }
-      r= fread(&as,1,sizeof(as),file);
-      if (r!=sizeof(as)) { perror(filename); exit(8); }
+      if (pos<sizeof(as)) break;
+      pos -= sizeof(as);
+      r= fseek(file,pos,SEEK_SET); if (r==-1) { perror(filename); exit(8); }
+      r= fread(&as,1,sizeof(as),file); if (r!=sizeof(as)) { perror(filename); exit(8); }
       printrecord(&as,filename);
       seekdist= -2*(long)sizeof(as);
     }