Release 950403
[wine/multimedia.git] / misc / dos_fs.c
blobdfc69ddbc828c1c38549278c013023967f4118c0
1 /*
2 * DOS-FS
3 * NOV 1993 Erik Bos <erik@xs4all.nl>
5 * FindFile by Bob, hacked for dos & unixpaths by Erik.
7 * Bugfix by dash@ifi.uio.no: ToUnix() was called to often
8 */
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <pwd.h>
16 #include <dirent.h>
17 #include <unistd.h>
18 #include <fcntl.h>
20 #if defined(__linux__) || defined(sun)
21 #include <sys/vfs.h>
22 #endif
23 #if defined(__NetBSD__) || defined(__FreeBSD__)
24 #include <sys/param.h>
25 #include <sys/mount.h>
26 #endif
28 #include "wine.h"
29 #include "windows.h"
30 #include "msdos.h"
31 #include "dos_fs.h"
32 #include "autoconf.h"
33 #include "comm.h"
34 #include "stddebug.h"
35 #include "debug.h"
37 #define WINE_INI_USER "~/.winerc"
38 #define MAX_OPEN_DIRS 16
39 #define MAX_DOS_DRIVES 26
41 extern char WindowsDirectory[256], SystemDirectory[256],TempDirectory[256];
43 char WindowsPath[256];
45 static int CurrentDrive = 2;
47 struct DosDriveStruct { /* eg: */
48 char *rootdir; /* /usr/windows */
49 char cwd[256]; /* / */
50 char label[13]; /* DRIVE-A */
51 unsigned int serialnumber; /* ABCD5678 */
52 int disabled; /* 0 */
55 static struct DosDriveStruct DosDrives[MAX_DOS_DRIVES];
56 static struct dosdirent DosDirs[MAX_OPEN_DIRS];
58 static void ExpandTildeString(char *s)
60 struct passwd *entry;
61 char temp[1024], *ptr = temp;
63 strcpy(temp, s);
65 while (*ptr)
67 if (*ptr != '~')
69 *s++ = *ptr++;
70 continue;
73 ptr++;
75 if ( (entry = getpwuid(getuid())) == NULL)
77 continue;
80 strcpy(s, entry->pw_dir);
81 s += strlen(entry->pw_dir);
83 *s = 0;
86 void ChopOffSlash(char *path)
88 if (path[strlen(path)-1] == '/' || path[strlen(path)-1] == '\\')
89 path[strlen(path)-1] = '\0';
92 void ToUnix(char *s)
94 /* \WINDOWS\\SYSTEM => /windows/system */
96 char *p;
98 for (p = s; *p; p++)
100 if (*p != '\\')
101 *s++ = tolower(*p);
102 else {
103 *s++ = '/';
104 if (*(p+1) == '/' || *(p+1) == '\\')
105 p++;
108 *s = '\0';
111 void ToDos(char *s)
113 /* /windows//system => \WINDOWS\SYSTEM */
115 char *p;
116 for (p = s; *p; p++)
118 if (*p != '/')
119 *s++ = toupper(*p);
120 else {
121 *s++ = '\\';
122 if (*(p+1) == '/' || *(p+1) == '\\')
123 p++;
126 *s = '\0';
129 void DOS_InitFS(void)
131 int x;
132 char drive[2], temp[256];
134 GetPrivateProfileString("wine", "windows", "c:\\windows",
135 WindowsDirectory, sizeof(WindowsDirectory), WINE_INI);
137 GetPrivateProfileString("wine", "system", "c:\\windows\\system",
138 SystemDirectory, sizeof(SystemDirectory), WINE_INI);
140 GetPrivateProfileString("wine", "temp", "c:\\windows",
141 TempDirectory, sizeof(TempDirectory), WINE_INI);
143 GetPrivateProfileString("wine", "path", "c:\\windows;c:\\windows\\system",
144 WindowsPath, sizeof(WindowsPath), WINE_INI);
146 ChopOffSlash(WindowsDirectory);
147 ToDos(WindowsDirectory);
149 ChopOffSlash(SystemDirectory);
150 ToDos(SystemDirectory);
152 ChopOffSlash(TempDirectory);
153 ToDos(TempDirectory);
155 ToDos(WindowsPath);
156 ExpandTildeString(WindowsPath);
158 for (x=0; x!=MAX_DOS_DRIVES; x++) {
159 DosDrives[x].serialnumber = (0xEB0500L | x);
161 drive[0] = 'A' + x;
162 drive[1] = '\0';
163 GetPrivateProfileString("drives", drive, "*", temp, sizeof(temp), WINE_INI);
164 if (!strcmp(temp, "*") || *temp == '\0') {
165 DosDrives[x].rootdir = NULL;
166 DosDrives[x].cwd[0] = '\0';
167 DosDrives[x].label[0] = '\0';
168 DosDrives[x].disabled = 1;
169 continue;
171 ExpandTildeString(temp);
172 ChopOffSlash(temp);
173 DosDrives[x].rootdir = strdup(temp);
174 strcpy(DosDrives[x].rootdir, temp);
175 strcpy(DosDrives[x].cwd, "/windows/");
176 strcpy(DosDrives[x].label, "DRIVE-");
177 strcat(DosDrives[x].label, drive);
178 DosDrives[x].disabled = 0;
180 DosDrives[25].rootdir = "/";
181 strcpy(DosDrives[25].cwd, "/");
182 strcpy(DosDrives[25].label, "UNIX-FS");
183 DosDrives[25].serialnumber = 0x12345678;
184 DosDrives[25].disabled = 0;
186 /* Get the startup directory and try to map it to a DOS drive
187 * and directory. (i.e., if we start in /dos/windows/word and
188 * drive C is defined as /dos, the starting wd for C will be
189 * /windows/word) Also set the default drive to whatever drive
190 * corresponds to the directory we started in.
193 for (x=0; x!=MAX_DOS_DRIVES; x++)
194 if (DosDrives[x].rootdir != NULL)
195 strcpy( DosDrives[x].cwd, "\\" );
197 getcwd(temp, 254);
198 strcat(temp, "/"); /* For DOS_GetDosFileName */
199 strcpy(temp, DOS_GetDosFileName(temp));
200 if(temp[0] != 'Z')
202 ToUnix(&temp[2]);
203 strcpy(DosDrives[temp[0] - 'A'].cwd, &temp[2]);
204 DOS_SetDefaultDrive(temp[0] - 'A');
206 else
208 DOS_SetDefaultDrive(2);
211 for (x=0; x!=MAX_DOS_DRIVES; x++) {
212 if (DosDrives[x].rootdir != NULL) {
213 dprintf_dosfs(stddeb, "DOSFS: %c: => %-40s %s %s %X %d\n",
214 'A'+x,
215 DosDrives[x].rootdir,
216 DosDrives[x].cwd,
217 DosDrives[x].label,
218 DosDrives[x].serialnumber,
219 DosDrives[x].disabled
224 for (x=0; x!=MAX_OPEN_DIRS ; x++)
225 DosDirs[x].inuse = 0;
227 dprintf_dosfs(stddeb,"wine.ini = %s\n",WINE_INI);
228 dprintf_dosfs(stddeb,"win.ini = %s\n",WIN_INI);
229 dprintf_dosfs(stddeb,"windir = %s\n",WindowsDirectory);
230 dprintf_dosfs(stddeb,"sysdir = %s\n",SystemDirectory);
231 dprintf_dosfs(stddeb,"tempdir = %s\n",TempDirectory);
232 dprintf_dosfs(stddeb,"path = %s\n",WindowsPath);
235 WORD DOS_GetEquipment(void)
237 WORD equipment;
238 int diskdrives = 0;
239 int parallelports = 0;
240 int serialports = 0;
241 int x;
243 /* borrowed from Ralph Brown's interrupt lists
245 bits 15-14: number of parallel devices
246 bit 13: [Conv] Internal modem
247 bit 12: reserved
248 bits 11- 9: number of serial devices
249 bit 8: reserved
250 bits 7- 6: number of diskette drives minus one
251 bits 5- 4: Initial video mode:
252 00b = EGA,VGA,PGA
253 01b = 40 x 25 color
254 10b = 80 x 25 color
255 11b = 80 x 25 mono
256 bit 3: reserved
257 bit 2: [PS] =1 if pointing device
258 [non-PS] reserved
259 bit 1: =1 if math co-processor
260 bit 0: =1 if diskette available for boot
262 /* Currently the only of these bits correctly set are:
263 bits 15-14 } Added by William Owen Smith,
264 bits 11-9 } wos@dcs.warwick.ac.uk
265 bits 7-6
266 bit 2 (always set)
269 if (DosDrives[0].rootdir != NULL)
270 diskdrives++;
271 if (DosDrives[1].rootdir != NULL)
272 diskdrives++;
273 if (diskdrives)
274 diskdrives--;
276 for (x=0; x!=MAX_PORTS; x++) {
277 if (COM[x].devicename)
278 serialports++;
279 if (LPT[x].devicename)
280 parallelports++;
282 if (serialports > 7) /* 3 bits -- maximum value = 7 */
283 serialports=7;
284 if (parallelports > 3) /* 2 bits -- maximum value = 3 */
285 parallelports=3;
287 equipment = (diskdrives << 6) | (serialports << 9) |
288 (parallelports << 14) | 0x02;
290 dprintf_dosfs(stddeb, "DOS_GetEquipment : diskdrives = %d serialports = %d "
291 "parallelports = %d\n"
292 "DOS_GetEquipment : equipment = %d\n",
293 diskdrives, serialports, parallelports, equipment);
295 return (equipment);
298 int DOS_ValidDrive(int drive)
300 int valid = 1;
302 dprintf_dosfs(stddeb,"ValidDrive %c (%d) -- ",'A'+drive,drive);
304 if (drive >= MAX_DOS_DRIVES)
305 valid = 0;
306 if (DosDrives[drive].rootdir == NULL)
307 valid = 0;
308 if (DosDrives[drive].disabled)
309 valid = 0;
311 dprintf_dosfs(stddeb, "%s\n", valid ? "Valid" : "Invalid");
312 return valid;
316 int DOS_ValidDirectory(char *name)
318 char *dirname;
319 struct stat s;
320 dprintf_dosfs(stddeb, "DOS_ValidDirectory: '%s'\n", name);
321 if ((dirname = DOS_GetUnixFileName(name)) == NULL)
322 return 0;
323 if (stat(dirname,&s))
324 return 0;
325 if (!S_ISDIR(s.st_mode))
326 return 0;
327 dprintf_dosfs(stddeb, "==> OK\n");
328 return 1;
333 /* Simplify the path in "name" by removing "//"'s and
334 ".."'s in names like "/usr/bin/../lib/test" */
335 void DOS_SimplifyPath(char *name)
337 char *l,*p;
338 BOOL changed;
340 dprintf_dosfs(stddeb,"SimplifyPath: Before %s\n",name);
341 do {
342 changed = FALSE;
343 while ((l = strstr(name,"//"))) {
344 strcpy(l,l+1); changed = TRUE;
346 while ((l = strstr(name,"/../"))) {
347 *l = 0;
348 p = strrchr(name,'/');
349 if (p == NULL) p = name;
350 strcpy(p,l+3);
351 changed = TRUE;
353 } while (changed);
354 dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name);
358 int DOS_GetDefaultDrive(void)
360 dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+CurrentDrive);
361 return( CurrentDrive);
364 void DOS_SetDefaultDrive(int drive)
366 dprintf_dosfs(stddeb,"SetDefaultDrive to %c:\n",'A'+drive);
367 if (DOS_ValidDrive(drive))
368 CurrentDrive = drive;
371 int DOS_DisableDrive(int drive)
373 if (drive >= MAX_DOS_DRIVES)
374 return 0;
375 if (DosDrives[drive].rootdir == NULL)
376 return 0;
378 DosDrives[drive].disabled = 1;
379 return 1;
382 int DOS_EnableDrive(int drive)
384 if (drive >= MAX_DOS_DRIVES)
385 return 0;
386 if (DosDrives[drive].rootdir == NULL)
387 return 0;
389 DosDrives[drive].disabled = 0;
390 return 1;
393 static void GetUnixDirName(char *rootdir, char *name)
395 int filename = 1;
396 char *nameptr, *cwdptr;
398 cwdptr = rootdir + strlen(rootdir);
399 nameptr = name;
401 dprintf_dosfs(stddeb,"GetUnixDirName: %s <=> %s => ",rootdir, name);
403 while (*nameptr) {
404 if (*nameptr == '.' & !filename) {
405 nameptr++;
406 if (*nameptr == '\0') {
407 cwdptr--;
408 break;
410 if (*nameptr == '.') {
411 cwdptr--;
412 while (cwdptr != rootdir) {
413 cwdptr--;
414 if (*cwdptr == '/') {
415 *(cwdptr+1) = '\0';
416 goto next;
419 goto next;
421 if (*nameptr == '\\' || *nameptr == '/') {
422 next: nameptr++;
423 filename = 0;
424 continue;
427 if (*nameptr == '\\' || *nameptr == '/') {
428 filename = 0;
429 if (nameptr == name)
430 cwdptr = rootdir;
431 *cwdptr++='/';
432 nameptr++;
433 continue;
435 filename = 1;
436 *cwdptr++ = *nameptr++;
438 *cwdptr = '\0';
440 ToUnix(rootdir);
442 dprintf_dosfs(stddeb,"%s\n", rootdir);
446 char *DOS_GetUnixFileName(char *dosfilename)
448 /* a:\windows\system.ini => /dos/windows/system.ini */
450 static char temp[256];
451 static char dostemp[256];
452 int drive;
454 if (dosfilename[1] == ':')
456 drive = (islower(*dosfilename) ? toupper(*dosfilename) : *dosfilename) - 'A';
458 if (!DOS_ValidDrive(drive))
459 return NULL;
460 else
461 dosfilename+=2;
462 } else
463 drive = CurrentDrive;
465 /* Consider dosfilename const */
466 strcpy(dostemp,dosfilename);
468 /* Expand the filename to it's full path if it doesn't
469 * start from the root.
471 DOS_ExpandToFullPath(dostemp, drive);
473 strcpy(temp, DosDrives[drive].rootdir);
474 strcat(temp, DosDrives[drive].cwd);
475 GetUnixDirName(temp + strlen(DosDrives[drive].rootdir), dostemp);
477 dprintf_dosfs(stddeb,"GetUnixFileName: %s => %s\n", dosfilename, temp);
478 return(temp);
481 /* Note: This function works on directories as well as long as
482 * the directory ends in a slash.
484 char *DOS_GetDosFileName(char *unixfilename)
486 int i;
487 static char temp[256], rootdir[256];
488 /* /dos/windows/system.ini => c:\windows\system.ini */
490 /* Expand it if it's a relative name.
492 DOS_ExpandToFullUnixPath(unixfilename);
494 for (i = 0 ; i != MAX_DOS_DRIVES; i++) {
495 if (DosDrives[i].rootdir != NULL) {
496 strcpy(rootdir, DosDrives[i].rootdir);
497 strcat(rootdir, "/");
498 if (strncmp(rootdir, unixfilename, strlen(rootdir)) == 0) {
499 sprintf(temp, "%c:\\%s", 'A' + i, unixfilename + strlen(rootdir));
500 ToDos(temp);
501 return temp;
505 sprintf(temp, "Z:%s", unixfilename);
506 ToDos(temp);
507 return(temp);
510 char *DOS_GetCurrentDir(int drive)
512 static char temp[256];
514 if (!DOS_ValidDrive(drive))
515 return 0;
517 strcpy(temp, DosDrives[drive].cwd);
518 DOS_SimplifyPath( temp );
519 ToDos(temp);
520 ChopOffSlash(temp);
522 dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
523 return (temp + 1);
526 int DOS_ChangeDir(int drive, char *dirname)
528 char temp[256],old[256];
530 if (!DOS_ValidDrive(drive))
531 return 0;
533 strcpy(temp, dirname);
534 ToUnix(temp);
535 strcpy(old, DosDrives[drive].cwd);
537 GetUnixDirName(DosDrives[drive].cwd, temp);
538 strcat(DosDrives[drive].cwd,"/");
540 dprintf_dosfs(stddeb,"DOS_SetCWD: %c: %s\n",'A'+drive,
541 DosDrives[drive].cwd);
543 if (!DOS_ValidDirectory(DosDrives[drive].cwd))
545 strcpy(DosDrives[drive].cwd, old);
546 return 0;
548 DOS_SimplifyPath(DosDrives[drive].cwd);
549 return 1;
552 int DOS_MakeDir(int drive, char *dirname)
554 char temp[256];
556 if (!DOS_ValidDrive(drive))
557 return 0;
559 strcpy(temp, DosDrives[drive].cwd);
560 GetUnixDirName(temp, dirname);
561 strcat(DosDrives[drive].cwd,"/");
563 ToUnix(temp + strlen(DosDrives[drive].cwd));
564 mkdir(temp,0);
566 dprintf_dosfs(stddeb,
567 "DOS_MakeDir: %c:\%s => %s",'A'+drive, dirname, temp);
568 return 1;
571 /* DOS_ExpandToFullPath takes a dos-style filename and converts it
572 * into a full path based on the current working directory.
573 * (e.g., "foo.bar" => "d:\\moo\\foo.bar")
575 void DOS_ExpandToFullPath(char *filename, int drive)
577 char temp[256];
579 dprintf_dosfs(stddeb, "DOS_ExpandToFullPath: Original = %s\n", filename);
581 /* If the filename starts with '/' or '\',
582 * don't bother -- we're already at the root.
584 if(filename[0] == '/' || filename[0] == '\\')
585 return;
587 strcpy(temp, DosDrives[drive].cwd);
588 strcat(temp, filename);
589 strcpy(filename, temp);
591 dprintf_dosfs(stddeb, " Expanded = %s\n", temp);
594 /* DOS_ExpandToFullUnixPath takes a unix filename and converts it
595 * into a full path based on the current working directory. Thus,
596 * it's probably not a good idea to get a relative name, change the
597 * working directory, and then convert it...
599 void DOS_ExpandToFullUnixPath(char *filename)
601 char temp[256];
603 if(filename[0] == '/')
604 return;
606 getcwd(temp, 255);
607 if(!strncmp(filename, "./", 2))
608 strcat(temp, filename + 1);
609 else
611 strcat(temp, "/");
612 strcat(temp, filename);
614 dprintf_dosfs(stddeb, "DOS_ExpandToFullUnixPath: %s => %s\n", filename, temp);
615 strcpy(filename, temp);
618 int DOS_GetSerialNumber(int drive, unsigned long *serialnumber)
620 if (!DOS_ValidDrive(drive))
621 return 0;
623 *serialnumber = DosDrives[drive].serialnumber;
624 return 1;
627 int DOS_SetSerialNumber(int drive, unsigned long serialnumber)
629 if (!DOS_ValidDrive(drive))
630 return 0;
632 DosDrives[drive].serialnumber = serialnumber;
633 return 1;
636 char *DOS_GetVolumeLabel(int drive)
638 if (!DOS_ValidDrive(drive))
639 return NULL;
641 return (DosDrives[drive].label);
644 int DOS_SetVolumeLabel(int drive, char *label)
646 if (!DOS_ValidDrive(drive))
647 return 0;
649 strncpy(DosDrives[drive].label, label, 8);
650 return 1;
653 int DOS_GetFreeSpace(int drive, long *size, long *available)
655 struct statfs info;
657 if (!DOS_ValidDrive(drive))
658 return 0;
660 if (statfs(DosDrives[drive].rootdir, &info) < 0) {
661 fprintf(stderr,"dosfs: cannot do statfs(%s)\n",
662 DosDrives[drive].rootdir);
663 return 0;
666 *size = info.f_bsize * info.f_blocks;
667 *available = info.f_bavail * info.f_bsize;
669 return 1;
672 char *DOS_FindFile(char *buffer, int buflen, char *filename, char **extensions,
673 char *path)
675 char *workingpath, *dirname, *rootname, **e;
676 DIR *d;
677 struct dirent *f;
678 int rootnamelen, found = 0;
679 struct stat filestat;
681 if (strchr(filename, '\\') != NULL)
683 strncpy(buffer, DOS_GetUnixFileName(filename), buflen);
684 stat( buffer, &filestat);
685 if (S_ISREG(filestat.st_mode))
686 return buffer;
687 else
688 return NULL;
691 if (strchr(filename, '/') != NULL)
693 strncpy(buffer, filename, buflen);
694 return buffer;
697 dprintf_dosfs(stddeb,"DOS_FindFile: looking for %s\n", filename);
698 rootnamelen = strlen(filename);
699 rootname = strdup(filename);
700 ToUnix(rootname);
701 workingpath = strdup(path);
703 for(dirname = strtok(workingpath, ";");
704 dirname != NULL;
705 dirname = strtok(NULL, ";"))
707 if (strchr(dirname, '\\') != NULL)
708 d = opendir( DOS_GetUnixFileName(dirname) );
709 else
710 d = opendir( dirname );
712 dprintf_dosfs(stddeb,"in %s\n",dirname);
713 if (d != NULL)
715 while ((f = readdir(d)) != NULL)
717 if (strncasecmp(rootname, f->d_name, rootnamelen) == 0)
719 if (extensions == NULL ||
720 strcasecmp(rootname, f->d_name) == 0)
721 found = 1;
722 else
723 if (f->d_name[rootnamelen] == '.')
724 for (e = extensions; *e != NULL; e++)
725 if (strcasecmp(*e, f->d_name + rootnamelen + 1)
726 == 0)
728 found = 1;
729 break;
732 if (found)
734 if (strchr(dirname, '\\') != NULL)
735 strncpy(buffer, DOS_GetUnixFileName(dirname), buflen);
736 else
737 strncpy(buffer, dirname, buflen);
739 strncat(buffer, "/", buflen - strlen(buffer));
740 strncat(buffer, f->d_name, buflen - strlen(buffer));
742 stat(buffer, &filestat);
743 if (S_ISREG(filestat.st_mode)) {
744 closedir(d);
745 free(rootname);
746 return buffer;
747 } else
748 found = 0;
752 closedir(d);
755 return NULL;
758 /**********************************************************************
759 * WineIniFileName
761 char *WineIniFileName(void)
763 int fd;
764 static char *filename = NULL;
765 static char name[256];
767 if (filename)
768 return filename;
770 strcpy(name, WINE_INI_USER);
771 ExpandTildeString(name);
772 if ((fd = open(name, O_RDONLY)) != -1) {
773 close(fd);
774 filename = name;
775 return(filename);
777 if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) {
778 close(fd);
779 filename = WINE_INI_GLOBAL;
780 return(filename);
782 fprintf(stderr,"wine: can't open configuration file %s or %s !\n",
783 WINE_INI_GLOBAL, WINE_INI_USER);
784 exit(1);
787 char *WinIniFileName(void)
789 static char *name = NULL;
791 if (name)
792 return name;
794 name = malloc(1024);
796 strcpy(name, DOS_GetUnixFileName(WindowsDirectory));
797 strcat(name, "/");
798 strcat(name, "win.ini");
800 name = realloc(name, strlen(name) + 1);
802 return name;
805 static int match(char *filename, char *filemask)
807 char name[12], mask[12];
808 int i;
810 dprintf_dosfs(stddeb, "match: %s, %s\n", filename, filemask);
812 for( i=0; i<11; i++ ) {
813 name[i] = ' ';
814 mask[i] = ' ';
816 name[11] = 0;
817 mask[11] = 0;
819 for( i=0; i<8; i++ )
820 if( !(*filename) || *filename == '.' )
821 break;
822 else
823 name[i] = toupper( *filename++ );
824 while( *filename && *filename != '.' )
825 filename++;
826 if( *filename )
827 filename++;
828 for( i=8; i<11; i++ )
829 if( !(*filename) )
830 break;
831 else
832 name[i] = toupper( *filename++ );
834 for( i=0; i<8; i++ )
835 if( !(*filemask) || *filemask == '.' )
836 break;
837 else if( *filemask == '*' ) {
838 int j;
839 for( j=i; j<8; j++ )
840 mask[j] = '?';
841 break;
843 else
844 mask[i] = toupper( *filemask++ );
845 while( *filemask && *filemask != '.' )
846 filemask++;
847 if( *filemask )
848 filemask++;
849 for( i=8; i<11; i++ )
850 if( !(*filemask) )
851 break;
852 else if (*filemask == '*' ) {
853 int j;
854 for( j=i; j<11; j++ )
855 mask[j] = '?';
856 break;
858 else
859 mask[i] = toupper( *filemask++ );
861 dprintf_dosfs(stddeb, "changed to: %s, %s\n", name, mask);
863 for( i=0; i<11; i++ )
864 if( ( name[i] != mask[i] ) && ( mask[i] != '?' ) )
865 return 0;
867 return 1;
870 struct dosdirent *DOS_opendir(char *dosdirname)
872 int x,y;
873 char *unixdirname;
874 char temp[256];
876 if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL)
877 return NULL;
879 strcpy(temp, unixdirname);
880 y = strlen(temp);
881 while (y--)
883 if (temp[y] == '/')
885 temp[y++] = '\0';
886 unixdirname += y;
887 break;
891 for (x=0; x <= MAX_OPEN_DIRS; x++) {
892 if (x == MAX_OPEN_DIRS) {
893 fprintf( stderr, "DOS_opendir(): Too many open directories\n");
894 return NULL;
896 if (!DosDirs[x].inuse) break;
897 if (strcmp(DosDirs[x].unixpath,temp) == 0) break;
900 strcpy(DosDirs[x].filemask, unixdirname);
901 ToDos(DosDirs[x].filemask);
902 dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, temp);
904 DosDirs[x].inuse = 1;
905 strcpy(DosDirs[x].unixpath, temp);
906 DosDirs[x].entnum = 0;
908 if ((DosDirs[x].ds = opendir(temp)) == NULL)
909 return NULL;
911 return &DosDirs[x];
915 struct dosdirent *DOS_readdir(struct dosdirent *de)
917 char temp[256];
918 struct dirent *d;
919 struct stat st;
921 if (!de->inuse)
922 return NULL;
924 do {
925 if ((d = readdir(de->ds)) == NULL)
926 return NULL;
928 de->entnum++; /* Increment the directory entry number */
929 strcpy(de->filename, d->d_name);
930 if (d->d_reclen > 12)
931 de->filename[12] = '\0';
933 ToDos(de->filename);
934 } while ( !match(de->filename, de->filemask) );
936 strcpy(temp,de->unixpath);
937 strcat(temp,"/");
938 strcat(temp,de->filename);
939 ToUnix(temp + strlen(de->unixpath));
941 stat (temp, &st);
942 de->attribute = 0x0;
943 if S_ISDIR(st.st_mode)
944 de->attribute |= FA_DIREC;
946 de->filesize = st.st_size;
947 de->filetime = st.st_mtime;
949 return de;
952 void DOS_closedir(struct dosdirent *de)
954 if (de && de->inuse)
956 closedir(de->ds);
957 de->inuse = 0;