OSDN Git Service

branch: yandytex with kpathsea.
[putex/putex.git] / src / texsourc / kpathsea / kpathsea / dirent.c
1 /*
2 Public domain. No warranty. Akira Kakuto
3 */
4
5 /*
6 DIR * opendir(char *name);
7 struct dirent * readdir(DIR * dirp);
8 int closedir(DIR * dirp);
9
10  to be used on VC++ 2.0
11  ( by A. Kakuto, 1995 )
12  rewritten on Jan. 18, 1997 ( A.K. )
13
14  dirent.h should be included
15 */
16
17 #include <windows.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <malloc.h>
21 #include "kpathsea/dirent.h"
22
23 static int find(DIR *dp, char *name)
24 {
25   HANDLE h;
26   WIN32_FIND_DATA *pfd;
27
28   pfd = (WIN32_FIND_DATA *)(dp->_d_buf);
29   if((h = FindFirstFile(name,pfd)) == INVALID_HANDLE_VALUE)
30     return -1;
31   dp->_d_hdir = (unsigned)h;
32   pfd->dwReserved1 = strlen(pfd->cFileName);
33   dp->_d_magic = pfd->dwFileAttributes;
34   pfd->dwReserved0 = (dp->_d_magic & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
35   dp->_d_direntptr = (struct dirent *)&(pfd->dwReserved0);
36   dp->_d_nfiles = 0;
37   return 0;
38 }
39
40 static int findn(DIR *dp)
41 {
42   BOOL res;
43   HANDLE h;
44   WIN32_FIND_DATA *pfd;
45
46   h = (HANDLE)dp->_d_hdir;
47   pfd = (WIN32_FIND_DATA *)(dp->_d_buf);
48   if((res = FindNextFile(h,pfd)) == FALSE)
49     return -1;
50   pfd->dwReserved1 = strlen(pfd->cFileName);
51   dp->_d_magic = pfd->dwFileAttributes;
52   pfd->dwReserved0 = (dp->_d_magic & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
53   dp->_d_direntptr = (struct dirent *)&(pfd->dwReserved0);
54
55   return 0;
56 }
57
58 DIR *opendir(char *fname)
59 {
60   DIR *dirptr;
61   char nbuf[512];
62   char *name, *lastpos;
63
64   if(!(dirptr = (DIR *)malloc(sizeof(DIR))))
65     return NULL;
66   strcpy(nbuf,fname);
67   name = nbuf;
68
69   if(*name != '\0' && *(name+1) == ':')
70     name += 2;
71
72   if(*name == '\0') {
73     *name='/'; *(name+1)='\0'; goto add_ast;
74     }
75   if(*(name+1) == '\0' && (*name == '/' || *name == '\\')) {
76     *name='/'; goto add_ast;
77     }
78
79   lastpos = nbuf;
80   while(*lastpos)
81     lastpos++;
82   lastpos--;
83   if(*lastpos == '/' || *lastpos == '\\') {
84     *lastpos = '\0'; lastpos--;
85     }
86
87   if(*name == '.' && name[1] == '\0') {
88     name[1]='/'; name[2]='\0'; goto add_ast;
89     }
90   if(*name == '.' && name[1] == '.' && name[2] == '\0') {
91     name[2]='/'; name[3]='\0'; goto add_ast;
92     }
93   if(*lastpos == '.' && (*(lastpos-1) == '/' || *(lastpos-1) == '\\')) {
94     *(lastpos+1)='/'; *(lastpos+2)='\0'; goto add_ast;
95     }
96   if(*lastpos == '.' && *(lastpos-1) == '.' &&
97     (*(lastpos-2) == '/' || *(lastpos-2) == '\\')) {
98     *(lastpos+1)='/'; *(lastpos+2)='\0'; goto add_ast;
99     }
100
101   if(find(dirptr, nbuf) != 0) {
102     free(dirptr);
103     return NULL;
104   }
105   if(strpbrk(name,"*?") == NULL) {
106     if(dirptr->_d_magic & FILE_ATTRIBUTE_DIRECTORY) {
107       FindClose((HANDLE)dirptr->_d_hdir);
108       strcat(name, "/");
109     add_ast:
110       strcat(name,"*");
111       if(find(dirptr,nbuf) != 0) {
112         free(dirptr);
113         return NULL;
114       }
115     }
116   }
117   dirptr->_d_nfiles = 0;
118   return dirptr;
119 }
120
121 int closedir(DIR *dirp)
122 {
123   HANDLE h;
124   BOOL res;
125
126   h = (HANDLE)dirp->_d_hdir;
127   res = FindClose(h);
128   if( res == FALSE) {
129     free(dirp);
130     return -1;
131   }
132   free(dirp);
133   return 0;
134 }
135
136 struct dirent * readdir(DIR *dirp)
137 {
138   if(dirp == NULL)
139     return NULL;
140   if(++(dirp->_d_nfiles) == 1) {
141     return (dirp->_d_direntptr);
142   }
143   if(findn(dirp) != 0)
144     return NULL;
145   return (dirp->_d_direntptr);
146 }