home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / snip1091.arj / FILESRCH.C < prev    next >
C/C++ Source or Header  |  1991-09-23  |  6KB  |  287 lines

  1. /*
  2.      Module:      FileSrch (File Search)
  3.      Version:     1.01  19-Sep-1989
  4.      Language:    ANSI C with MS-DOS extensions
  5.  
  6.      This module will search subdirectories for files to be deleted. It can
  7.      query the user as to which files selected should be deleted.
  8.  
  9.      Written by Scott Robert Ladd. No rights reserved.
  10. */
  11.  
  12. #if defined(__TURBOC__)
  13.     #include <dir.h>
  14. #elif defined(LATTICE)
  15.     #include <stdio.h>
  16. #else
  17.     #include <direct.h>
  18. #endif
  19. #include <dos.h>
  20. #include <stddef.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "filesrch.h"
  24.  
  25. #if defined(M_I86SM) || defined(M_I86MM) || defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__) || defined(SPTR)
  26.     #define SMALL_DATA_PTRS
  27. #endif
  28.  
  29. #define MAX_SPEC 128
  30.  
  31. /* global data */
  32.  
  33. static char * orig_spec;
  34. static char   srch_attr;
  35. static void (* file_func)(char * dir, FILE_DATA * fd);
  36.  
  37. static union  REGS  regs;
  38. static struct SREGS sregs;
  39.  
  40. static unsigned old_dta_seg;
  41. static unsigned old_dta_off;
  42.  
  43. /* local function prototypes */
  44.  
  45. static void sub_find_work(char * dir_spec);
  46. static void set_dta(void * new_dta);
  47. static void reset_dta(void);
  48.  
  49. /* actual program code! */
  50.  
  51. void sub_find(char * spec,
  52.               char attr,
  53.               char * dir,
  54.               void (* handler)(char * dir, FILE_DATA * fd))
  55. {
  56.       char * start_dir;
  57.       char * orig_dir;
  58.  
  59.       if (spec != NULL)
  60.             orig_spec = strdup(spec);
  61.       else  orig_spec = "*.*";
  62.  
  63.       srch_attr = attr;
  64.       file_func = handler;
  65.  
  66.       if (dir != NULL)
  67.       {
  68.             orig_dir = malloc(MAX_SPEC);
  69.             getcwd(orig_dir,MAX_SPEC);
  70.             start_dir = strdup(dir);
  71.       }
  72.       else
  73.       {
  74.             orig_dir = NULL;
  75.             start_dir = malloc(MAX_SPEC);
  76.             getcwd(start_dir,MAX_SPEC);
  77.       }
  78.  
  79.       sub_find_work(start_dir);
  80.  
  81.       if (orig_dir != NULL)
  82.       {
  83.             chdir(orig_dir);
  84.             free(orig_dir);
  85.       }
  86.  
  87.       free(start_dir);
  88. }
  89.  
  90. static void sub_find_work(char * dir_spec)
  91. {
  92.       typedef struct dir_entry {
  93.             char * direct;
  94.             struct dir_entry * next;
  95.       } DIR_ENTRY;
  96.  
  97.       DIR_ENTRY * first_dir, * temp_dir, * cur_dir;
  98.       char * dir_buf, * work_dir;
  99.       FILE_DATA file;
  100.       int res;
  101.  
  102.       work_dir = malloc(MAX_SPEC);
  103.  
  104.       first_dir = malloc(sizeof(DIR_ENTRY));
  105.       cur_dir = first_dir;
  106.       cur_dir->next = NULL;
  107.  
  108.       chdir(dir_spec);
  109.       getcwd(work_dir,64);
  110.  
  111.       res = find_first("*.*",(char)0xFF,&file);
  112.  
  113.       while (!res)
  114.       {
  115.             if (wild_match(file.name, orig_spec) && (file.attrib & srch_attr))
  116.             {
  117.                   file_func(work_dir,&file);
  118.             }
  119.  
  120.             if (((file.attrib & 0x10) == 0x10) && (file.name[0] != '.'))
  121.             {
  122.                   cur_dir->direct = strdup(file.name);
  123.                   cur_dir->next   = malloc(sizeof(DIR_ENTRY));
  124.                   cur_dir         = cur_dir->next;
  125.                   cur_dir->next   = NULL;
  126.             }
  127.  
  128.             res = find_next(&file);
  129.       }
  130.  
  131.       dir_buf = malloc(MAX_SPEC);
  132.       cur_dir = first_dir;
  133.  
  134.       while (cur_dir->next != NULL)
  135.       {
  136.             chdir(work_dir);
  137.             chdir(cur_dir->direct);
  138.  
  139.             getcwd(dir_buf,128);
  140.             sub_find_work(dir_buf);
  141.  
  142.             temp_dir = cur_dir;
  143.             cur_dir  = cur_dir->next;
  144.  
  145.             free(temp_dir->direct);
  146.             free(temp_dir);
  147.       }
  148. }
  149.  
  150. int wild_match(char * name, char * tmpl)
  151. {
  152.       strupr(name);
  153.       strupr(tmpl);
  154.  
  155.       while ((*name && *name != '.') || (*tmpl && *tmpl != '.'))
  156.       {
  157.             if ((*name != *tmpl) && (*tmpl != '?'))
  158.             {
  159.                   if (*tmpl != '*')
  160.                         return 0;
  161.                   else
  162.                   {
  163.                         while (*name && *name != '.')
  164.                               name++;
  165.                         while (*tmpl && *tmpl != '.')
  166.                               tmpl++;
  167.                         break;
  168.                   }
  169.             }
  170.             else
  171.             {
  172.                   name++;
  173.                   tmpl++;
  174.             }
  175.       }
  176.  
  177.       if (*name == '.')
  178.             name++;
  179.  
  180.       if (*tmpl == '.')
  181.             tmpl++;
  182.  
  183.       while (*name || *tmpl)
  184.       {
  185.             if ((*name != *tmpl) && (*tmpl != '?'))
  186.             {
  187.                   if (*tmpl != '*')
  188.                         return 0;
  189.                   else  return 1;
  190.             }
  191.             else
  192.             {
  193.                   name++;
  194.                   tmpl++;
  195.             }
  196.       }
  197.  
  198.       return 1;
  199. }
  200.  
  201. int find_first(char * spec, char attrib, FILE_DATA * fd)
  202. {
  203.       int res;
  204.  
  205.       set_dta(fd);
  206.  
  207.       regs.h.ah = 0x4E;
  208.       regs.x.cx = (unsigned)attrib;
  209.  
  210. #if defined(SMALL_DATA_PTRS)
  211.       regs.x.dx = (unsigned)spec;
  212.  #if defined(LATTICE)
  213.       res = intdos(®s,®s);
  214.  #else
  215.       intdos(®s,®s);
  216.  #endif
  217. #else
  218.       segread(&sregs);
  219.       sregs.ds  = FP_SEG(spec);
  220.       regs.x.dx = FP_OFF(spec);
  221.  #if defined(LATTICE)
  222.       res = intdosx(®s,®s,&sregs);
  223.  #else
  224.       intdosx(®s,®s,&sregs);
  225.  #endif
  226. #endif
  227.  
  228. #if !defined(LATTICE)
  229.       res = regs.x.cflag;
  230. #endif
  231.  
  232.       reset_dta();
  233.  
  234.       return res;
  235. }
  236.  
  237. int find_next(FILE_DATA * fd)
  238. {
  239.       int res;
  240.  
  241.       set_dta(fd);
  242.  
  243.       regs.h.ah = 0x4F;
  244.  
  245. #if defined(LATTICE)
  246.       res = intdos(®s,®s);
  247. #else
  248.       intdos(®s,®s);
  249.       res = regs.x.cflag;
  250. #endif
  251.  
  252.       reset_dta();
  253.  
  254.       return res;
  255. }
  256.  
  257. static void set_dta(void * new_dta)
  258. {
  259.       regs.h.ah = 0x2F;
  260.       intdosx(®s,®s,&sregs);
  261.  
  262.       old_dta_seg = sregs.es;
  263.       old_dta_off = regs.x.bx;
  264.  
  265.       regs.h.ah = 0x1A;
  266.  
  267. #ifdef SMALL_DATA_PTRS
  268.       regs.x.dx = (unsigned)(new_dta);
  269.       intdos(®s,®s);
  270. #else
  271.       sregs.ds  = FP_SEG(new_dta);
  272.       regs.x.dx = FP_OFF(new_dta);
  273.       intdosx(®s,®s,&sregs);
  274. #endif
  275. }
  276.  
  277. static void reset_dta(void)
  278. {
  279.       segread(&sregs);
  280.  
  281.       regs.h.ah = 0x1A;
  282.       sregs.ds  = old_dta_seg;
  283.       regs.x.dx = old_dta_off;
  284.  
  285.       intdosx(®s,®s,&sregs);
  286. }
  287.