duc_dir *duc_dir_open(struct duc *duc, const char *path) { /* Canonicalized path */ char *path_canon = duc_canonicalize_path(path); if(!path_canon) { duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } /* Find top path in database */ char *path_try = duc_strdup(path_canon); int l = strlen(path_try); struct duc_devino devino = { 0, 0 }; while(l > 0) { path_try[l] = '\0'; struct duc_index_report *report; report = db_read_report(duc, path_try); if(report) { devino = report->devino; free(report); break; } l--; } free(path_try); if(l == 0) { duc_log(duc, DUC_LOG_FTL, "Path %s not found in database", path_canon); duc->err = DUC_E_PATH_NOT_FOUND; free(path_canon); return NULL; } struct duc_dir *dir; dir = duc_dir_new(duc, &devino); if(dir == NULL) { duc->err = DUC_E_PATH_NOT_FOUND; free(path_canon); return NULL; } char rest[DUC_PATH_MAX]; strncpy(rest, path_canon+l, sizeof rest); char *name = strtok(rest, "/"); while(dir && name) { struct duc_dirent *ent = duc_dir_find_child(dir, name); struct duc_dir *dir_next = NULL; if(ent) { dir_next = duc_dir_openent(dir, ent); } duc_dir_close(dir); dir = dir_next; name = strtok(NULL, "/"); } if(dir) { dir->path = strdup(path_canon); } free(path_canon); return dir; }
duc_dir *duc_dir_open(struct duc *duc, const char *path) { /* Canonicalized path */ char *path_canon = stripdir(path); if(!path_canon) { duc->err = DUC_E_PATH_NOT_FOUND; return NULL; } /* Find top path in database */ int l = strlen(path_canon); dev_t dev = 0; ino_t ino = 0; while(l > 0) { struct duc_index_report *report; size_t report_len; report = db_get(duc->db, path_canon, l, &report_len); if(report && report_len == sizeof(*report)) { dev = report->dev; ino = report->ino; free(report); break; } l--; while(l > 1 && path_canon[l] != '/') l--; } if(l == 0) { duc_log(duc, DUC_LOG_WRN, "Path %s not found in database", path_canon); duc->err = DUC_E_PATH_NOT_FOUND; free(path_canon); return NULL; } struct duc_dir *dir; dir = db_read_dir(duc, dev, ino); if(dir == NULL) { duc->err = DUC_E_PATH_NOT_FOUND; free(path_canon); return NULL; } char rest[PATH_MAX]; strncpy(rest, path_canon+l, sizeof rest); char *name = strtok(rest, "/"); while(dir && name) { struct duc_dirent *ent = duc_dir_find_child(dir, name); struct duc_dir *dir_next = NULL; if(ent) { dir_next = duc_dir_openent(dir, ent); } duc_dir_close(dir); dir = dir_next; name = strtok(NULL, "/"); } if(dir) { dir->path = strdup(path_canon); } return dir; }