Blame


1 fd04aace 2003-11-23 devnull #include <u.h>
2 f7012583 2003-11-25 devnull #define NOPLAN9DEFINES
3 fd04aace 2003-11-23 devnull #include <libc.h>
4 fd04aace 2003-11-23 devnull #include <sys/stat.h>
5 fd04aace 2003-11-23 devnull #include <dirent.h>
6 fd04aace 2003-11-23 devnull
7 2acd6fa6 2005-02-08 devnull extern int _p9dir(struct stat*, struct stat*, char*, Dir*, char**, char*);
8 fd04aace 2003-11-23 devnull
9 64bcfff3 2003-11-25 devnull #if defined(__linux__)
10 fd04aace 2003-11-23 devnull static int
11 64bcfff3 2003-11-25 devnull mygetdents(int fd, struct dirent *buf, int n)
12 d2c4ee9e 2003-11-24 devnull {
13 64bcfff3 2003-11-25 devnull off_t off;
14 e95a7088 2003-12-09 devnull int nn;
15 64bcfff3 2003-11-25 devnull
16 03480d73 2004-01-09 devnull /* This doesn't match the man page, but it works in Debian with a 2.2 kernel */
17 64bcfff3 2003-11-25 devnull off = p9seek(fd, 0, 1);
18 64bcfff3 2003-11-25 devnull nn = getdirentries(fd, (void*)buf, n, &off);
19 64bcfff3 2003-11-25 devnull return nn;
20 64bcfff3 2003-11-25 devnull }
21 fa325e9b 2020-01-10 cross #elif defined(__APPLE__)
22 64bcfff3 2003-11-25 devnull static int
23 64bcfff3 2003-11-25 devnull mygetdents(int fd, struct dirent *buf, int n)
24 64bcfff3 2003-11-25 devnull {
25 caade784 2012-10-20 rsc long off;
26 caade784 2012-10-20 rsc return getdirentries(fd, (void*)buf, n, &off);
27 caade784 2012-10-20 rsc }
28 0c292663 2015-06-03 rsc #elif defined(__FreeBSD__) || defined(__DragonFly__)
29 caade784 2012-10-20 rsc static int
30 caade784 2012-10-20 rsc mygetdents(int fd, struct dirent *buf, int n)
31 caade784 2012-10-20 rsc {
32 d765c371 2012-06-27 0intro off_t off;
33 669250d1 2003-12-03 devnull return getdirentries(fd, (void*)buf, n, &off);
34 d2c4ee9e 2003-11-24 devnull }
35 0c292663 2015-06-03 rsc #elif defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__)
36 64bcfff3 2003-11-25 devnull static int
37 64bcfff3 2003-11-25 devnull mygetdents(int fd, struct dirent *buf, int n)
38 64bcfff3 2003-11-25 devnull {
39 64bcfff3 2003-11-25 devnull return getdents(fd, (void*)buf, n);
40 64bcfff3 2003-11-25 devnull }
41 e6c837d6 2009-07-15 rsc #elif defined(__AIX__)
42 e6c837d6 2009-07-15 rsc static int
43 e6c837d6 2009-07-15 rsc mygetdents(int fd, struct dirent *buf, int n)
44 e6c837d6 2009-07-15 rsc {
45 e6c837d6 2009-07-15 rsc return getdirent(fd, (void*)buf, n);
46 e6c837d6 2009-07-15 rsc }
47 669250d1 2003-12-03 devnull #endif
48 d2c4ee9e 2003-11-24 devnull
49 20035ed4 2014-02-28 minux.ma #if defined(__DragonFly__)
50 20035ed4 2014-02-28 minux.ma static inline int d_reclen(struct dirent *de) { return _DIRENT_DIRSIZ(de); }
51 20035ed4 2014-02-28 minux.ma #else
52 20035ed4 2014-02-28 minux.ma static inline int d_reclen(struct dirent *de) { return de->d_reclen; }
53 20035ed4 2014-02-28 minux.ma #endif
54 20035ed4 2014-02-28 minux.ma
55 d2c4ee9e 2003-11-24 devnull static int
56 fd04aace 2003-11-23 devnull countde(char *p, int n)
57 fd04aace 2003-11-23 devnull {
58 fd04aace 2003-11-23 devnull char *e;
59 fd04aace 2003-11-23 devnull int m;
60 fd04aace 2003-11-23 devnull struct dirent *de;
61 fd04aace 2003-11-23 devnull
62 fd04aace 2003-11-23 devnull e = p+n;
63 fd04aace 2003-11-23 devnull m = 0;
64 fd04aace 2003-11-23 devnull while(p < e){
65 fd04aace 2003-11-23 devnull de = (struct dirent*)p;
66 20035ed4 2014-02-28 minux.ma if(d_reclen(de) <= 4+2+2+1 || p+d_reclen(de) > e)
67 fd04aace 2003-11-23 devnull break;
68 1c253ceb 2003-11-23 devnull if(de->d_name[0]=='.' && de->d_name[1]==0)
69 1c253ceb 2003-11-23 devnull de->d_name[0] = 0;
70 1c253ceb 2003-11-23 devnull else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0)
71 1c253ceb 2003-11-23 devnull de->d_name[0] = 0;
72 1c8efa18 2003-12-04 devnull m++;
73 20035ed4 2014-02-28 minux.ma p += d_reclen(de);
74 fd04aace 2003-11-23 devnull }
75 fd04aace 2003-11-23 devnull return m;
76 fd04aace 2003-11-23 devnull }
77 fd04aace 2003-11-23 devnull
78 fd04aace 2003-11-23 devnull static int
79 fd04aace 2003-11-23 devnull dirpackage(int fd, char *buf, int n, Dir **dp)
80 fd04aace 2003-11-23 devnull {
81 fd04aace 2003-11-23 devnull int oldwd;
82 fd04aace 2003-11-23 devnull char *p, *str, *estr;
83 fd04aace 2003-11-23 devnull int i, nstr, m;
84 fd04aace 2003-11-23 devnull struct dirent *de;
85 2acd6fa6 2005-02-08 devnull struct stat st, lst;
86 fd04aace 2003-11-23 devnull Dir *d;
87 fd04aace 2003-11-23 devnull
88 fd04aace 2003-11-23 devnull n = countde(buf, n);
89 fd04aace 2003-11-23 devnull if(n <= 0)
90 fd04aace 2003-11-23 devnull return n;
91 fd04aace 2003-11-23 devnull
92 fd04aace 2003-11-23 devnull if((oldwd = open(".", O_RDONLY)) < 0)
93 fd04aace 2003-11-23 devnull return -1;
94 fd04aace 2003-11-23 devnull if(fchdir(fd) < 0)
95 fd04aace 2003-11-23 devnull return -1;
96 fa325e9b 2020-01-10 cross
97 fd04aace 2003-11-23 devnull p = buf;
98 fd04aace 2003-11-23 devnull nstr = 0;
99 1c8efa18 2003-12-04 devnull
100 fd04aace 2003-11-23 devnull for(i=0; i<n; i++){
101 fd04aace 2003-11-23 devnull de = (struct dirent*)p;
102 46199d11 2005-02-08 devnull memset(&lst, 0, sizeof lst);
103 1c8efa18 2003-12-04 devnull if(de->d_name[0] == 0)
104 1c8efa18 2003-12-04 devnull /* nothing */ {}
105 0a229052 2005-02-08 devnull else if(lstat(de->d_name, &lst) < 0)
106 1c253ceb 2003-11-23 devnull de->d_name[0] = 0;
107 0a229052 2005-02-08 devnull else{
108 0a229052 2005-02-08 devnull st = lst;
109 46199d11 2005-02-08 devnull if(S_ISLNK(lst.st_mode))
110 0a229052 2005-02-08 devnull stat(de->d_name, &st);
111 0a229052 2005-02-08 devnull nstr += _p9dir(&lst, &st, de->d_name, nil, nil, nil);
112 0a229052 2005-02-08 devnull }
113 20035ed4 2014-02-28 minux.ma p += d_reclen(de);
114 fd04aace 2003-11-23 devnull }
115 fd04aace 2003-11-23 devnull
116 fd04aace 2003-11-23 devnull d = malloc(sizeof(Dir)*n+nstr);
117 fd04aace 2003-11-23 devnull if(d == nil){
118 fd04aace 2003-11-23 devnull fchdir(oldwd);
119 fd04aace 2003-11-23 devnull close(oldwd);
120 fd04aace 2003-11-23 devnull return -1;
121 fd04aace 2003-11-23 devnull }
122 fd04aace 2003-11-23 devnull str = (char*)&d[n];
123 fd04aace 2003-11-23 devnull estr = str+nstr;
124 fd04aace 2003-11-23 devnull
125 fd04aace 2003-11-23 devnull p = buf;
126 fd04aace 2003-11-23 devnull m = 0;
127 fd04aace 2003-11-23 devnull for(i=0; i<n; i++){
128 fd04aace 2003-11-23 devnull de = (struct dirent*)p;
129 46199d11 2005-02-08 devnull if(de->d_name[0] != 0 && lstat(de->d_name, &lst) >= 0){
130 2acd6fa6 2005-02-08 devnull st = lst;
131 2acd6fa6 2005-02-08 devnull if((lst.st_mode&S_IFMT) == S_IFLNK)
132 2acd6fa6 2005-02-08 devnull stat(de->d_name, &st);
133 2acd6fa6 2005-02-08 devnull _p9dir(&lst, &st, de->d_name, &d[m++], &str, estr);
134 2acd6fa6 2005-02-08 devnull }
135 20035ed4 2014-02-28 minux.ma p += d_reclen(de);
136 fd04aace 2003-11-23 devnull }
137 fd04aace 2003-11-23 devnull
138 fd04aace 2003-11-23 devnull fchdir(oldwd);
139 fd04aace 2003-11-23 devnull close(oldwd);
140 fd04aace 2003-11-23 devnull *dp = d;
141 fd04aace 2003-11-23 devnull return m;
142 fd04aace 2003-11-23 devnull }
143 fd04aace 2003-11-23 devnull
144 fd04aace 2003-11-23 devnull long
145 fd04aace 2003-11-23 devnull dirread(int fd, Dir **dp)
146 fd04aace 2003-11-23 devnull {
147 fd04aace 2003-11-23 devnull char *buf;
148 fd04aace 2003-11-23 devnull struct stat st;
149 fd04aace 2003-11-23 devnull int n;
150 fd04aace 2003-11-23 devnull
151 fd04aace 2003-11-23 devnull *dp = 0;
152 fd04aace 2003-11-23 devnull
153 fd04aace 2003-11-23 devnull if(fstat(fd, &st) < 0)
154 fd04aace 2003-11-23 devnull return -1;
155 fd04aace 2003-11-23 devnull
156 fd04aace 2003-11-23 devnull if(st.st_blksize < 8192)
157 fd04aace 2003-11-23 devnull st.st_blksize = 8192;
158 fd04aace 2003-11-23 devnull
159 fd04aace 2003-11-23 devnull buf = malloc(st.st_blksize);
160 fd04aace 2003-11-23 devnull if(buf == nil)
161 fd04aace 2003-11-23 devnull return -1;
162 fd04aace 2003-11-23 devnull
163 912fba95 2003-11-24 devnull n = mygetdents(fd, (void*)buf, st.st_blksize);
164 fd04aace 2003-11-23 devnull if(n < 0){
165 fd04aace 2003-11-23 devnull free(buf);
166 fd04aace 2003-11-23 devnull return -1;
167 fd04aace 2003-11-23 devnull }
168 fd04aace 2003-11-23 devnull n = dirpackage(fd, buf, n, dp);
169 fd04aace 2003-11-23 devnull free(buf);
170 fd04aace 2003-11-23 devnull return n;
171 fd04aace 2003-11-23 devnull }
172 fd04aace 2003-11-23 devnull
173 fd04aace 2003-11-23 devnull
174 fd04aace 2003-11-23 devnull long
175 fd04aace 2003-11-23 devnull dirreadall(int fd, Dir **d)
176 fd04aace 2003-11-23 devnull {
177 fd04aace 2003-11-23 devnull uchar *buf, *nbuf;
178 fd04aace 2003-11-23 devnull long n, ts;
179 fd04aace 2003-11-23 devnull struct stat st;
180 fd04aace 2003-11-23 devnull
181 fd04aace 2003-11-23 devnull if(fstat(fd, &st) < 0)
182 fd04aace 2003-11-23 devnull return -1;
183 fd04aace 2003-11-23 devnull
184 fd04aace 2003-11-23 devnull if(st.st_blksize < 8192)
185 fd04aace 2003-11-23 devnull st.st_blksize = 8192;
186 fd04aace 2003-11-23 devnull
187 fd04aace 2003-11-23 devnull buf = nil;
188 fd04aace 2003-11-23 devnull ts = 0;
189 fd04aace 2003-11-23 devnull for(;;){
190 fd04aace 2003-11-23 devnull nbuf = realloc(buf, ts+st.st_blksize);
191 fd04aace 2003-11-23 devnull if(nbuf == nil){
192 fd04aace 2003-11-23 devnull free(buf);
193 fd04aace 2003-11-23 devnull return -1;
194 fd04aace 2003-11-23 devnull }
195 fd04aace 2003-11-23 devnull buf = nbuf;
196 912fba95 2003-11-24 devnull n = mygetdents(fd, (void*)(buf+ts), st.st_blksize);
197 fd04aace 2003-11-23 devnull if(n <= 0)
198 fd04aace 2003-11-23 devnull break;
199 fd04aace 2003-11-23 devnull ts += n;
200 fd04aace 2003-11-23 devnull }
201 fd04aace 2003-11-23 devnull if(ts >= 0)
202 8ad51794 2004-03-25 devnull ts = dirpackage(fd, (char*)buf, ts, d);
203 fd04aace 2003-11-23 devnull free(buf);
204 fd04aace 2003-11-23 devnull if(ts == 0 && n < 0)
205 fd04aace 2003-11-23 devnull return -1;
206 fd04aace 2003-11-23 devnull return ts;
207 fd04aace 2003-11-23 devnull }