diff options
author | Christophe Grenier <[email protected]> | 2007-10-29 22:38:52 +0100 |
---|---|---|
committer | Christophe Grenier <[email protected]> | 2007-10-29 22:38:52 +0100 |
commit | 9928d99936105b4653d2d1b8ca74dc3ffba5c71e (patch) | |
tree | 06aa4f5e9f0055027c6fb54dd47a8414cf2fba32 /src/savehdr.c |
First version in git
Diffstat (limited to 'src/savehdr.c')
-rw-r--r-- | src/savehdr.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/src/savehdr.c b/src/savehdr.c new file mode 100644 index 00000000..1a092542 --- /dev/null +++ b/src/savehdr.c @@ -0,0 +1,256 @@ +/* + + File: savehdr.c + + Copyright (C) 2004-2007 Christophe GRENIER <[email protected]> + + This software 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 the Free Software Foundation, Inc., 51 + Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_STRING_H +#include <string.h> +#endif +#ifdef HAVE_TIME_H +#include <time.h> +#endif +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +#include <stdio.h> +#include <errno.h> +#include "types.h" +#include "common.h" +#include "fnctdsk.h" /* get_LBA_part */ +#include "analyse.h" +#include "savehdr.h" +#include "log.h" +#define BACKUP_MAXSIZE 5120 + +int save_header(disk_t *disk_car,partition_t *partition, const int verbose) +{ + unsigned char *buffer; + FILE *f_backup; + int res=0; + if(verbose>1) + { + log_trace("save_header\n"); + } + f_backup=fopen("header.log","ab"); + if(!f_backup) + { + log_critical("Can't create header.log file: %s\n",strerror(errno)); + return -1; + } + buffer=MALLOC(256*DEFAULT_SECTOR_SIZE); + memset(buffer,0,DEFAULT_SECTOR_SIZE); + { + char status='D'; + switch(partition->status) + { + case STATUS_PRIM: status='P'; break; + case STATUS_PRIM_BOOT: status='*'; break; + case STATUS_EXT: status='E'; break; + case STATUS_EXT_IN_EXT: status='X'; break; + case STATUS_LOG: status='L'; break; + case STATUS_DELETED: status='D'; break; + } + snprintf((char*)buffer,256*DEFAULT_SECTOR_SIZE,"%s\n%2u %c Sys=%02X %5u %3u %2u %5u %3u %2u %10lu\n", + disk_car->description(disk_car), partition->order,status,disk_car->arch->get_part_type(partition), + offset2cylinder(disk_car,partition->part_offset), offset2head(disk_car,partition->part_offset),offset2sector(disk_car,partition->part_offset), + offset2cylinder(disk_car,partition->part_offset+partition->part_size-disk_car->sector_size), offset2head(disk_car,partition->part_offset+partition->part_size-disk_car->sector_size),offset2sector(disk_car,partition->part_offset+partition->part_size-disk_car->sector_size), + (unsigned long)(partition->part_size/disk_car->sector_size)); + } + if(fwrite(buffer,DEFAULT_SECTOR_SIZE,1,f_backup)!=1) + res=-1; + if(res>=0 && disk_car->read(disk_car,256*DEFAULT_SECTOR_SIZE, buffer, partition->part_offset)!=0) + res=-1; + if(res>=0 && fwrite(buffer,DEFAULT_SECTOR_SIZE,256,f_backup)!=256) + res=-1; + fclose(f_backup); + free(buffer); + return res; +} + +backup_disk_t *partition_load(const disk_t *disk_car, const int verbose) +{ + FILE *f_backup; + char *buffer; + char *pos=NULL; + int taille; + backup_disk_t *new_backup=NULL; + backup_disk_t *list_backup; + list_backup=(backup_disk_t*)MALLOC(sizeof(*list_backup)); + list_backup->list.prev= &list_backup->list; + list_backup->list.next = &list_backup->list; + + if(verbose>1) + { + log_trace("partition_load\n"); + } + f_backup=fopen("backup.log","r"); + if(!f_backup) + { + log_error("Can't open backup.log file: %s\n",strerror(errno)); + return list_backup; + } + buffer=MALLOC(BACKUP_MAXSIZE); + taille=fread(buffer,1,BACKUP_MAXSIZE,f_backup); + buffer[(taille<BACKUP_MAXSIZE?taille:BACKUP_MAXSIZE-1)]='\0'; + if(verbose>1) + { + log_info("partition_load backup.log size=%d\n",taille); + } + for(pos=buffer;pos<buffer+taille;pos++) + { + if(*pos=='\n') + { + *pos='\0'; + } + } + pos=buffer; + while(pos!=NULL && pos<buffer+taille) + { + if(*pos=='#') + { + pos++; + if(verbose>1) + { + log_verbose("new disk: %s\n",pos); + } + if(new_backup!=NULL) + td_list_add_tail(&new_backup->list,&list_backup->list); + new_backup=(backup_disk_t*)MALLOC(sizeof(*new_backup)); + new_backup->description[0]='\0'; + new_backup->list_part=NULL; + new_backup->my_time=strtol(pos,&pos,10); + if(pos!=NULL) + { + strncpy(new_backup->description,++pos,sizeof(new_backup->description)); + } + } + else if(new_backup!=NULL) + { + partition_t *new_partition=partition_new(disk_car->arch); + char status; + unsigned int part_type; + unsigned long part_size; + unsigned long part_offset; + if(verbose>1) + { + log_verbose("new partition\n"); + } + if(sscanf(pos,"%2u : start=%10lu, size=%10lu, Id=%02X, %c\n", + &new_partition->order, &part_offset, + &part_size,&part_type,&status)==5) + { + new_partition->part_offset=(uint64_t)part_offset*disk_car->sector_size; + new_partition->part_size=(uint64_t)part_size*disk_car->sector_size; + if(disk_car->arch->set_part_type!=NULL) + disk_car->arch->set_part_type(new_partition,part_type); + switch(status) + { + case 'P': new_partition->status=STATUS_PRIM; break; + case '*': new_partition->status=STATUS_PRIM_BOOT; break; + case 'L': new_partition->status=STATUS_LOG; break; + default: new_partition->status=STATUS_DELETED; break; + } + if(new_partition->status!=STATUS_DELETED) + { + int insert_error=0; + new_backup->list_part=insert_new_partition(new_backup->list_part, new_partition, 0, &insert_error); + if(insert_error>0) + free(new_partition); + } + else + { + free(new_partition); + } + } + else + { + log_critical("partition_load: sscanf failed\n"); + free(new_partition); + pos=NULL; + } + } + if(pos!=NULL) + { + while(*pos!='\0' && pos<buffer+taille) + pos++; + pos++; + } + } + if(new_backup!=NULL) + td_list_add_tail(&new_backup->list,&list_backup->list); + fclose(f_backup); + free(buffer); + return list_backup; +} + +int partition_save(disk_t *disk_car, list_part_t *list_part, const int verbose) +{ + list_part_t *parts; + FILE *f_backup; + if(verbose>0) + { + log_trace("partition_save\n"); + } + f_backup=fopen("backup.log","a"); + if(!f_backup) + { + log_critical("Can't create backup.log file: %s\n",strerror(errno)); + return -1; + } + fprintf(f_backup,"#%u %s\n",(unsigned int)time(NULL), disk_car->description(disk_car)); + for(parts=list_part;parts!=NULL;parts=parts->next) + { + switch(parts->part->status) + { + case STATUS_PRIM: + case STATUS_PRIM_BOOT: + case STATUS_EXT: + case STATUS_LOG: + { + char status='D'; + switch(parts->part->status) + { + case STATUS_PRIM: status='P'; break; + case STATUS_PRIM_BOOT: status='*'; break; + case STATUS_EXT: status='E'; break; + case STATUS_EXT_IN_EXT: status='X'; break; + case STATUS_LOG: status='L'; break; + case STATUS_DELETED: status='D'; break; + } + fprintf(f_backup,"%2d : start=%9lu, size=%9lu, Id=%02X, %c\n", + parts->part->order, (unsigned long)(parts->part->part_offset/disk_car->sector_size), + (unsigned long)(parts->part->part_size/disk_car->sector_size), + disk_car->arch->get_part_type(parts->part), status); + } + break; + default: + break; + } + } + fclose(f_backup); + return 0; +} + |