/* Bigfiles - finds the large files on a system. If no arguments are provided, then filenames are read from standard input otherwise, the arguments are considered to be directory names David Horton, Centre for Information Technology Research, University of Queensland horton@citr.uq.oz.au */ #include #define _INCLUDE_POSIX_SOURCE /* HP/UX */ #include #define _INCLUDE_HPUX_SOURCE /* HP/UX */ #define _INCLUDE_XOPEN_SOURCE /* HP/UX */ #include #include #include #define MF 200 #define FNLEN 2000 #if !defined(S_ISLNK) # define S_ISLNK(_M) ((_M & S_IFMT)==S_IFMT) /* test for symbolic link */ #endif #include #ifdef void #error #endif #ifdef gets #undef gets #endif #define gets(b) fgets(b, sizeof(b), stdin) struct context { /* context we need to keep for a possibly big file */ off_t size; char name[FNLEN]; }; struct context c[MF]; /* array of biggest files so far, sorted */ char device_mode = '\0'; /* s means will be only one device, S means device set */ dev_t device = 0; /* the device number */ #ifdef __STDC__ void big (off_t st_size, char *fname) { /* see if this is a big file */ #else void big (st_size, fname) /* see if this is a big file */ off_t st_size; char *fname; { /* see if this is a big file */ #endif int i; /*printf("big(%d,%s)\n", (int) st_size, fname); */ for (i = MF-1; i >= 0; i--) { /* starting from the smallest we have*/ if (c[i].size >= st_size) /* see if bigger */ break; else { if ( i != (MF-1)) { /* if it is shuffle into place */ c[i+1].size = c[i].size; memcpy(c[i+1].name,c[i].name,sizeof(c[i].name)); } } } if ( i != MF-1) { /* final test for top of the tree */ c[i+1].size = st_size; memcpy(c[i+1].name,fname,sizeof(c[i+1].name)); } } #if defined(__STDC__) void tree(char *root) { /* Process a unix directory instead of*/ #else void tree(root) /* Process a unix directory instead of*/ char *root; { /* Process a unix directory instead of*/ #endif DIR *dirp; /* a list of filenames on stdin */ struct dirent *dp; struct stat s; char buf[FNLEN]; /*printf("tree(%s)\n", root); */ dirp = opendir(root); /* Open the top of the directory tree */ if (dirp == NULL) { perror(root); return; /* Cannot open */ } while ((dp = readdir(dirp)) != NULL) { /*process entries in directory*/ if ( strcmp(dp->d_name, ".") == 0) continue; /* don't go infinite */ if ( strcmp(dp->d_name, "..") == 0) continue; /* don't go up */ sprintf(buf,"%s/%s", root, dp->d_name); if (lstat(buf,&s)) { continue; /* no data available */ } switch (device_mode) { case 's': device = s.st_dev; device_mode = 'S'; break; case 'S': if (s.st_dev != device) { continue; } break; default: break; } if (S_ISLNK(s.st_mode)) continue; /* don't follow symbolic links */ if (S_ISDIR(s.st_mode)) { /* go down sub-tree */ tree(buf); } if (!S_ISREG(s.st_mode)) { /* only look at regular files */ continue; } big(s.st_size, buf); /* see if big file or not */ } (void) closedir(dirp); } static char Copyright[] = "@(#) Copyright 1994, David Horton"; static char rcs[] = "@(#)$RCSfile$ $Revision$"; #if defined(__STDC__) void main(int argc, char *argv[]) { #else main(argc, argv) int argc; char *argv[]; { #endif struct stat s; char fname[FNLEN]; /* buffer for filename */ char *fn; int i; int many = MF; int dirs = 0; memset(c, 0, sizeof(c)); if (argc == 1) { /* no args -> read filenames from stdin */ while ( (fn = gets(fname)) != NULL) { s.st_size = 0; if (lstat(fname,&s)) { continue; /* no data available */ } if (!S_ISREG(s.st_mode)) { /* only look at regular files */ continue; } big(s.st_size, fname); } } else { /* otherwise a list of directory heads */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { case 's': case 'S': device_mode = 's'; break; case 'h': fprintf(stderr, "Usage: %s [-h] [-v] [-s] [-N] [directory]...\n",argv[0]); exit(0); break; case 'v': fprintf(stderr, "%s : %s\n",argv[0], Copyright); fprintf(stderr, "%s\n", rcs); exit(0); break; default: many = - atoi(argv[i]); if ((many ==0) || (many > MF)) many = MF; continue; } } tree(argv[i]); dirs ++; } } for( i=0; i < many; i++) { if (c[i].size == 0) break; printf("%10d %s\n",(int)c[i].size,c[i].name); } exit (0); }