boxdir * boxtree_add_folder(const char * path, const char * id, jobj * folder) { boxdir * aDir; boxfile * aFile, * part; list_iter it, pit; jobj * obj, *item; char * type; aDir = boxdir_create(); aDir->id = strdup(id); if(options.verbose) syslog(LOG_DEBUG, "Adding %s", path); obj = jobj_get(folder, "entries"); it = list_get_iter(obj->children); for(; it; it = list_iter_next(it)) { item = list_iter_getval(it); aFile = obj_to_file(item); type = jobj_getval(item, "type"); if(!strcmp(type,"folder")) list_append(aDir->folders, aFile); else { if(options.splitfiles && ends_with(aFile->name, PART_SUFFIX)) list_insert_sorted_comp(aDir->pieces, aFile, filename_compare); else list_append(aDir->files, aFile); } free(type); } if(options.splitfiles) { it = list_get_iter(aDir->files); pit = list_get_iter(aDir->pieces); for(; pit; pit = list_iter_next(pit)) { part = (boxfile*)list_iter_getval(pit); find_file_for_part(part->name, &it); if(it) { aFile = (boxfile*)list_iter_getval(it); aFile->size+=part->size; } else { syslog(LOG_WARNING, "Stale file part %s found", part->name ); it = list_get_iter(aDir->files); } } } xmlHashAddEntry(allDirs, path, aDir); return aDir; }
list_iter boxpath_first_part(boxpath * bpath) { list_iter it; boxfile * part; if(!boxpath_getfile(bpath)) return NULL; it = list_get_iter(bpath->dir->pieces); while(it && (filename_compare(bpath->file, list_iter_getval(it)) > 0)) it = list_iter_next(it); if(it) { part = (boxfile*) list_iter_getval(it); if(strncmp(bpath->base, part->name, strlen(bpath->base))) return NULL; } return it; }
void list_dump(list *l, const char * fmt) { list_iter it = list_get_iter(l); printf("list size is %d\n", list_size(l)); while(it) { printf(fmt, list_iter_getval(it)); it = list_iter_next(it); } }
/* boxtree_* functions and helpers used at mount time to fill the allDirs hash */ void find_file_for_part(const char * pname, list_iter * it) { boxfile * f; while(*it) { f = (boxfile*) list_iter_getval(*it); if(!strncmp(f->name, pname, strlen(f->name))) break; *it = list_iter_next(*it); } }
jobj * jobj_array_item(const jobj * obj, int at) { list_iter it; int i; if(obj->type != T_ARR) return NULL; if(at >= list_size(obj->children)) return NULL; it = list_get_iter(obj->children); for(i=0; i<at; ++i) it = list_iter_next(it); return (jobj*) list_iter_getval(it); }
list_iter boxpath_next_part(boxpath * bpath, list_iter it) { boxfile * part; it = list_iter_next(it); if(it) { part = (boxfile*) list_iter_getval(it); if(strncmp(bpath->file->name, part->name, strlen(bpath->file->name))) return NULL; } return it; }
void jobj_free(jobj * obj) { list_iter it; if(obj->type = T_VAL) { free(obj->value); return; } it = list_get_iter(obj->children); for(; it; it = list_iter_next(it)) { jobj_free(list_iter_getval(it)); } list_free(obj->children); free(obj); }
jobj * jobj_get(const jobj * obj, const char * key) { list_iter it; if(obj->type == T_VAL) return NULL; it = list_get_iter(obj->children); jobj * item; for(; it; it = list_iter_next(it)) { item = list_iter_getval(it); if(!strcmp(item->key, key)) return item; } return NULL; }
boxfile * obj_to_file(jobj * obj) { list_iter it; jobj * item; boxfile * f = (boxfile*) malloc(sizeof(boxfile)); memset(f, 0, sizeof(boxfile)); it = list_get_iter(obj->children); for(; it; it = list_iter_next(it)) { item = list_iter_getval(it); if(!strcmp(item->key,"id")) f->id = strdup(item->value); else if(!strcmp(item->key, "size")) f->size = atoll(item->value); else if(!strcmp(item->key, "name")) f->name = strdup(item->value); else if(!strcmp(item->key, "created_at")) f->ctime = unix_time(item->value); else if(!strcmp(item->key, "modified_at")) f->mtime = unix_time(item->value); } return f; }
int boxpath_getfile(boxpath * bpath) { list_iter it; boxfile * aFile; /* check for obvious cases */ if(!bpath) return FALSE; if(bpath->file) return TRUE; it = list_get_iter(bpath->is_dir ? bpath->dir->folders : bpath->dir->files); for(; it; it = list_iter_next(it)) { aFile = (boxfile*)list_iter_getval(it); if(!strcmp(aFile->name, bpath->base)) { bpath->file = aFile; return TRUE; } } return FALSE; }
// Move a dir to another path in the tree, // recursively updating all the child entries in allDirs void boxtree_movedir(const char * from, const char * to) { boxdir * aDir = xmlHashLookup(allDirs, from); list_iter it; char * newfrom, * newto, *name; if(!aDir) { syslog(LOG_ERR, "no such directory %s", from); return; } for (it=list_get_iter(aDir->folders); it; it = list_iter_next(it)) { name = ((boxfile*)list_iter_getval(it))->name; newfrom = pathappend(from, name); newto = pathappend(to, name); boxtree_movedir(newfrom, newto); free(newfrom); free(newto); } //LOCKDIR(aDir); xmlHashRemoveEntry(allDirs, from, NULL); xmlHashAddEntry(allDirs, to, aDir); //UNLOCKDIR(aDir); }