chiark / gitweb /
Merge branch 'master' into merge-141006
authorJonathan Amery <jdamery+zgit@ysolde.ucam.org>
Mon, 6 Oct 2014 11:59:10 +0000 (12:59 +0100)
committerJonathan Amery <jdamery+zgit@ysolde.ucam.org>
Mon, 6 Oct 2014 11:59:10 +0000 (12:59 +0100)
Conflicts:
acctdump.c

1  2 
cprogs/acctdump.c

diff --combined cprogs/acctdump.c
index e1b76746efa514255b95dbe30c38f8b0a6a5c010,fbf7eadf24b980a619edbd4c3d2667bd077a2625..98fab9c55d4f96d0d782500894c99a5c1f62b4d1
  #include <grp.h>
  #include <dirent.h>
  #include <ctype.h>
 -#include <sys/stat.h>
 -#include <sys/acct.h>
  #include <errno.h>
 +#include <sys/stat.h>
 +
 +typedef unsigned long long u64;
 +#include "acct.h"
 +/*#include <sys/acct.h>*/
 +typedef struct acct_v3 struct_acct;
  
  #include "myopt.h"
  
@@@ -96,12 -92,16 +96,16 @@@ static void scandev(const char *basenam
    
    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;
      }
      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;
        scandev(fnbuf,levelsleft-1);
      }
    }
+   if (errno)
+       fprintf(stderr, "%s: readdir: %s\n", basename, strerror(errno));
    closedir(dir);
    free(fnbuf);
  }
@@@ -155,7 -161,7 +165,7 @@@ static void printbanner(void) 
    checkstdout();
  }
  
 -static void printrecord(const struct acct *as, const char *filename) {
 +static void printrecord(const struct_acct *as, const char *filename) {
    static int walkeddev;
  
    int i, dc, r;
    struct deventry *deve, devlookfor;
    struct passwd *pw;
    struct group *gr;
 +  time_t btime;
  
    if (raw) {
      printf("%10lu ",(unsigned long)as->ac_btime);
    } else {
 -    time_t btime=as->ac_btime;
 +    btime= as->ac_btime;
      tm= localtime(&btime);
      strftime(buf,sizeof(buf),"%Y-%m-%d %H:%M:%S",tm); buf[sizeof(buf)-1]= 0;
      printf("%19s ",buf);
    else printf("%-8ld ",(long)as->ac_gid);
  
    if (raw) {
 -    if (as->ac_tty == (dev_t)-1) {
 +    if (!(as->ac_tty + 1) /* check for -1 without knowing type */) {
        printf("-        ");
      } else {
        printf("%08lx ",(unsigned long)as->ac_tty);
      }
    } else {
 -    if (as->ac_tty == (dev_t)-1) {
 +    if (!(as->ac_tty + 1)) {
        printf("-          ");
      } else {
        if (!walkeddev) {
    }
  
    r= as->ac_flag;
 -  for (i=1, fp= "FSDX"; *fp; fp++, i<<=1) {
 +  for (i=1, fp= "FS4DX"; *fp; fp++, i<<=1) {
      if (r&i) {
        putchar(*fp);
        r &= ~i;
 -    } else {
 +    } else if (!isdigit(*fp)) {
        putchar(' ');
      }
    }
  }
  
  static void processfile(FILE *file, const char *filename) {
 -  struct acct as;
 +  struct_acct as;
+   long pos;
    int r;
    
    if (forwards) {
        printrecord(&as,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);
      }
    }
    if (ferror(file) || fclose(file)) { perror(filename); exit(8); }
@@@ -303,11 -310,8 +317,11 @@@ static void processnamedfile(const cha
  }
  
  int main(int argc, const char *const *argv) {
 +union { struct_acct ac; char c[1]; } xu;
    myopt(&argv,cmdinfos);
    if (!nobanner) printbanner();
 +fprintf(stdout,"s=%d %d\n",(int)sizeof(struct_acct),
 +      (int)((char*)&xu.ac.ac_comm - xu.c));
    if (usestdin) {
      processfile(stdin,"<standard input>");
    } else if (!*argv) {