8 #include <lufs/proto.h>
16 lu_vtree_create(struct lufs_fattr *root_fattr){
19 TRACE("creating vtree...");
21 if(!(vt = malloc(sizeof(struct vtree))))
24 memset(vt, 0, sizeof(struct vtree));
26 INIT_LIST_HEAD(&vt->root.children);
27 memcpy(&vt->root.fattr, root_fattr, sizeof(struct lufs_fattr));
32 vt->root.stamp = time(NULL);
38 lu_vtree_delete(struct ventry *ve){
39 struct list_head *p, *tmp;
41 list_for_each_safe(p, tmp, &ve->children)
42 lu_vtree_delete(list_entry(p, struct ventry, list));
44 TRACE("deleting %s", ve->name);
57 lu_vtree_destroy(struct vtree *vt){
58 struct list_head *p, *tmp;
60 TRACE("deleting tree");
62 list_for_each_safe(p, tmp, &vt->root.children)
63 lu_vtree_delete(list_entry(p, struct ventry, list));
69 lu_vtree_search(struct ventry *ve, char *name){
73 TRACE("searching for %s in %s", name, ve->name);
76 if((sep = strchr(name, '/'))){
80 TRACE("scanning for %s in %s", name, ve->name);
82 list_for_each(p, &ve->children){
83 if(!strcmp(name, list_entry(p, struct ventry, list)->name)){
84 TRACE("portion found: %s", list_entry(p, struct ventry, list)->name);
85 ve = list_entry(p, struct ventry, list);
90 if(strcmp(name, ve->name)){
91 TRACE("portion not found");
102 TRACE("entry found");
108 lu_vtree_find(struct vtree *vt, char *entry){
110 TRACE("entry: %s", entry);
113 TRACE("entry is not an absolute path");
117 if(!strcmp(entry, "/"))
120 return lu_vtree_search(&vt->root, entry + 1);
124 lu_vtree_add(struct vtree *vt, char *dir, char *name, char *link, struct lufs_fattr *fattr, void *private){
125 struct ventry *ve, *new;
127 TRACE("add %s to %s", name, dir);
129 if(!(ve = lu_vtree_find(vt, dir)))
132 if(!(new = lu_vtree_search(ve, name))){
133 TRACE("allocating new entry");
135 if(!(new = malloc(sizeof(struct ventry))))
138 memset(new, 0, sizeof(struct ventry));
140 INIT_LIST_HEAD(&new->children);
144 list_add_tail(&new->list, &ve->children);
146 TRACE("emtry already in tree");
153 if(!(new->name = malloc(strlen(name) + 1)))
156 if(link && !(new->link = malloc(strlen(link) + 1)))
159 strcpy(new->name, name);
161 strcpy(new->link, link);
163 memcpy(&new->fattr, fattr, sizeof(struct lufs_fattr));
165 new->private = private;
166 new->stamp = time(NULL);
174 list_del(&new->list);
180 lu_vtree_lookup(struct vtree *vt, char *file, struct lufs_fattr *fattr, char *link, int buflen, void **private){
183 TRACE("looking up %s", file);
186 TRACE("we need an absolute path here...");
190 if(!strcmp(file, "/"))
193 if(!(ve = lu_vtree_search(&vt->root, file + 1)))
198 memcpy(fattr, &ve->fattr, sizeof(struct lufs_fattr));
201 if(snprintf(link, buflen, "%s", ve->link) >= buflen){
202 WARN("link too long!");
203 link[buflen - 1] = 0;
211 *private = ve->private;
217 lu_vtree_readdir(struct vtree *vt, char *dir, int offset, char *buf, int buflen){
218 struct ventry *ve, *e;
220 unsigned slen, off = 0, len = 0;
222 TRACE("reading directory %s", dir);
225 TRACE("we need an absolute path here...");
229 if(!strcmp(dir, "/"))
232 if(!(ve = lu_vtree_search(&vt->root, dir + 1)))
235 TRACE("directory found");
239 list_for_each(p, &ve->children){
241 e = list_entry(p, struct ventry, list);
242 slen = strlen(e->name);
244 if(len + slen + 2 >= buflen){
245 TRACE("buffer filled up");
249 strcat(buf, e->name);