static int item(struct dir *item) { struct dir *t; /* Go back to parent dir */ if(!item) { curdir = curdir->parent; return 0; } item = item_copy(item); item_add(item); /* Ensure that any next items will go to this directory */ if(item->flags & FF_DIR) curdir = item; /* Special-case the name of the root item to be empty instead of "/". This is * what getpath() expects. */ if(item == root && strcmp(item->name, "/") == 0) item->name[0] = 0; /* Update stats of parents. Don't update the size/asize fields if this is a * possible hard link, because hlnk_check() will take care of it in that * case. */ if(item->flags & FF_HLNKC) { addparentstats(item->parent, 0, 0, 1); hlink_check(item); } else addparentstats(item->parent, item->size, item->asize, 1); /* propagate ERR and SERR back up to the root */ if(item->flags & FF_SERR || item->flags & FF_ERR) for(t=item->parent; t; t=t->parent) t->flags |= FF_SERR; dir_output.size = root->size; dir_output.items = root->items; return 0; }
void freedir(struct dir *dr) { if(!dr) return; /* free dr->sub recursively */ if(dr->sub) freedir_rec(dr->sub); /* update references */ if(dr->parent && dr->parent->sub == dr) dr->parent->sub = dr->next; if(dr->prev) dr->prev->next = dr->next; if(dr->next) dr->next->prev = dr->prev; freedir_hlnk(dr); /* update sizes of parent directories if this isn't a hard link. * If this is a hard link, freedir_hlnk() would have done so already */ addparentstats(dr->parent, dr->flags & FF_HLNKC ? 0 : -dr->size, dr->flags & FF_HLNKC ? 0 : -dr->asize, -(dr->items+1)); free(dr); }