home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 270_01 / est.c < prev    next >
Text File  |  1979-12-31  |  8KB  |  367 lines

  1. /*    HEADER: CUG270;
  2.     TITLE:    Find largest, smallest, oldest, newest files;
  3.     DATE:    5/16/88;
  4.     DESCRIPTION: "Lists n largest, smallest, oldest, newest files
  5.         from a given path specification under MS-DOS.  Illustrates
  6.         use of _makepath, _splitpath, _dos_findfirst & _dos_findnext;
  7.     KEYWORDS:  _makepath, _splitpath, _dos_findfirst, _dos_findnext;
  8.     SYSTEM: MS-DOS;
  9.     FILENAME: EST.C;
  10.     WARNINGS: Uses library functions specific to Microsoft C5.0;
  11.     COMPILERS: Microsoft;
  12.     AUTHOR: Les Aldridge;
  13. */
  14. /*
  15.  * Produced by Programming ARTS
  16.  * PO Box 219
  17.  * Milltown, NJ 08850 (201) 846-7242
  18.  * 5/16/88
  19.  * Programmer: Les Aldridge
  20.  *
  21. */
  22. /*
  23.  * EST Program: i.e. largEST, smallEST, oldEST, newEST files in a group.
  24.  *    Program idea suggested by Chris Chuba of DIALOGIC Corp.
  25.  *       Implemented by Les Aldridge.
  26.  *    This program may be freely distributed but not sold.
  27.  *
  28.  * Copyright (c) 1988 Programming ARTS.
  29. */
  30. #include <dos.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <malloc.h>
  34. #include <ctype.h>
  35.  
  36. #define OLDX    0
  37. #define NEWX    1
  38. #define LARGEX    2
  39. #define SMALLX    3
  40.  
  41. struct fdata {
  42.     unsigned    time, date;
  43.     long        size;
  44.     char        path[40];
  45.     char        name[13];
  46. };
  47.  
  48. static short    cmpold(struct find_t *ptr, struct fdata *fdp)
  49. {
  50.     if ((ptr->wr_date < fdp->date)
  51.     || ((ptr->wr_date == fdp->date) && (ptr->wr_time < fdp->time)))
  52.         return(1);
  53.     else
  54.         return(0);
  55. }
  56.  
  57.  
  58. static short    cmpnew(struct find_t *ptr, struct fdata *fdp)
  59. {
  60.     if ((ptr->wr_date > fdp->date)
  61.     || ((ptr->wr_date == fdp->date) && (ptr->wr_time > fdp->time)))
  62.         return(1);
  63.     else
  64.         return(0);
  65. }
  66.  
  67. static short    cmplarge(struct find_t *ptr, struct fdata *fdp)
  68. {
  69.     if (ptr->size > fdp->size) return(1);
  70.     else return(0);
  71. }
  72.  
  73.  
  74. static short    cmpsmall(struct find_t *ptr, struct fdata *fdp)
  75. {
  76.     if (ptr->size < fdp->size) return(1);
  77.     else return(0);
  78. }
  79.  
  80. static struct estobj {
  81.     short            flag;
  82.     char            *ename;
  83.     struct fdata    **eptr;
  84.     short            (*compare)(struct find_t *, struct fdata *);
  85. }     obj[] = {
  86.         { 0, "Oldest",   NULL, cmpold },
  87.         { 0, "Newest",   NULL, cmpnew },
  88.         { 0, "Largest",  NULL, cmplarge },
  89.         { 0, "Smallest", NULL, cmpsmall }
  90.     };
  91.  
  92. static char        drive[8], dir[40], fpath[40], dpath[80];
  93. static char        fil[16], ext[8];
  94. static short    subds, maxf;
  95.  
  96. static void *stalloc(short count, short size)
  97. {
  98.     void  *p;
  99.  
  100.     p = calloc(count, size);
  101.     if (p == NULL)
  102.     {
  103.         printf("Memory allocation error.\n");
  104.         exit(1);
  105.     }
  106.     return(p);
  107. }
  108.  
  109. static void update(struct fdata *fd, struct find_t *ptr, char *path)
  110. {
  111.     /*
  112.     * Fill in the file data.
  113.     */
  114.     strcpy(fd->name, ptr->name);
  115.     strcpy(fd->path, path);
  116.     fd->size = ptr->size;
  117.     fd->date = ptr->wr_date;
  118.     fd->time = ptr->wr_time;
  119. }
  120.  
  121. static void chk(struct find_t *ptr, char *path)
  122. {
  123.     /*
  124.     * Check file against n members of selected group for
  125.     * the __est so far.
  126.     *
  127.     * Uses array of ptrs to struct fdata.
  128.     * Each array consists of maxf+1 ptrs.
  129.     * Whenever a file passes the criterion to fit into a group (i.e it is
  130.     * older, newer, etc. one member of the array will be displaced and the
  131.     * new member will fill a slot in the array.  Members are pushed down to
  132.     * accomodate the new member.  The 'maxf'th member is pushed out. 
  133.     */
  134.     short  i, j, est = 0;
  135.     struct fdata   *fdp, *out;
  136.  
  137.     for (i = 0; i < 4; i++)
  138.     {
  139.         if (obj[i].flag)
  140.         {
  141.             out = obj[i].eptr[maxf];
  142.             for (j = maxf-1; j >=0; j--)
  143.             {
  144.                 fdp = obj[i].eptr[j];
  145.                 if ((fdp->date == 0) || (obj[i].compare(ptr, fdp)))
  146.                 {
  147.                      est++;
  148.                      obj[i].eptr[j+1] = fdp;
  149.                 }
  150.                 else
  151.                      break;
  152.             }
  153.             if (est)
  154.             {
  155.                 obj[i].eptr[j+1] = out;
  156.                 update(out, ptr, path);
  157.             }
  158.         }
  159.     }
  160. }
  161.  
  162. static void makefp(char *d, char *f, char *fp)
  163. {
  164.     _splitpath(f, NULL, NULL, fil, ext);
  165.     _makepath(fp, NULL, d, fil, ext);
  166. }
  167.  
  168.  
  169. static void findfiles(char *dp, char *fp)
  170. {
  171.     /*
  172.     * Possibly-recursive procedure to find files.
  173.     */
  174.     char           *wkp;
  175.     short          ret;
  176.     struct find_t  *bp;
  177.  
  178.     bp = stalloc(1, sizeof(struct find_t));
  179.     wkp = stalloc(1, 40);
  180.  
  181.     if (subds)  /* search subdirectories */
  182.     {
  183.         makefp(dp, "*", wkp);
  184.         ret =_dos_findfirst(wkp, _A_SUBDIR, bp);
  185.         while (ret == 0)
  186.         {
  187.             if (bp->attrib & _A_SUBDIR) 
  188.             {
  189.                  if (*(bp->name) != '.')
  190.                  {
  191.                      makefp(dp, bp->name, wkp);
  192.                      findfiles(wkp, fp);
  193.                  }
  194.             }
  195.             ret = _dos_findnext(bp);
  196.         }
  197.     }
  198.     makefp(dp, fp, wkp);
  199.     ret = _dos_findfirst(wkp, _A_NORMAL, bp);
  200.     while (ret == 0)
  201.     {
  202.         chk(bp, dp);
  203.         ret = _dos_findnext(bp);
  204.     }
  205.     free(bp);
  206.     free(wkp);
  207. }
  208.  
  209. static void mkdate(struct fdata *fp, char *str)
  210. {
  211.     unsigned yr, mn, da, hr, min, sec, d, t;
  212.  
  213.     t = fp->time;
  214.     d = fp->date;
  215.     yr = (d >> 9)+80;
  216.     mn = (d >> 5) & 0xF;
  217.     da = d & 0x1F;
  218.     hr = t >> 11;
  219.     min = (t >>5) & 0x3F;
  220.     sec = t & 0x1F;
  221.     sprintf(str, "%02u/%02u/%02u  %02u:%02u:%02u",
  222.                  mn, da, yr, hr, min, sec);
  223. }
  224.  
  225. static char dtstr[50];
  226.     
  227. static void prt(struct fdata  *fd[])
  228. {
  229.     short i;
  230.     struct fdata *fp;
  231.  
  232.     for (i = 0; i < maxf; i++)
  233.     {
  234.         fp = fd[i];
  235.         if (fp->date == 0) continue;
  236.         mkdate(fp, dtstr);
  237.         _splitpath(fp->name, NULL, NULL, fil, ext);
  238.         _makepath(dpath, NULL, fp->path, fil, ext);
  239.         printf("%-44s %9lu %s\n", dpath, fp->size, dtstr);
  240.     }
  241. }
  242.  
  243.  
  244. static void tballoc(struct fdata *tb[], short count, short size)
  245. {
  246.     short i;
  247.  
  248.     for (i = 0; i <= count; i++)
  249.     {
  250.         tb[i] = stalloc(1, size);
  251.     }
  252. }
  253.  
  254. static void    prmsg(void)
  255. {
  256.         printf("\nCopyright 1988 Programming ARTS\n");
  257.         printf("\nUSAGE: est [/onlsd<nn>] <path>\n");
  258.         printf("  Options: /o = list   oldest files.\n");
  259.         printf("           /n = list   newest files.\n");
  260.         printf("           /l = list  largest files.\n");
  261.         printf("           /s = list smallest files.\n");
  262.         printf("           /d = search subdirectories.\n");
  263.         printf("           /<nn> = # of files in group to list.\n");
  264.         printf("NOTE: if <path> is a directory, it must end with \\.\n\n");
  265.         printf("Example: est /old5 \\*.*\n");
  266.         printf("  Will list the 5 oldest and 5 largest files on the\n");
  267.         printf("  current drive searching all subdirectories.\n\n");
  268. }
  269.  
  270.  
  271. short    main(short  arity, char  *param[])
  272. {
  273.     short            p, i;
  274.     char            *fptr = NULL, *pp;
  275.  
  276.     if (arity < 2)
  277.     {
  278.         prmsg();
  279.         exit(0);                                              
  280.     }
  281.     maxf = 10;
  282.     for (p = 1; p < arity; p++) 
  283.     {
  284.         pp = param[p];
  285.         if (*pp == '/' || *pp == '-')
  286.         {
  287.             for (pp++; *pp; pp++)
  288.             {
  289.                  switch (*pp)
  290.                  {
  291.                  case 'o' :
  292.                  case 'O' :
  293.                      obj[OLDX].flag = 1;
  294.                      break;
  295.                  case 'n' :
  296.                  case 'N' :
  297.                      obj[NEWX].flag = 1;
  298.                      break;
  299.                  case 'l' :
  300.                  case 'L' :
  301.                      obj[LARGEX].flag = 1;
  302.                      break;
  303.                  case 's' :
  304.                  case 'S' :
  305.                      obj[SMALLX].flag = 1;
  306.                      break;
  307.                  case 'd' :
  308.                  case 'D' :
  309.                      subds = 1;
  310.                        break;
  311.                  default :
  312.                      if (isdigit(*pp)) maxf = atoi(pp);
  313.                      else
  314.                      {
  315.                         prmsg();
  316.                         exit(1);
  317.                      }
  318.                      while (isdigit(*(pp+1))) { pp++; }
  319.                      if (maxf <= 0)
  320.                      {
  321.                          printf("\nInvalid numeric parameter.\n");
  322.                         exit(1);
  323.                      }
  324.                      break;
  325.                  }
  326.             }
  327.         }
  328.         else
  329.             fptr = param[p];
  330.     }
  331.     if (fptr == NULL) fptr = "*.*";
  332.     if ((obj[0].flag+obj[1].flag+obj[2].flag+obj[3].flag) == 0)
  333.     {
  334.         prmsg();    /* no criterion specified */
  335.         exit(0);
  336.     }
  337.     for (i = 0; i < 4; i++)
  338.     {
  339.         if (obj[i].flag)
  340.         {
  341.             obj[i].eptr = stalloc(maxf+1, sizeof(struct fdata *));
  342.             tballoc(obj[i].eptr, maxf, sizeof(struct fdata));
  343.         }
  344.     }
  345.  
  346.     _splitpath(fptr, drive, dir, fil, ext);
  347.     _makepath(dpath, drive, dir, NULL, NULL);
  348.     if (dpath[0] == 0) getcwd(dpath, 30);
  349.     if (fil[0] == 0) strcpy(fil, "*.*");
  350.     _makepath(fpath, NULL, NULL, fil, ext);
  351.  
  352.     findfiles(dpath, fpath);
  353.     /*
  354.     * print results
  355.     */
  356.     for (i = 0; i < 4; i++)
  357.     {
  358.         if (obj[i].flag)
  359.         {
  360.             if (maxf == 1) printf("\nThe %s File:\n", obj[i].ename);
  361.             else printf("\nThe %d %s Files:\n", maxf, obj[i].ename);
  362.             prt(obj[i].eptr);
  363.         }
  364.     }    
  365. }
  366.  
  367.