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>
7 fd04aace 2003-11-23 devnull extern int _p9dir(struct stat*, char*, Dir*, char**, char*);
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)
13 64bcfff3 2003-11-25 devnull off_t off;
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;
21 8ad51794 2004-03-25 devnull #elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
22 64bcfff3 2003-11-25 devnull static int
23 64bcfff3 2003-11-25 devnull mygetdents(int fd, struct dirent *buf, int n)
25 912fba95 2003-11-24 devnull long off;
26 669250d1 2003-12-03 devnull return getdirentries(fd, (void*)buf, n, &off);
28 64bcfff3 2003-11-25 devnull #elif defined(__sun__)
29 64bcfff3 2003-11-25 devnull static int
30 64bcfff3 2003-11-25 devnull mygetdents(int fd, struct dirent *buf, int n)
32 64bcfff3 2003-11-25 devnull return getdents(fd, (void*)buf, n);
36 d2c4ee9e 2003-11-24 devnull static int
37 fd04aace 2003-11-23 devnull countde(char *p, int n)
41 fd04aace 2003-11-23 devnull struct dirent *de;
45 fd04aace 2003-11-23 devnull while(p < e){
46 fd04aace 2003-11-23 devnull de = (struct dirent*)p;
47 fd04aace 2003-11-23 devnull if(de->d_reclen <= 4+2+2+1 || p+de->d_reclen > e)
49 1c253ceb 2003-11-23 devnull if(de->d_name[0]=='.' && de->d_name[1]==0)
50 1c253ceb 2003-11-23 devnull de->d_name[0] = 0;
51 1c253ceb 2003-11-23 devnull else if(de->d_name[0]=='.' && de->d_name[1]=='.' && de->d_name[2]==0)
52 1c253ceb 2003-11-23 devnull de->d_name[0] = 0;
54 fd04aace 2003-11-23 devnull p += de->d_reclen;
56 fd04aace 2003-11-23 devnull return m;
59 fd04aace 2003-11-23 devnull static int
60 fd04aace 2003-11-23 devnull dirpackage(int fd, char *buf, int n, Dir **dp)
62 fd04aace 2003-11-23 devnull int oldwd;
63 fd04aace 2003-11-23 devnull char *p, *str, *estr;
64 fd04aace 2003-11-23 devnull int i, nstr, m;
65 fd04aace 2003-11-23 devnull struct dirent *de;
66 fd04aace 2003-11-23 devnull struct stat st;
69 fd04aace 2003-11-23 devnull n = countde(buf, n);
70 fd04aace 2003-11-23 devnull if(n <= 0)
71 fd04aace 2003-11-23 devnull return n;
73 fd04aace 2003-11-23 devnull if((oldwd = open(".", O_RDONLY)) < 0)
74 fd04aace 2003-11-23 devnull return -1;
75 fd04aace 2003-11-23 devnull if(fchdir(fd) < 0)
76 fd04aace 2003-11-23 devnull return -1;
79 fd04aace 2003-11-23 devnull nstr = 0;
81 fd04aace 2003-11-23 devnull for(i=0; i<n; i++){
82 fd04aace 2003-11-23 devnull de = (struct dirent*)p;
83 1c8efa18 2003-12-04 devnull if(de->d_name[0] == 0)
84 1c8efa18 2003-12-04 devnull /* nothing */ {}
85 1c8efa18 2003-12-04 devnull else if(stat(de->d_name, &st) < 0)
86 1c253ceb 2003-11-23 devnull de->d_name[0] = 0;
88 fd04aace 2003-11-23 devnull nstr += _p9dir(&st, de->d_name, nil, nil, nil);
89 fd04aace 2003-11-23 devnull p += de->d_reclen;
92 fd04aace 2003-11-23 devnull d = malloc(sizeof(Dir)*n+nstr);
93 fd04aace 2003-11-23 devnull if(d == nil){
94 fd04aace 2003-11-23 devnull fchdir(oldwd);
95 fd04aace 2003-11-23 devnull close(oldwd);
96 fd04aace 2003-11-23 devnull return -1;
98 fd04aace 2003-11-23 devnull str = (char*)&d[n];
99 fd04aace 2003-11-23 devnull estr = str+nstr;
101 fd04aace 2003-11-23 devnull p = buf;
103 fd04aace 2003-11-23 devnull for(i=0; i<n; i++){
104 fd04aace 2003-11-23 devnull de = (struct dirent*)p;
105 1c253ceb 2003-11-23 devnull if(de->d_name[0] != 0 && stat(de->d_name, &st) >= 0)
106 fd04aace 2003-11-23 devnull _p9dir(&st, de->d_name, &d[m++], &str, estr);
107 fd04aace 2003-11-23 devnull p += de->d_reclen;
110 fd04aace 2003-11-23 devnull fchdir(oldwd);
111 fd04aace 2003-11-23 devnull close(oldwd);
112 fd04aace 2003-11-23 devnull *dp = d;
113 fd04aace 2003-11-23 devnull return m;
117 fd04aace 2003-11-23 devnull dirread(int fd, Dir **dp)
119 fd04aace 2003-11-23 devnull char *buf;
120 fd04aace 2003-11-23 devnull struct stat st;
123 fd04aace 2003-11-23 devnull *dp = 0;
125 fd04aace 2003-11-23 devnull if(fstat(fd, &st) < 0)
126 fd04aace 2003-11-23 devnull return -1;
128 fd04aace 2003-11-23 devnull if(st.st_blksize < 8192)
129 fd04aace 2003-11-23 devnull st.st_blksize = 8192;
131 fd04aace 2003-11-23 devnull buf = malloc(st.st_blksize);
132 fd04aace 2003-11-23 devnull if(buf == nil)
133 fd04aace 2003-11-23 devnull return -1;
135 912fba95 2003-11-24 devnull n = mygetdents(fd, (void*)buf, st.st_blksize);
136 fd04aace 2003-11-23 devnull if(n < 0){
137 fd04aace 2003-11-23 devnull free(buf);
138 fd04aace 2003-11-23 devnull return -1;
140 fd04aace 2003-11-23 devnull n = dirpackage(fd, buf, n, dp);
141 fd04aace 2003-11-23 devnull free(buf);
142 fd04aace 2003-11-23 devnull return n;
147 fd04aace 2003-11-23 devnull dirreadall(int fd, Dir **d)
149 fd04aace 2003-11-23 devnull uchar *buf, *nbuf;
150 fd04aace 2003-11-23 devnull long n, ts;
151 fd04aace 2003-11-23 devnull struct stat st;
153 fd04aace 2003-11-23 devnull if(fstat(fd, &st) < 0)
154 fd04aace 2003-11-23 devnull return -1;
156 fd04aace 2003-11-23 devnull if(st.st_blksize < 8192)
157 fd04aace 2003-11-23 devnull st.st_blksize = 8192;
159 fd04aace 2003-11-23 devnull buf = nil;
161 fd04aace 2003-11-23 devnull for(;;){
162 fd04aace 2003-11-23 devnull nbuf = realloc(buf, ts+st.st_blksize);
163 fd04aace 2003-11-23 devnull if(nbuf == nil){
164 fd04aace 2003-11-23 devnull free(buf);
165 fd04aace 2003-11-23 devnull return -1;
167 fd04aace 2003-11-23 devnull buf = nbuf;
168 912fba95 2003-11-24 devnull n = mygetdents(fd, (void*)(buf+ts), st.st_blksize);
169 fd04aace 2003-11-23 devnull if(n <= 0)
171 fd04aace 2003-11-23 devnull ts += n;
173 fd04aace 2003-11-23 devnull if(ts >= 0)
174 8ad51794 2004-03-25 devnull ts = dirpackage(fd, (char*)buf, ts, d);
175 fd04aace 2003-11-23 devnull free(buf);
176 fd04aace 2003-11-23 devnull if(ts == 0 && n < 0)
177 fd04aace 2003-11-23 devnull return -1;
178 fd04aace 2003-11-23 devnull return ts;