7 append(char **p, char *s)
15 memmove(o = *p, s, n);
21 xdirdup(Dir *d, int n)
29 p += strlen(d[i].name)+1;
30 if(d[i].uid) p += strlen(d[i].uid)+1;
31 if(d[i].gid) p += strlen(d[i].gid)+1;
32 if(d[i].muid) p += strlen(d[i].muid)+1;
34 o = malloc(n*sizeof(*d) + (int)p);
35 memmove(o, d, n*sizeof(*d));
38 o[i].name = append(&p, d[i].name);
39 o[i].uid = append(&p, d[i].uid);
40 o[i].gid = append(&p, d[i].gid);
41 o[i].muid = append(&p, d[i].muid);
46 static int xdirread0(char **path, int (*namecmp)(char *, char *), Dir **d);
49 xdirread(char **path, int (*namecmp)(char *, char *), Dir **d)
54 if((n = xdirread0(path, namecmp, &t)) > 0)
62 xdirstat0(char **path, int (*namecmp)(char *, char *), char *err)
68 if(d = dirstat(*path))
70 if(!splitpath(*path, &base, &name))
72 if((n = xdirread0(&base, namecmp, &t)) < 0)
75 if(namecmp(t[i].name, name))
77 free(*path); *path = conspath(base, t[i].name);
78 d = xdirdup(&t[i], 1);
89 xdirstat(char **path, int (*namecmp)(char *, char *))
91 return xdirstat0(path, namecmp, "name not found");
94 typedef struct XDir XDir;
113 qidcmp(Qid *q1, Qid *q2)
115 return (q1->type != q2->type) || (q1->path != q2->path) || (q1->vers != q2->vers);
118 static XDir *xdirlist;
119 static int xdircount;
122 xdirread0(char **path, int (*namecmp)(char *, char *), Dir **d)
129 for(p = nil, x = xdirlist; x; p=x, x=x->next){
130 if(namecmp(x->path, *path))
136 while(t = dirstat(x->path)){
137 if(qidcmp(&t->qid, &x->qid))
142 if(strcmp(x->path, *path)){
144 *path = strdup(x->path);
153 if((fd = open(*path, OREAD)) < 0){
155 if(t = xdirstat0(path, namecmp, "directory entry not found"))
156 fd = open(*path, OREAD);
161 if(fd < 0 || t == nil)
163 if((t->qid.type & QTDIR) == 0){
164 werrstr("not a directory");
167 if((n = dirreadall(fd, d)) < 0)
172 for(p = xdirlist, x = xdirlist->next; x->next; p = x, x = x->next)
178 x = mallocz(sizeof(*x), 1);
180 x->path = strdup(*path);
196 xdirflush(char *path, int (*namecmp)(char *, char *))
203 if(s = strrchr(path, '/'))
205 d = smprint("%.*s", n, path);
207 for(pp = &xdirlist; x = *pp; pp = xx){
209 snprint(s, n, "%s", x->path);
210 if(namecmp(d, s) == 0){