home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_48.arc / FILESRCH.ARC / FILESRCH
Text File  |  1989-05-16  |  7KB  |  348 lines

  1. /* Support code from Micro Cornucopia Magazine Issue #48
  2.  
  3. Micro Cornucopia
  4. PO Box 223
  5. Bend, OR 97709 */
  6.  
  7.  
  8.  
  9. /* FILESRCH.H */
  10. /*
  11.      Header:      FileSrch (File Search)
  12.      Version:     1.00  02-Apr-1989
  13.      Language:    ANSI C with MS-DOS extensions
  14.  
  15.      This module will search subdirectories for files to be deleted. It can
  16.      query the user as to which files selected should be deleted.
  17.  
  18.      Written by Scott Robert Ladd. No rights reserved.
  19. */
  20.  
  21. #if !defined(FILESRCH_H)
  22. #define FILESRCH_H 1
  23.  
  24. #if defined(_MSC) || defined(_QC) || defined(__WATCOMC__)
  25.     #pragma pack(1)
  26. #endif
  27.  
  28. typedef
  29.   struct
  30.     {
  31.     char     reserved[21];
  32.     char     attrib;
  33.     unsigned time;
  34.     unsigned date;
  35.     long     size;
  36.     char     name[13];
  37.     }
  38.   FILE_DATA;
  39.  
  40. #if defined(_MSC) || defined(_QC) || defined(__WATCOMC__)
  41.     #pragma pack()
  42. #endif
  43.  
  44. /* attribute bit masks */
  45.  
  46. #define ATTR_READONLY   0x01 /* read only */
  47. #define ATTR_HIDDEN     0x02 /* hidden */
  48. #define ATTR_SYSTEM     0x04 /* system */
  49. #define ATTR_VOLABEL    0x08 /* volume label */
  50. #define ATTR_DIRECTORY  0x10 /* directory */
  51. #define ATTR_ARCHIVE    0x20 /* archive */
  52. #define ATTR_ALL        0x3F /* all files */
  53.  
  54. /* prototypes */
  55.  
  56. void sub_find(char * spec,
  57.               char attrib,
  58.               char * top_dir,
  59.               void (* handler)(char * dir, FILE_DATA * fd));
  60.  
  61. int wild_match(char * name, char * tmpl);
  62.  
  63. int find_first(char * spec, char attrib, FILE_DATA * fd);
  64.  
  65. int find_next(FILE_DATA * fd);
  66.  
  67. #endif
  68.  
  69.  
  70.  
  71. /* FILESRCH.C */
  72. /*
  73.      Module:      FileSrch (File Search)
  74.      Version:     1.00  02-Apr-1989
  75.      Language:    ANSI C with MS-DOS extensions
  76.  
  77.      This module will search subdirectories for files to be deleted. It can
  78.      query the user as to which files selected should be deleted.
  79.  
  80.      Written by Scott Robert Ladd. No rights reserved.
  81. */
  82.  
  83. #if defined(__TURBOC__)
  84.     #include "dir.h"
  85. #else
  86.     #include "direct.h"
  87. #endif
  88. #include "dos.h"
  89. #include "stddef.h"
  90. #include "stdlib.h"
  91. #include "string.h"
  92. #include "filesrch.h"
  93.  
  94. #if defined(M_I86SM) || defined(M_I86MM) || defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
  95.     #define SMALL_DATA_PTRS
  96. #endif
  97.  
  98. #define MAX_SPEC 128
  99.  
  100. /* global data */
  101.  
  102. static char * orig_spec;
  103. static char   srch_attr;
  104. static void (* file_func)(char * dir, FILE_DATA * fd);
  105.  
  106. static union  REGS  regs;
  107. static struct SREGS sregs;
  108.  
  109. static unsigned old_dta_seg;
  110. static unsigned old_dta_off;
  111.  
  112. /* local function prototypes */
  113.  
  114. static void sub_find_work(char * dir_spec);
  115. static void set_dta(void * new_dta);
  116. static void reset_dta(void);
  117.  
  118. /* actual program code! */
  119.  
  120. void sub_find(char * spec,
  121.               char attr,
  122.               char * dir,
  123.               void (* handler)(char * dir, FILE_DATA * fd))
  124.     {
  125.     char * start_dir;
  126.     char * orig_dir;
  127.  
  128.     if (spec != NULL)
  129.         orig_spec = strdup(spec);
  130.     else
  131.         orig_spec = "*.*";
  132.  
  133.     srch_attr = attr;
  134.     file_func = handler;
  135.  
  136.     if (dir != NULL)
  137.         {
  138.         orig_dir = malloc(MAX_SPEC);
  139.         getcwd(orig_dir,MAX_SPEC);
  140.         start_dir = strdup(dir);
  141.         }
  142.     else
  143.         {
  144.         orig_dir = NULL;
  145.         start_dir = malloc(MAX_SPEC);
  146.         getcwd(start_dir,MAX_SPEC);
  147.         }
  148.  
  149.     sub_find_work(start_dir);
  150.  
  151.     if (orig_dir != NULL)
  152.         {
  153.         chdir(orig_dir);
  154.         free(orig_dir);
  155.         }
  156.  
  157.     free(start_dir);
  158.     }
  159.  
  160. static void sub_find_work(char * dir_spec)
  161.     {
  162.     typedef struct dir_entry
  163.         {
  164.         char * direct;
  165.         struct dir_entry * next;
  166.         }
  167.         DIR_ENTRY;
  168.  
  169.     DIR_ENTRY * first_dir, * temp_dir, * cur_dir;
  170.     char * dir_buf, * work_dir;
  171.     FILE_DATA file;
  172.     int res;
  173.  
  174.     work_dir = malloc(MAX_SPEC);
  175.  
  176.     first_dir = malloc(sizeof(DIR_ENTRY));
  177.     cur_dir = first_dir;
  178.     cur_dir->next = NULL;
  179.  
  180.     chdir(dir_spec);
  181.     getcwd(work_dir,64);
  182.  
  183.     res = find_first("*.*",0xFF,&file);
  184.  
  185.     while (!res)
  186.         {
  187.         if (wild_match(file.name, orig_spec) && (file.attrib & srch_attr))
  188.             {
  189.             file_func(work_dir,&file);
  190.             }
  191.  
  192.         if (((file.attrib & 0x10) == 0x10) && (file.name[0] != '.'))
  193.             {
  194.             cur_dir->direct = strdup(file.name);
  195.             cur_dir->next   = malloc(sizeof(DIR_ENTRY));
  196.             cur_dir         = cur_dir->next;
  197.             cur_dir->next   = NULL;
  198.             }
  199.  
  200.         res = find_next(&file);
  201.         }
  202.  
  203.     dir_buf = malloc(MAX_SPEC);
  204.     cur_dir = first_dir;
  205.  
  206.     while (cur_dir->next != NULL)
  207.         {
  208.         chdir(work_dir);
  209.         chdir(cur_dir->direct);
  210.  
  211.         getcwd(dir_buf,128);
  212.         sub_find_work(dir_buf);
  213.  
  214.         temp_dir = cur_dir;
  215.         cur_dir  = cur_dir->next;
  216.  
  217.         free(temp_dir->direct);
  218.         free(temp_dir);
  219.         }
  220.     }
  221.  
  222. int wild_match(char * name, char * tmpl)
  223.     {
  224.     strupr(name);
  225.     strupr(tmpl);
  226.  
  227.     while ((*name && *name != '.') || (*tmpl && *tmpl != '.'))
  228.         {
  229.         if ((*name != *tmpl) && (*tmpl != '?'))
  230.             {
  231.             if (*tmpl != '*')
  232.                 {
  233.                 return 0;
  234.                 }
  235.             else
  236.                 {
  237.                 while (*name && *name != '.')
  238.                     name++;
  239.                 while (*tmpl && *tmpl != '.')
  240.                     tmpl++;
  241.                 break;
  242.                 }
  243.             }
  244.         else
  245.             {
  246.             name++;
  247.             tmpl++;
  248.             }
  249.         }
  250.  
  251.     if (*name == '.')
  252.         name++;
  253.  
  254.     if (*tmpl == '.')
  255.         tmpl++;
  256.  
  257.     while (*name || *tmpl)
  258.         {
  259.         if ((*name != *tmpl) && (*tmpl != '?'))
  260.             {
  261.             if (*tmpl != '*')
  262.                 return 0;
  263.             else
  264.                 return 1;
  265.             }
  266.         else
  267.             {
  268.             name++;
  269.             tmpl++;
  270.             }
  271.         }
  272.  
  273.     return 1;
  274.     }
  275.  
  276. int find_first(char * spec, char attrib, FILE_DATA * fd)
  277.     {
  278.     unsigned res;
  279.  
  280.     set_dta(fd);
  281.  
  282.     regs.h.ah = 0x4E;
  283.     regs.x.cx = (unsigned)attrib;
  284.  
  285.     #ifdef SMALL_DATA_PTRS
  286.         regs.x.dx = (unsigned)spec;
  287.         intdos(®s,®s);
  288.     #else
  289.         segread(&sregs);
  290.         sregs.ds  = FP_SEG(spec);
  291.         regs.x.dx = FP_OFF(spec);
  292.         intdosx(®s,®s,&sregs);
  293.     #endif
  294.  
  295.     res = regs.x.cflag;
  296.  
  297.     reset_dta();
  298.  
  299.     return res;
  300.     }
  301.  
  302. int find_next(FILE_DATA * fd)
  303.     {
  304.     unsigned res;
  305.  
  306.     set_dta(fd);
  307.  
  308.     regs.h.ah = 0x4F;
  309.     intdos(®s,®s);
  310.  
  311.     res = regs.x.cflag;
  312.  
  313.     reset_dta();
  314.  
  315.     return res;
  316.     }
  317.  
  318. static void set_dta(void * new_dta)
  319.     {
  320.     regs.h.ah = 0x2F;
  321.     intdosx(®s,®s,&sregs);
  322.  
  323.     old_dta_seg = sregs.es;
  324.     old_dta_off = regs.x.bx;
  325.  
  326.     regs.h.ah = 0x1A;
  327.  
  328.     #ifdef SMALL_DATA_PTRS
  329.         regs.x.dx = (unsigned)(new_dta);
  330.         intdos(®s,®s);
  331.     #else
  332.         sregs.ds  = FP_SEG(new_dta);
  333.         regs.x.dx = FP_OFF(new_dta);
  334.         intdosx(®s,®s,&sregs);
  335.     #endif
  336.     }
  337.  
  338. static void reset_dta(void)
  339.     {
  340.     segread(&sregs);
  341.  
  342.     regs.h.ah = 0x1A;
  343.     sregs.ds  = old_dta_seg;
  344.     regs.x.dx = old_dta_off;
  345.  
  346.     intdosx(®s,®s,&sregs);
  347.     }
  348.