/*************************************************************************** * Copyright (C) 2010 by Roberto Maar * * robi6@users.sf.net * * * * 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 . * ***************************************************************************/ //construct for global collect of hardlinks #include #include #include #include "hard_link_stack.h" static struct link_stack_head head; void init_link_stack(){ head.count = 0; head.begin = NULL; head.pointer = NULL; } void add_link_stack(ext2_ino_t inode_nr, __u32 link_count, char* name, __u32 generation){ struct link_entry* this; this = malloc (sizeof(struct link_entry)); if (!this) goto errout; this->inode_nr = inode_nr; this->link_count = link_count -1 ; this->name = malloc(strlen(name) +1); this->generation = generation; if (!this->name) goto errout; strcpy(this->name,name); this->next = head.begin; head.begin = this; head.count++; return; errout: if(this->name) free(this->name); if(this) free(this); } // subfunction for check_find_dir() use in stage 2 of magical recover int rename_hardlink_path(char *old, char *neu){ char *newname; char *endname; int size = strlen(old); head.pointer = head.begin; while (head.pointer) { if (! strcmp(old,head.pointer->name)){ newname=malloc(strlen(neu) + strlen(head.pointer->name) - size +1); if (! newname) return 1; strcpy(newname,neu); endname = head.pointer->name + size; strcat(newname,endname); free(head.pointer->name); head.pointer->name = newname; //#ifdef DEBUG fprintf(stderr,"HL-DB change %s -> %s\n",old,neu); //#endif } head.pointer = head.pointer->next; } return 0; } char* check_link_stack(ext2_ino_t inode_nr, __u32 generation){ head.pointer = head.begin; while (head.pointer) { if((head.pointer->inode_nr == inode_nr) && (head.pointer->generation == generation)) break; head.pointer = head.pointer->next; } #ifdef DEBUG if (head.pointer) printf("HARD_LINK found -> %s\n",head.pointer->name); #endif return (head.pointer) ? head.pointer->name : NULL ; } // not used ; gcc warning okay static void del_link_stack(struct link_entry* entry){ if(entry->name) free(entry->name); head.pointer = head.begin; if (head.begin->next){ while ((head.pointer->next) && (head.pointer != entry) && (head.pointer->next != entry)) head.pointer = head.pointer->next; if(head.begin == entry) head.begin = entry->next; else head.pointer->next = entry->next; } else head.begin = NULL; free(entry); head.count--; } int match_link_stack(ext2_ino_t inode_nr, __u32 generation){ int retval = 1; if ((head.pointer->inode_nr == inode_nr) && (head.pointer->generation == generation)){ // if (! --(head.pointer->link_count)) // del_link_stack(head.pointer); (head.pointer->link_count)-- ; retval = 0; } return retval; } void clear_link_stack(){ int d_count = 0 ; fflush(stdout); if (head.count){ fprintf(stderr,"Hardlink Database : %lu entries\n", (long unsigned int)head.count); head.pointer = head.begin; while (head.pointer){ if(head.pointer->link_count){ fprintf(stderr,"%10d\t%s\n",head.pointer->link_count,head.pointer->name); d_count++ ; } if(head.pointer->name) free(head.pointer->name); head.begin = head.pointer->next; free(head.pointer); head.pointer = head.begin; } if (! d_count) fprintf(stderr,"all Hardlinks be resolved\n"); } }