home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2066 < prev    next >
Internet Message Format  |  1990-12-28  |  5KB

  1. From: dt@yenta.alb.nm.us (David B. Thomas)
  2. Newsgroups: alt.sources
  3. Subject: ndu -- news disk usage
  4. Message-ID: <1990Nov15.090658.8937@yenta.alb.nm.us>
  5. Date: 15 Nov 90 09:06:58 GMT
  6.  
  7. I just wrote a handy disk usage analyzer for news that I call "ndu",
  8. "news disk usage".  Like everything in unix, there is probably some
  9. wonderful command I've never noticed that does exactly the same thing
  10. this program does, only much better.  Then again, like everything in
  11. unix, this was fun to write!
  12.  
  13. It tells you, for each newsgroup, how much space it uses (excluding
  14. subdirectories, unlike du(1)), how many articles are online, and the age
  15. of the oldest article.
  16.  
  17. The output is in a format suitable for crunching by sort, awk, and them
  18. cats.
  19.  
  20. ----- begin readme -----
  21.  
  22. ndu -- "news disk usage"
  23.  
  24. ndu is a useful tool for analyzing the /usr/spool/news directory tree.
  25.  
  26. While ndu can be used to gather information about any directory tree, it
  27. was designed to analyze /usr/spool/news, and will do so by default.
  28.  
  29. Usage is:        ndu [ directory ]
  30.  
  31. The output shows, for each subdirectory (newsgroup) encountered, space
  32. used (in kb), number of files (articles), and the age of oldest file in days.
  33.  
  34. The format of the output is suitable for feeding to sort, awk, and many other
  35. nifty tools to help you analyze what's there.
  36.  
  37.  
  38. Some sample output:
  39.  
  40.    23    40     3   ./misc/test
  41.    71    46     1   ./misc/consumers/house
  42.    58    37     1   ./misc/consumers
  43.   144    52     1   ./misc/legal
  44.    71    67     3   ./misc/wanted
  45.    96    50     3   ./misc/invest
  46.   136    57     1   ./misc/kids
  47.   193   146     3   ./misc/forsale/computers
  48.   222   169     3   ./misc/forsale
  49.   ^^^-------------------------------------------space used in kb
  50.     ^^^-------------------------------------number of articles
  51.         ^-------------------------------age in days of oldest article
  52.  
  53.  
  54. Space and number of articles do not include subdirectories or their contents.
  55. Note that misc/consumers/house exceeds misc/consumers in both space used and
  56. number of articles.
  57.  
  58. Age is rounded down to the nearest day, so a 0 simply means that all files
  59. in that directory are less than 24 hours old.
  60.  
  61. BUGS
  62.       -    All file names are listed beginning with "./".
  63.       -    It does not convert the paths to newsgroup names with periods.
  64.       -    It reads directories primitive-unix-style, so it probably won't
  65. work on a non-unix system without some minor hacking.  Oh well, life is
  66. long and the program is short :-)
  67.  
  68. ----- end readme -----
  69. ----- begin ndu.c -----
  70.  
  71. /*
  72.  * ndu.c    -- news disk usage
  73.  *
  74.  *    usage:    ndu [ directory ]
  75.  *
  76.  * generates a disk usage report for all directories subordinate to and
  77.  * including the path specified (default /usr/spool/news).
  78.  *
  79.  * Each line in the report shows space used in kb, number of files, and the
  80.  * age of the oldest file in days.  Space and number of files exclude
  81.  * subdirectories and their contents, unlike du(1).
  82.  *
  83.  * Crufted up by: David B. Thomas <dt@yenta.alb.nm.us>
  84.  *
  85.  * This program is free and you can do anything you want with it, including
  86.  * saving me some embarrassment by claiming you wrote it!
  87.  *                        -dt
  88.  */
  89.  
  90. #include <stdio.h>
  91. #include <fcntl.h>
  92. #include <sys/stat.h>
  93. #include <sys/dir.h>
  94. #include <malloc.h>
  95.  
  96. #define    SECINDAY    (24 * 3600)
  97.  
  98. int    dirfunc();
  99.  
  100. char    *progname,
  101.     *topdir = "/usr/spool/news";
  102.  
  103. time_t    now;
  104.  
  105.  
  106. main(argc,argv)
  107. int    argc;
  108. char    *argv[];
  109. {
  110.     progname = argv[0];
  111.  
  112.     switch (argc) {
  113.         case 2:
  114.         topdir = argv[1];
  115.         /* fallthru */
  116.         case 1:
  117.         break;
  118.         default:
  119.         fprintf (stderr, "usage: %s [ directory ]\n", progname);
  120.         exit (-1);
  121.     }
  122.  
  123.     time(&now);
  124.     chdir (topdir);
  125.     dodir (".");
  126.  
  127.     exit (0);
  128. } /* main() */
  129.  
  130.  
  131. /*
  132.  * dodir(path)
  133.  *    recursively explores directory specified by path, tallying and
  134.  * reporting info as it goes.
  135.  */
  136.  
  137. dodir(path)
  138. char    *path;
  139. {
  140.     /* these must be stacked */
  141.     int            fd,
  142.                 nfiles = 0;
  143.     size_t            size = 0;
  144.     time_t            oldest = now;
  145.     char            *fullpath;
  146.     /* these can be overwritten -- one static copy ok */
  147.     static char        fname[DIRSIZ+1];
  148.     static struct direct    dir;
  149.     static struct stat    stt;
  150.  
  151.  
  152.     if ( (fd = open (path, O_RDONLY)) == -1) {
  153.         fprintf (stderr, "%s: can't read %s\n", progname, path);
  154.         return;
  155.     }
  156.  
  157.     while (read(fd, &dir, sizeof(struct direct)) == sizeof(struct direct)) {
  158.  
  159.         /* make a null-terminated string with the filename */
  160.         strncpy (fname, dir.d_name, DIRSIZ);
  161.         fname[DIRSIZ] = '\0';
  162.  
  163.         /* skip . and .. and empty dir slots */
  164.         if (!dir.d_ino ||
  165.             !strcmp(fname,".") ||
  166.             !strcmp(fname,"..")  )
  167.             continue;
  168.  
  169.         /* build the full path of this file */
  170.         fullpath = malloc (strlen(path)+strlen(fname)+2);
  171.         sprintf (fullpath, "%s/%s", path, fname);
  172.  
  173.         if (stat(fullpath, &stt) == -1) {
  174.             fprintf (stderr,
  175.                 "%s: cannot stat %s\n", progname, fullpath);
  176.             free (fullpath);
  177.             continue;
  178.         }
  179.         if (stt.st_mode & S_IFDIR) {
  180.             dodir (fullpath);
  181.             free (fullpath);
  182.             continue;
  183.         }
  184.         free (fullpath);
  185.         if (stt.st_mtime < oldest)
  186.             oldest = stt.st_mtime;
  187.         size += stt.st_size;
  188.         ++nfiles;
  189.     }
  190.     close (fd);
  191.     /* report size in kb, number of articles, age of oldest in days */
  192.     if (nfiles)
  193.         printf ("%5d %5d %5d   %s\n", size/1000, nfiles,
  194.             (now-oldest) / SECINDAY, path);
  195. } /* dodir() */
  196. ----- end ndu.c -----
  197.  
  198. Please send me any comments, mods, etc.        --little david
  199. -- 
  200. You mean you WUZ a Romanian....MUTHA!
  201.