home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / C / CFLOW / FILEWDIR.C < prev    next >
Text File  |  1993-12-01  |  6KB  |  222 lines

  1. /*    filewdir.c    CI-C86 Utility Function
  2.  
  3.     Copyright (c) 1985 by:
  4.  
  5.         Lawrence R. Steeger
  6.         1009 North Jackson Street
  7.         Milwaukee, Wisconsin 53202
  8.         414-277-8149
  9. */
  10.  
  11. #include <stdio.h>
  12.  
  13. typedef    struct _files {
  14.  
  15.         struct _files *_fchain,    /* next FILES pointer */
  16.                   *_bchain;    /* previous FILES pointer */
  17.  
  18.         unsigned int _fmode;    /* original "mode" */
  19.  
  20.         unsigned char *_fspec,    /* original "filespec" */
  21.                   *_file1,    /* 1st file name */
  22.                   *_fnext;    /* next file name */
  23.     } FILES;
  24.  
  25. #define    fchain fcurr->_fchain
  26. #define bchain fcurr->_bchain
  27. #define fmode fcurr->_fmode
  28. #define    fspec fcurr->_fspec
  29. #define    file1 fcurr->_file1
  30. #define    fnext fcurr->_fnext
  31.  
  32. static    FILES *fanchor = NULL;        /* FILES anchor pointer */
  33.  
  34. /*    filewdir(filespec,mode)
  35.  
  36.     Return file name specifications that match a wildcard "filespec"
  37.     in the specified "mode".
  38.  
  39.     Returns:  (unsigned char *)    1st or next file name specification
  40.           NULL            no more file name specifications
  41.  
  42.     Note:      File name specifications returned may be freed
  43.           by using free().
  44.  
  45.           To reset all file specifications in progress
  46.           use "filewdir("")".  Any currently active
  47.           "filespec"s will be purged.
  48.  
  49.           Legal file modes are:
  50.  
  51.             0x00    Normal
  52.             0x01    Read Only
  53.             0x02    Hidden
  54.             0x04    System
  55.             0x08    Volume Label
  56.             0x10    Subdirectory
  57.             0x20    Archive
  58. */
  59.  
  60. unsigned char *filewdir(filespec, mode)
  61. unsigned char *filespec;
  62. unsigned int mode;
  63. {
  64.     unsigned char *filedir();    /* standard CI-C86 "dir" function */
  65.  
  66.     char *alloc(),            /* standard function */
  67.          *strcpy();            /* standard function */
  68.  
  69.     register FILES *fcurr,        /* FILES current entry pointer */
  70.                *ftemp;        /* FILES temporary pointer */
  71.  
  72.     unsigned char *fileptr;        /* file name specification pointer */
  73.  
  74.     if (*filespec == '\0') {    /* purge all FILES */
  75.  
  76.         for (fcurr = fanchor; fcurr != NULL;) {    /* run FILES chain */
  77.  
  78.             ftemp = fchain;
  79.  
  80.             /* free a FILES entry */
  81.  
  82.             free(fspec);
  83.             free(file1);
  84.             free((unsigned char *)fcurr);
  85.  
  86.             fcurr = ftemp;
  87.         }
  88.  
  89.         return (unsigned char *)(fanchor = NULL);
  90.     }
  91.  
  92.     /*    search FILES for matching file specification and file mode */
  93.  
  94.     for (fcurr = ftemp = fanchor;
  95.          fcurr != NULL;
  96.          ftemp = fcurr, fcurr = fchain)
  97.  
  98.         if ((strcmp(fspec, filespec) == 0)
  99.         &&  (mode == fmode))
  100.             break;
  101.  
  102.     if (fcurr != NULL) {        /* existing entry found... */
  103.  
  104.         if (*fnext) {        /* ...and a file name exists */
  105.  
  106.             fileptr = alloc((strlen(fnext) + 1));    /* file name */
  107.             strcpy(fileptr, fnext);
  108.  
  109.             fnext += (strlen(fnext) + 1);    /* next file name */
  110.  
  111.             return (fileptr);        /* return file name */
  112.         }
  113.  
  114.         /* no more file names - dechain this entry and return NULL */
  115.  
  116.         if (bchain == NULL)
  117.             fanchor = fchain;        /* 1st on chain */
  118.         else
  119.             bchain->_fchain = fchain;    /* not 1st on chain */
  120.  
  121.         /* free this entry */
  122.  
  123.         free(fspec);
  124.         free(file1);
  125.         free((unsigned char *)fcurr);
  126.  
  127.         return (NULL);            /* indicate no files left */
  128.     }
  129.  
  130.     /*    new FILES entry may be required    */
  131.  
  132.     if (*(fileptr = filedir(filespec, mode)) == '\0') {
  133.         free(fileptr);
  134.         return (NULL);            /* no file names */
  135.     }
  136.  
  137.     /*    at least 1 file name found    */
  138.  
  139.     fcurr = alloc(sizeof(FILES));        /* allocate FILES entry */
  140.  
  141.     if (ftemp == NULL)
  142.         fanchor = fcurr;        /* 1st on chain */
  143.     else
  144.         ftemp->_fchain = fcurr;        /* last on chain */
  145.  
  146.     bchain = ftemp;                /* back chain link */
  147.  
  148.     fspec = alloc(strlen(filespec) + 1);    /* save file specification */
  149.     strcpy(fspec, filespec);
  150.  
  151.     fmode = mode;                /* save file mode */
  152.  
  153.     file1 = fnext = fileptr;        /* set files' pointers */
  154.  
  155.     fileptr = alloc((strlen(fileptr) + 1));    /* get file name storage */
  156.     strcpy(fileptr, fnext);
  157.  
  158.     fnext += (strlen(fnext) + 1);        /* next file name pointer */
  159.  
  160.     return (fileptr);            /* return 1st file name */
  161. }
  162.  
  163. /*    get file directory
  164.  
  165.     note:
  166.  
  167.     this contains a bypass for the way DOS functions 0x4e and 0x4f
  168.     work.  this bypass enables true selection by mode.
  169.  
  170.     an extension has been added to "mode".  if mode = 0xffff then
  171.     all file names matching the filespec will be returned.
  172. */
  173.  
  174. unsigned char *realloc(); 
  175.  
  176. struct ff_str {
  177.   char dummy[21];        /* reserved for dos */ 
  178.   unsigned char attribute;    /* returned attribute */ 
  179.   unsigned time; 
  180.   unsigned date; 
  181.   long size;            /* size of file */ 
  182.   unsigned char fn[13];        /* string containing the filename */ 
  183. };
  184.  
  185. unsigned char *filedir(filename,mode)
  186. unsigned char *filename;
  187. unsigned mode;
  188. {
  189.   struct {int ax,bx,cx,dx,si,di,ds,es;}srv;
  190.   struct ff_str ff_area;
  191.   unsigned char *result=0;
  192.   int reslen=0; 
  193.  
  194. #ifdef _C86_BIG 
  195.   srv.ds=((unsigned long)filename)>>16; 
  196. #else 
  197.   segread(&srv.si);        /* get ds value */
  198. #endif 
  199.   srv.dx=filename;
  200.   if (mode) srv.cx=0xff;        /* set search all modes */
  201.   else srv.cx=0x00;            /* set search normal only */
  202.   bdos(0x1a,&ff_area);            /* set the transfer address */
  203.   for(srv.ax=0x4e00;!(sysint21(&srv,&srv)&1);srv.ax=0x4f00){
  204. /*    printf(":%s 0x%02x:", ff_area.fn, ff_area.attribute); */
  205.     if ((mode && !(ff_area.attribute & (unsigned char)mode))
  206.     &&  (mode != 0xffff)) {
  207. /*    printf("\n"); */
  208.     continue;
  209.     }
  210.     /* return only filenames with desired modes */
  211.     result=realloc(result,reslen+strlen(ff_area.fn)+1);
  212.     if (result==NULL) return NULL;    /* no memory left */
  213.     strcpy(result+reslen,ff_area.fn);
  214.     reslen+=strlen(ff_area.fn)+1;
  215. /*    printf("<\n"); */
  216.   } 
  217.   return realloc(result,reslen+1); 
  218. }
  219.  
  220. /*    end of filewdir.c    */
  221.  
  222.