/*************************************************************************** * Copyright (C) 2010 by Roberto Maar * * robi@users.berlios.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, see . * ***************************************************************************/ // A special linked list for collect directory entry // Used for manage old directory blocks in journal #include #include #include "dir_list.h" // add new Dir-List item struct dir_list_t* add_list_item (struct dir_list_head_t *head , ext2_ino_t nr, char* name ,char entry){ struct dir_list_t *this; if( !nr || (! strcmp(name,""))) return head->last; this = malloc(sizeof(struct dir_list_t)); if (! this) goto errout; this->filename = malloc(strlen(name) + 1); if (! this->filename) goto errout; head->last->next = this; head->last = this; this->next = (struct dir_list_t*) head; head->count++; this->entry = entry; this->inode_nr = nr; strcpy(this->filename,name); return (this); errout: fprintf(stderr,"no free memory\n"); if (this->filename) free(this->filename); if (this) free(this); return NULL; } // destroy Dir-List int clear_dir_list(struct dir_list_head_t *head) { struct dir_list_t *next; struct dir_list_t *this; next = head->next; while (next != (struct dir_list_t*) head){ this = next; if (next->filename) free(next->filename); next = this->next; free(this); } free(head->pathname); free(head); return 0; } // create a new Dir-List struct dir_list_head_t* new_dir_list (ext2_ino_t path_inode, ext2_ino_t dir_inode, char *path, char *name){ struct dir_list_head_t *this; int len_n; this = malloc(sizeof(struct dir_list_head_t)); if (! this) return NULL; this->next = (struct dir_list_t*) this; this->last = (struct dir_list_t*) this; this->path_inode = path_inode; this->dir_inode = dir_inode; this->count = 0; len_n = strlen(path) + strlen(name) +2; this->pathname = malloc(len_n); if (this->pathname) { strcpy(this->pathname, path); if ((strlen(path) > 0) && strcmp(path,"/")) strcat(this->pathname,"/"); this->dirname = strchr(this->pathname,0); strcat(this->pathname , name); } else { if (this->pathname) free(this->pathname); free(this); return NULL; } return(this); } //local helper func ;check for duplicate values static char d_find_entry(struct dir_list_head_t* dir , ext2_ino_t ino , char *filename){ char ret = 0; struct dir_list_t *pointer = dir->next; while (pointer != (struct dir_list_t*) dir){ if (strcmp(pointer->filename,filename)) pointer = pointer->next; else { if (pointer->inode_nr == ino) return 1; pointer = pointer->next; } } return ret; } // sort out invalid values by data copy struct dir_list_head_t* clean_up_dir_list(struct dir_list_head_t* o_dir ){ struct dir_list_head_t* n_dir; int i; char *p; struct dir_list_t *pointer; n_dir = new_dir_list(o_dir->path_inode,o_dir->dir_inode," "," "); if (!n_dir) return o_dir; //change the allocatet names p = n_dir->pathname; n_dir->pathname = o_dir->pathname; o_dir->pathname = p; p = n_dir->dirname; n_dir->dirname = o_dir->dirname; o_dir->dirname = p; //copy all practicable values pointer = o_dir->next; for (i = o_dir->count ; i>0 ; i-- , pointer = pointer->next ){ if ( (!pointer->inode_nr) || (pointer->filename[0] == 0) ) continue; switch (pointer->entry){ case DIRENT_DOT_FILE: // break; case DIRENT_DOT_DOT_FILE: break; case DIRENT_OTHER_FILE: // if (d_find_entry(n_dir , pointer->inode_nr , pointer->filename)) // continue; // break; case DIRENT_DELETED_FILE: if (d_find_entry(n_dir , pointer->inode_nr , pointer->filename)|| (pointer->inode_nr < EXT2_GOOD_OLD_FIRST_INO)) continue; break; default: continue; } if(! add_list_item (n_dir, pointer->inode_nr , pointer->filename,0)) fprintf(stderr, "ERROR by copy of dirlist"); } clear_dir_list(o_dir); return n_dir; }