summaryrefslogtreecommitdiff
path: root/src/dir_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dir_list.c')
-rw-r--r--src/dir_list.c184
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;
+}
+
+
+
+
+