diff options
Diffstat (limited to 'src/dir_list.c')
-rw-r--r-- | src/dir_list.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/src/dir_list.c b/src/dir_list.c new file mode 100644 index 0000000..7f38b15 --- /dev/null +++ b/src/dir_list.c @@ -0,0 +1,184 @@ +/*************************************************************************** + * 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +// A special linked list for collect directory entry +// Used for manage old directory blocks in journal + +#include <stdio.h> +#include <stdlib.h> +#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 of 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)) + 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; +} + + + + + |