home *** CD-ROM | disk | FTP | other *** search
- /* filewdir.c CI-C86 Utility Function
-
- Copyright (c) 1985 by:
-
- Lawrence R. Steeger
- 1009 North Jackson Street
- Milwaukee, Wisconsin 53202
- 414-277-8149
- */
-
- #include <stdio.h>
-
- typedef struct _files {
-
- struct _files *_fchain, /* next FILES pointer */
- *_bchain; /* previous FILES pointer */
-
- unsigned int _fmode; /* original "mode" */
-
- unsigned char *_fspec, /* original "filespec" */
- *_file1, /* 1st file name */
- *_fnext; /* next file name */
- } FILES;
-
- #define fchain fcurr->_fchain
- #define bchain fcurr->_bchain
- #define fmode fcurr->_fmode
- #define fspec fcurr->_fspec
- #define file1 fcurr->_file1
- #define fnext fcurr->_fnext
-
- static FILES *fanchor = NULL; /* FILES anchor pointer */
-
- /* filewdir(filespec,mode)
-
- Return file name specifications that match a wildcard "filespec"
- in the specified "mode".
-
- Returns: (unsigned char *) 1st or next file name specification
- NULL no more file name specifications
-
- Note: File name specifications returned may be freed
- by using free().
-
- To reset all file specifications in progress
- use "filewdir("")". Any currently active
- "filespec"s will be purged.
-
- Legal file modes are:
-
- 0x00 Normal
- 0x01 Read Only
- 0x02 Hidden
- 0x04 System
- 0x08 Volume Label
- 0x10 Subdirectory
- 0x20 Archive
- */
-
- unsigned char *filewdir(filespec, mode)
- unsigned char *filespec;
- unsigned int mode;
- {
- unsigned char *filedir(); /* standard CI-C86 "dir" function */
-
- char *alloc(), /* standard function */
- *strcpy(); /* standard function */
-
- register FILES *fcurr, /* FILES current entry pointer */
- *ftemp; /* FILES temporary pointer */
-
- unsigned char *fileptr; /* file name specification pointer */
-
- if (*filespec == '\0') { /* purge all FILES */
-
- for (fcurr = fanchor; fcurr != NULL;) { /* run FILES chain */
-
- ftemp = fchain;
-
- /* free a FILES entry */
-
- free(fspec);
- free(file1);
- free((unsigned char *)fcurr);
-
- fcurr = ftemp;
- }
-
- return (unsigned char *)(fanchor = NULL);
- }
-
- /* search FILES for matching file specification and file mode */
-
- for (fcurr = ftemp = fanchor;
- fcurr != NULL;
- ftemp = fcurr, fcurr = fchain)
-
- if ((strcmp(fspec, filespec) == 0)
- && (mode == fmode))
- break;
-
- if (fcurr != NULL) { /* existing entry found... */
-
- if (*fnext) { /* ...and a file name exists */
-
- fileptr = alloc((strlen(fnext) + 1)); /* file name */
- strcpy(fileptr, fnext);
-
- fnext += (strlen(fnext) + 1); /* next file name */
-
- return (fileptr); /* return file name */
- }
-
- /* no more file names - dechain this entry and return NULL */
-
- if (bchain == NULL)
- fanchor = fchain; /* 1st on chain */
- else
- bchain->_fchain = fchain; /* not 1st on chain */
-
- /* free this entry */
-
- free(fspec);
- free(file1);
- free((unsigned char *)fcurr);
-
- return (NULL); /* indicate no files left */
- }
-
- /* new FILES entry may be required */
-
- if (*(fileptr = filedir(filespec, mode)) == '\0') {
- free(fileptr);
- return (NULL); /* no file names */
- }
-
- /* at least 1 file name found */
-
- fcurr = alloc(sizeof(FILES)); /* allocate FILES entry */
-
- if (ftemp == NULL)
- fanchor = fcurr; /* 1st on chain */
- else
- ftemp->_fchain = fcurr; /* last on chain */
-
- bchain = ftemp; /* back chain link */
-
- fspec = alloc(strlen(filespec) + 1); /* save file specification */
- strcpy(fspec, filespec);
-
- fmode = mode; /* save file mode */
-
- file1 = fnext = fileptr; /* set files' pointers */
-
- fileptr = alloc((strlen(fileptr) + 1)); /* get file name storage */
- strcpy(fileptr, fnext);
-
- fnext += (strlen(fnext) + 1); /* next file name pointer */
-
- return (fileptr); /* return 1st file name */
- }
-
- /* get file directory
-
- note:
-
- this contains a bypass for the way DOS functions 0x4e and 0x4f
- work. this bypass enables true selection by mode.
-
- an extension has been added to "mode". if mode = 0xffff then
- all file names matching the filespec will be returned.
- */
-
- unsigned char *realloc();
-
- struct ff_str {
- char dummy[21]; /* reserved for dos */
- unsigned char attribute; /* returned attribute */
- unsigned time;
- unsigned date;
- long size; /* size of file */
- unsigned char fn[13]; /* string containing the filename */
- };
-
- unsigned char *filedir(filename,mode)
- unsigned char *filename;
- unsigned mode;
- {
- struct {int ax,bx,cx,dx,si,di,ds,es;}srv;
- struct ff_str ff_area;
- unsigned char *result=0;
- int reslen=0;
-
- #ifdef _C86_BIG
- srv.ds=((unsigned long)filename)>>16;
- #else
- segread(&srv.si); /* get ds value */
- #endif
- srv.dx=filename;
- if (mode) srv.cx=0xff; /* set search all modes */
- else srv.cx=0x00; /* set search normal only */
- bdos(0x1a,&ff_area); /* set the transfer address */
- for(srv.ax=0x4e00;!(sysint21(&srv,&srv)&1);srv.ax=0x4f00){
- /* printf(":%s 0x%02x:", ff_area.fn, ff_area.attribute); */
- if ((mode && !(ff_area.attribute & (unsigned char)mode))
- && (mode != 0xffff)) {
- /* printf("\n"); */
- continue;
- }
- /* return only filenames with desired modes */
- result=realloc(result,reslen+strlen(ff_area.fn)+1);
- if (result==NULL) return NULL; /* no memory left */
- strcpy(result+reslen,ff_area.fn);
- reslen+=strlen(ff_area.fn)+1;
- /* printf("<\n"); */
- }
- return realloc(result,reslen+1);
- }
-
- /* end of filewdir.c */
-
-