home *** CD-ROM | disk | FTP | other *** search
/ Shareware 1 2 the Maxx / sw_1.zip / sw_1 / DISK_UTL / WORST.ZIP / WORST.C < prev    next >
C/C++ Source or Header  |  1992-07-30  |  6KB  |  362 lines

  1. /* File: WORST.C */
  2.  
  3. /* Written by Dan Lewis and released to the public domain.        */
  4.  
  5. /* Compiled using the C-Ware (DeSmet) DC88 compiler and the -px switch    */
  6. /* Bound (linked) using C-Ware (DeSmet) BIND and the -s2000 switch    */
  7.  
  8. typedef unsigned char    BOOL ;
  9. typedef unsigned char    BYTE ;
  10. typedef unsigned int    WORD ;
  11. typedef    long        DUBL ;
  12.  
  13. #define    FALSE    0
  14. #define    TRUE    1
  15.  
  16. #define    NULL    ((void *) 0)
  17.  
  18. #define    READ_ONLY    0x01
  19. #define    HIDDEN        0x02
  20. #define    SYSTEM        0x04
  21. #define    VOL_LABEL    0x08
  22. #define    DIR_ENTRY    0x10
  23. #define    ARCHIVE        0x20
  24.  
  25. #define    FIND_ATTB    (HIDDEN|SYSTEM|DIR_ENTRY)
  26.  
  27. #define    FIND_FIRST    0x4E
  28. #define    FIND_NEXT    0x4F
  29.  
  30. typedef struct TIME
  31.     {
  32.     unsigned
  33.     hsec:5,        /* seconds/2 (0-29)    */
  34.     min:6,        /* minute (0-59)    */
  35.     hour:5 ;    /* hour (0-23)    */
  36.     } TIME ;
  37.  
  38. typedef struct DATE
  39.     {
  40.     unsigned
  41.         day:5,        /* day (1-31)    */
  42.         month:4,    /* month (1-12)    */
  43.         year:7 ;    /* year - 1980    */
  44.     } DATE ;
  45.  
  46. typedef struct DTA
  47.     {
  48.     char    rsvd[21] ;
  49.     char    attb ;
  50.     TIME    time ;
  51.     DATE    date ;
  52.     long    size ;
  53.     char    name[13] ;
  54.     } DTA ;
  55.  
  56. typedef struct STAT
  57.     {
  58.     char    *name ;
  59.     char    file[100] ;
  60.     TIME    time ;
  61.     DATE    date ;
  62.     DUBL    size ;
  63.     } STAT ;
  64.  
  65. #define    NEWER(a, b)    (*((DUBL *) &a.time) > *((DUBL *) &b.time))
  66.  
  67. BOOL found = FALSE ;
  68. char *slash ;
  69.  
  70. STAT newest   = {"Newest"} ;
  71. STAT oldest   = {"Oldest"} ;
  72. STAT largest  = {"Largest"} ;
  73. STAT smallest = {"Smallest"} ;
  74.  
  75. void Set_DTA(DTA *) ;
  76. BOOL Find(BYTE, char *, WORD) ;
  77. void Replace(STAT *, char *, DTA *) ;
  78. void Get_Root(char *, char *) ;
  79. void Header(void) ;
  80. char *Time(TIME *) ;
  81. char *Date(DATE *) ;
  82. void Empty(char *, DTA *) ;
  83. DUBL Search(char *, BOOL) ;
  84. void Display(STAT *) ;
  85. void Clean(char *) ;
  86.  
  87. void Set_DTA(dta)
  88. DTA *dta ;
  89.     {
  90. #ifndef    _lint
  91. #asm
  92.     mov    ah,1Ah
  93.     mov    dx,#dta
  94.     int    21h
  95. #end
  96. #endif
  97.     }
  98.  
  99. BOOL Find(mode, spec, attb)
  100. BYTE mode ;
  101. char *spec ;
  102. WORD attb ;
  103.     {
  104. #ifndef    _lint
  105. #asm
  106.     mov    ah,#mode
  107.     xor    al,al
  108.     mov    cx,#attb
  109.     mov    dx,#spec
  110.     int    21h
  111.     mov    ax,0
  112.     jc    Fail1
  113.     inc    ax
  114. Fail1:
  115. #end
  116. #endif
  117.     }
  118.  
  119. void Replace(stat, dir, dta)
  120. STAT *stat ;
  121. char *dir ;
  122. DTA *dta ;
  123.     {
  124.     strcpy(stat->file, dir) ;
  125.     strcat(stat->file, dta->name) ;
  126.     stat->time = dta->time ;
  127.     stat->date = dta->date ;
  128.     stat->size = dta->size ;
  129.     found = TRUE ;
  130.     }
  131.  
  132. void Get_Root(spec, root)
  133. char *spec ;
  134. char *root ;
  135.     {
  136.     char temp[100] ;
  137.     char *token ;
  138.     BOOL first ;
  139.  
  140.     first = TRUE ;
  141.     strcpy(temp, spec) ;
  142.     strcpy(root, "") ;
  143.  
  144.     for (token = temp; token = strtok(token, "\\/"); token = NULL)
  145.         {
  146.         if (!first || strchr("\\/", spec[0])) strcat(root, slash) ;
  147.         first = FALSE ;
  148.         if (strpbrk(token, "?*")) break ;
  149.         strcat(root, token) ;
  150.         }
  151.     }
  152.  
  153. void Header()
  154.     {
  155.     static BOOL virgin = TRUE ;
  156.  
  157.     if (!virgin) return ;
  158.     printf("Category   Date    Time     Bytes File or Directory Name\n") ;
  159.     printf("-------- -------- ------ -------- -------------------------");
  160.     printf("\n") ;
  161.     virgin = FALSE ;
  162.     }
  163.  
  164. char *Time(t)
  165. TIME *t ;
  166.     {
  167.     static char time[7] ;
  168.     char ampm ;
  169.  
  170.     if (t->hour >= 12)
  171.         {
  172.         t->hour -= 12 ;
  173.         ampm = 'p' ;
  174.         }
  175.     else ampm = 'a' ;
  176.     sprintf(time, "%2u:%02u%c", t->hour, t->min, ampm) ;
  177.     return time ;
  178.     }
  179.  
  180. char *Date(d)
  181. DATE *d ;
  182.     {
  183.     static char date[9] ;
  184.  
  185.     sprintf(date, "%2u-%02u-%02u", d->month, d->day,
  186.         (d->year + 1980) % 100) ;
  187.     return date ;
  188.     }
  189.  
  190. void Clean(spec)
  191. char *spec ;
  192.     {
  193.     char *p = spec ;
  194.  
  195.     while ((p = strstr(p, ".\\")) || (p = strstr(p, "./")))
  196.         {
  197.         if (p == spec || p[-1] != '.') strcpy(p, p + 2) ;
  198.         else p++ ;
  199.         }
  200.     }
  201.  
  202. void Empty(dir, dta)
  203. char *dir ;
  204. DTA *dta ;
  205.     {
  206.     Header() ;
  207.     printf("Empty    %s %s %8lu %s%s%s\n",
  208.         Date(&dta->date),
  209.         Time(&dta->time),
  210.         dta->size,
  211.         dir,
  212.         dta->name,
  213.         slash) ;
  214.     found = TRUE ;
  215.     }
  216.  
  217. DUBL Search(spec, recurse)
  218. char *spec ;
  219. BOOL recurse ;
  220.     {
  221.     char dir[100] ;
  222.     DUBL bytes, dbytes ;
  223.     BYTE mode ;
  224.     DTA dta ;
  225.  
  226.  
  227.     bytes = 0L ;
  228.     Get_Root(spec, dir) ;
  229.  
  230.     Set_DTA(&dta) ;
  231.     mode = FIND_FIRST ;
  232.     while (Find(mode, spec, FIND_ATTB))
  233.         {
  234.         mode = FIND_NEXT ;
  235.         if (!strcmp(dta.name, "."))    continue ;
  236.         if (!strcmp(dta.name, ".."))    continue ;
  237.  
  238.         if (dta.attb & DIR_ENTRY)
  239.             {
  240.             if (recurse)
  241.                 {
  242.                 strcpy(spec, dir) ;
  243.                 strcat(spec, dta.name) ;
  244.                 strcat(spec, slash) ;
  245.                 strcat(spec, "*.*") ;
  246.                 dbytes = Search(spec, recurse) ;
  247.                 if (!dbytes) Empty(dir, &dta) ;
  248.                 bytes += dbytes ;
  249.                 Set_DTA(&dta) ;
  250.                 }
  251.             continue ;
  252.             }
  253.  
  254.         bytes += dta.size ;
  255.  
  256.         if (NEWER(dta, newest))       Replace(&newest,   dir, &dta) ;
  257.         if (NEWER(oldest, dta))       Replace(&oldest,   dir, &dta) ;
  258.  
  259.         if (dta.size > largest.size)  Replace(&largest,  dir, &dta) ;
  260.         if (dta.size < smallest.size) Replace(&smallest, dir, &dta) ;
  261.         }
  262.  
  263.     return bytes ;
  264.     }
  265.  
  266. void Display(stat)
  267. STAT *stat ;
  268.     {
  269.     printf("%-8s %s %s %8lu %s\n",
  270.         stat->name,
  271.         Date(&stat->date),
  272.         Time(&stat->time),
  273.         stat->size,
  274.         stat->file) ;
  275.     }
  276.  
  277. main(argc, argv)
  278. unsigned argc ;
  279. char *argv[] ;
  280.     {
  281.     BOOL recurse, searched ;
  282.     char spec[100] ;
  283.     unsigned arg ;
  284.     DTA dta ;
  285.  
  286.  
  287.     smallest.size = 0x7FFFFFFFL ;
  288.     *((DUBL *) &oldest.time)   = 0x7FFFFFFFL ;
  289.  
  290.     slash = "\\" ;
  291.     for (arg = 1; arg < argc; arg++)
  292.         {
  293.         if (!strchr(argv[arg], '/')) continue ;
  294.         slash = "/" ;
  295.         break ;
  296.         }
  297.  
  298.     recurse = FALSE ;
  299.     strcpy(spec, "*.*") ;
  300.  
  301.     printf("\n") ;
  302.     searched = FALSE ;
  303.     for (arg = 1; arg < argc; arg++)
  304.         {
  305.         strupr(argv[arg]) ;
  306.         if (!strcmp(argv[arg], "+S"))
  307.             {
  308.             recurse = TRUE ;
  309.             continue ;
  310.             }
  311.  
  312.         if (!strcmp(argv[arg], "-S"))
  313.             {
  314.             recurse = FALSE ;
  315.             continue ;
  316.             }
  317.  
  318.         strcpy(spec, argv[arg]) ;
  319.         switch (spec[strlen(spec) - 1])
  320.             {
  321.             case ':':
  322.             case '/':
  323.             case '\\':
  324.                 strcat(spec, "*.*") ;
  325.                 break ;
  326.  
  327.             case '.':
  328.                 strcat(spec, slash) ;
  329.                 strcat(spec, "*.*") ;
  330.                 break ;
  331.             }
  332.  
  333.         Set_DTA(&dta) ;
  334.         if (!strpbrk(spec, "*?")    &&
  335.             Find(0x4E, spec, FIND_ATTB)    &&
  336.             (dta.attb & DIR_ENTRY))
  337.             {
  338.             strcat(spec, slash) ;
  339.             strcat(spec, "*.*") ;
  340.             }
  341.  
  342.         Clean(spec) ;
  343.         Search(spec, recurse) ;
  344.         searched = TRUE ;
  345.         }
  346.  
  347.     if (!searched) Search(spec, recurse) ;
  348.  
  349.     if (!found)
  350.         {
  351.         printf("\tNo files matching '%s'!\7\n", spec) ;
  352.         exit(0xFF) ;
  353.         }
  354.  
  355.     Header() ;
  356.     Display(&smallest) ;
  357.     Display(&largest) ;
  358.     Display(&oldest) ;
  359.     Display(&newest) ;
  360.     exit(0x00) ;
  361.     }
  362.