/* Open file */ fb_file *fb_open ( const char *path, int decompress, int compress ) { fb_file *ret = NULL; fb_dir *dir = NULL; char *tmp = strdup(path); char *pos = strrchr(tmp, '/'); if (!pos) { free(tmp); return NULL; } /* Find directory */ *pos = '\0'; dir = fb_opendir(tmp); if (!dir) { free(tmp); return NULL; } /* Open */ ret = fb_open2(dir, pos+1, decompress, compress); fb_closedir(dir); free(tmp); return ret; }
/* * Process directory * * Note: should we follow symlinks? */ static void scanfile_load_dir ( const char *path, const char *type, int lvl ) { char p[256]; fb_dir *dir; fb_dirent *de; tvhtrace("scanfile", "load dir %s", path); if (lvl >= 3) return; if (!(dir = fb_opendir(path))) return; lvl++; while ((de = fb_readdir(dir))) { if (*de->name == '.') continue; if (de->type == FB_DIR) { snprintf(p, sizeof(p), "%s/%s", path, de->name); scanfile_load_dir(p, de->name, lvl+1); } else if (type) { scanfile_load_file(type, dir, de->name); } } fb_closedir(dir); }
// TODO: this could do with being more efficient int fb_stat ( const char *path, struct filebundle_stat *st ) { int ret = 1; fb_dir *dir; fb_file *fp; if (*path == '/') { struct stat _st; if (!lstat(path, &_st)) { st->type = FB_DIRECT; st->is_dir = S_ISDIR(_st.st_mode) ? 1 : 0; st->size = _st.st_size; ret = 0; } } else if ((dir = fb_opendir(path))) { st->type = dir->type; st->is_dir = 1; st->size = 0; ret = 0; fb_closedir(dir); } else if ((fp = fb_open(path, 0, 0))) { st->type = fp->type; st->is_dir = 0; st->size = fp->size; ret = 0; fb_close(fp); } return ret; }
/* Get entry list */ int fb_scandir ( const char *path, fb_dirent ***list ) { int i, ret = -1; struct dirent **de; fb_dir *dir; if (!(dir = fb_opendir(path))) return -1; /* Direct */ if (dir->type == FB_DIRECT) { if ((ret = scandir(dir->d.root, &de, NULL, NULL)) > 0) { *list = malloc(sizeof(fb_dirent*)*ret); for (i = 0; i < ret; i++) { (*list)[i] = calloc(1, sizeof(fb_dirent)); strcpy((*list)[i]->name, de[i]->d_name); switch(de[i]->d_type) { case DT_DIR: (*list)[i]->type = FB_DIR; break; case DT_REG: (*list)[i]->type = FB_FILE; break; default: { struct stat st; char buf[512]; snprintf(buf, sizeof(buf), "%s/%s", dir->d.root, de[i]->d_name); if (!lstat(buf, &st)) (*list)[i]->type = S_ISDIR(st.st_mode) ? FB_DIR : FB_FILE; break; } } free(de[i]); } free(de); } /* Bundle */ } else { const filebundle_entry_t *fb; ret = dir->b.root->d.count; fb = dir->b.root->d.child; *list = malloc(ret * sizeof(fb_dirent*)); i = 0; while (fb) { (*list)[i] = calloc(1, sizeof(fb_dirent)); strncpy((*list)[i]->name, fb->name, sizeof((*list)[i]->name)); (*list)[i]->name[sizeof((*list)[i]->name)-1] = '\0'; fb = fb->next; i++; } } /* Close */ fb_closedir(dir); return ret; }
/* Get entry list */ int fb_scandir ( const char *path, fb_dirent ***list ) { int i, ret = -1; struct dirent **de; fb_dir *dir; if (!(dir = fb_opendir(path))) return -1; /* Direct */ if (dir->type == FB_DIRECT) { if ((ret = scandir(dir->d.root, &de, NULL, NULL)) != -1) { if (ret == 0) return 0; *list = malloc(sizeof(fb_dirent*)*ret); for (i = 0; i < ret; i++) { (*list)[i] = calloc(1, sizeof(fb_dirent)); strcpy((*list)[i]->name, de[i]->d_name); (*list)[i]->type = FB_DIRECT; free(de[i]); } free(de); } /* Bundle */ } else { const filebundle_entry_t *fb; ret = dir->b.root->d.count; fb = dir->b.root->d.child; *list = malloc(ret * sizeof(fb_dirent)); i = 0; while (fb) { (*list)[i] = calloc(1, sizeof(fb_dirent)); strcpy((*list)[i]->name, fb->name); fb = fb->next; i++; } } /* Close */ fb_closedir(dir); return ret; }