Пример #1
0
void read_bitmap(char* device, file_system_info fs_info, unsigned long* bitmap, int pui)
{
    off_t a = 0, b = 0;
    off_t block = 0;;
    int start = 0;
    int bit_size = 1;

    pc_init_bitmap(bitmap, 0x00, fs_info.totalblock);

    fs_open(device);
    /// init progress
    progress_bar   prog;	/// progress_bar structure defined in progress.h
    progress_init(&prog, start, fs_info.totalblock, fs_info.totalblock, BITMAP, bit_size);
    pc_init_bitmap(bitmap, 0x00, fs_info.totalblock);

    while (exfat_find_used_sectors(&ef, &a, &b) == 0) {
        printf("block %" PRId64 " %" PRId64 " \n", a, b);
        for (block = a; block <= b; block++) {
            pc_set_bit((uint64_t)block, bitmap);
            log_mesg(3, 0, 0, fs_opt.debug, "%s: used block %" PRId64 " \n", __FILE__, block);
            /// update progress
            update_pui(&prog, block, block, 0);
        }
    }

    fs_close();
    /// update progress
    update_pui(&prog, 1, 1, 1);
}
Пример #2
0
static void do_scrub(sg_t *sg, uint64_t num_blocks, uint32_t block_size)
{
	uint64_t block_offset;
	uint32_t blocks_to_read = 1024*1024/block_size;
	progress_t progress;

	find_num_blocks_to_read(sg, &blocks_to_read, block_size);

	progress_init(&progress);
	for (block_offset = 0; block_offset < num_blocks; block_offset += blocks_to_read) {
		progress_update(&progress, block_offset, num_blocks);
		if (num_blocks - block_offset < blocks_to_read)
			blocks_to_read = num_blocks - block_offset;

		switch (do_scrub_read(sg, block_offset, blocks_to_read, block_size)) {
		case READ_OK: break;
		case READ_ERROR: fprintf(stderr, "Error while reading data\n"); return;
		case READ_MEDIUM_ERR:
			fprintf(stderr, "Medium error reading at offset %llu\n", (unsigned long long)block_offset);
			break;
		}
	}

	progress_update(&progress, num_blocks, num_blocks);
	printf("\n");
}
Пример #3
0
static int start_enter(struct state *st, struct state *prev)
{
    progress_init(MODE_NORMAL);

    audio_music_fade_to(0.5f, "bgm/inter.ogg");

    return start_gui();
}
Пример #4
0
static int start_action(int tok, int val)
{
    audio_play(AUD_MENU, 1.0f);

    switch (tok)
    {
    case GUI_BACK:
        return goto_state(&st_set);

    case START_CHALLENGE:
        if (config_cheat())
        {
            progress_init(curr_mode() == MODE_CHALLENGE ?
                          MODE_NORMAL : MODE_CHALLENGE);
            gui_toggle(challenge_id);
            return 1;
        }
        else
        {
            progress_init(MODE_CHALLENGE);
            return start_action(START_LEVEL, 0);
        }
        break;

    case GUI_SCORE:
        gui_score_set(val);
        start_over(gui_active(), 0);
        return 1;

    case START_LOCK_GOALS:
        config_set_d(CONFIG_LOCK_GOALS, val);
        return goto_state(&st_start);

    case START_LEVEL:
        if (progress_play(get_level(val)))
            return goto_state(&st_level);

        break;
    }

    return 1;
}
Пример #5
0
void read_bitmap(char* device, file_system_info fs_info, unsigned long* bitmap, int pui)
{
    uint32_t offset, total, current;
    uint32_t used_block = 0, free_block = 0, err_block = 0;
    int status = 0;
    int start = 0;
    int bit_size = 1;

    fs_open(device);
    /// init progress
    progress_bar   prog;        /// progress_bar structure defined in progress.h
    progress_init(&prog, start, fs_info.totalblock, fs_info.totalblock, BITMAP, bit_size);

    offset = logical_volume_offset(fs);
    total = fs->fbb->bmh.total_items + offset;

    // containing the volume information and the LVM information
    for(current = 0; current < offset; current++){
        pc_set_bit(current, bitmap);
        used_block++;
        update_pui(&prog, current, current, 0);
    }

    // the logical volume
    for(current = offset; current < total; current++){
	status = vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(current-offset,0));
	if (status == -1) {
	    err_block++;
	    pc_clear_bit(current, bitmap);
	} else if (status == 1){
	    used_block++;
	    pc_set_bit(current, bitmap);
	} else if (status == 0){
	    free_block++;
	    pc_clear_bit(current, bitmap);
	}

	log_mesg(2, 0, 0, fs_opt.debug, "%s: Block 0x%8.8x status: %i\n", __FILE__, current, status);
	update_pui(&prog, current, current, 0);

    }
    fs_close();
    update_pui(&prog, 1, 1, 1);

    log_mesg(0, 0, 0, fs_opt.debug, "%s: Used:%"PRIu32", Free:%"PRIu32", Status err:%"PRIu32"\n", __FILE__, used_block, free_block, err_block);

}
Пример #6
0
static void write_inode_tables(ext2_filsys fs)
{
	errcode_t	retval;
	blk_t		blk;
	dgrp_t		i;
	int		num;
	struct progress_struct progress;
	int		lazy_flag = 0;

	if (quiet)
		memset(&progress, 0, sizeof(progress));
	else
		progress_init(&progress, _("Writing inode tables: "),
			      fs->group_desc_count);

	if (EXT2_HAS_COMPAT_FEATURE(fs->super, 
				    EXT2_FEATURE_COMPAT_LAZY_BG))
		lazy_flag = 1;

	for (i = 0; i < fs->group_desc_count; i++) {
		progress_update(&progress, i);
		
		blk = fs->group_desc[i].bg_inode_table;
		num = fs->inode_blocks_per_group;

		if (!(lazy_flag &&
		      (fs->group_desc[i].bg_flags & EXT2_BG_INODE_UNINIT))) {
			retval = zero_blocks(fs, blk, num, 0, &blk, &num);
			if (retval) {
				fprintf(stderr, _("\nCould not write %d "
				"blocks in inode table starting at %u: %s\n"),
					num, blk, error_message(retval));
				exit(1);
			}
		}
		if (sync_kludge) {
			if (sync_kludge == 1)
				sync();
			else if ((i % sync_kludge) == 0)
				sync();
		}
	}
	zero_blocks(0, 0, 0, 0, 0, 0);
	progress_close(&progress);
}
Пример #7
0
static void set_ecc(uint32_t start, uint32_t size)
{
    uint32_t i = start + 8;
    uint8_t ecc = 0;

    printf("About to erase and set ECC bits in region 0x%08x to 0x%08x\n", start, start + size);
    check_confirm();
    erase_range(start, size, true);

    printf("Programming ECC bits...\n");
    progress_init(size);
    while (i < start + size) {
        blocklevel_write(bl, i, &ecc, sizeof(ecc));
        i += 9;
        progress_tick(i - start);
    }
    progress_end();
}
Пример #8
0
int main(int argc, char *argv[] )
{
        progress_t bar;
        // progress_init(&bar, "", 50, PROGRESS_NUM_STYLE);
        // progress_init(&bar, "", 50, PROGRESS_CHR_STYLE);
        progress_init(&bar, "", 50, PROGRESS_BGC_STYLE);

        int i;
        for (i = 0; i <= 50; i++) {
                progress_show(&bar, i / 50.0f);
                sleep(1);
        }
        printf("\n+-Done\n");

        progress_destroy(&bar);

        return 0;
}
Пример #9
0
/// readbitmap - read bitmap
extern void readbitmap(char* device, image_head image_hdr, char* bitmap, int pui)
{
    unsigned long long     total_block, block, bused = 0, bfree = 0;
    int                    done = 0, i = 0, start = 0, bit_size = 1;
    char* p;


    fs_open(device);

    /// init progress
    progress_bar   bprog;	/// progress_bar structure defined in progress.h
    progress_init(&bprog, start, image_hdr.totalblock, bit_size);

    total_block = 0;
    /// read group
    while ((i = cgread(&disk)) != 0) {
        log_mesg(2, 0, 0, fs_opt.debug, "%s: \ncg = %d\n", __FILE__, disk.d_lcg);
        log_mesg(2, 0, 0, fs_opt.debug, "%s: blocks = %i\n", __FILE__, acg.cg_ndblk);
        p = cg_blksfree(&acg);

        for (block = 0; block < acg.cg_ndblk; block++) {
            if (isset(p, block)) {
                bitmap[total_block] = 0;
                bfree++;
                log_mesg(3, 0, 0, fs_opt.debug, "%s: bitmap is free %lli\n", __FILE__, block);
            } else {
                bitmap[total_block] = 1;
                bused++;
                log_mesg(3, 0, 0, fs_opt.debug, "%s: bitmap is used %lli\n", __FILE__, block);
            }
            total_block++;
            update_pui(&bprog, total_block ,done);
        }
        log_mesg(1, 0, 0, fs_opt.debug, "%s: read bitmap done\n", __FILE__);

    }

    fs_close();

    log_mesg(1, 0, 0, fs_opt.debug, "%s: total used = %lli, total free = %lli\n", __FILE__, bused, bfree);
    done = 1;
    update_pui(&bprog, 1, done);

}
Пример #10
0
void read_bitmap(char* device, file_system_info fs_info, unsigned long* bitmap, int pui)
{
    reiserfs_bitmap_t    *fs_bitmap;
    reiserfs_tree_t	 *tree;
    unsigned long long	 blk = 0;
    unsigned long long 	 bused = 0, bfree = 0;
    int start = 0;
    int bit_size = 1;
    int done = 0;
    
    fs_open(device);
    tree = reiserfs_fs_tree(fs);
    fs_bitmap = tree->fs->bitmap;
    
    /// init progress
    progress_bar   bprog;	/// progress_bar structure defined in progress.h
    progress_init(&bprog, start, fs->super->s_v1.sb_block_count, fs->super->s_v1.sb_block_count, BITMAP, bit_size);

    for( blk = 0; blk < (unsigned long long)fs->super->s_v1.sb_block_count; blk++ ){
	
	log_mesg(3, 0, 0, fs_opt.debug, "%s: block sb_block_count %llu\n", __FILE__, fs->super->s_v1.sb_block_count);
	log_mesg(3, 0, 0, fs_opt.debug, "%s: block bitmap check %llu\n", __FILE__, blk);
	if(reiserfs_tools_test_bit(blk, fs_bitmap->bm_map)){
	    bused++;
	    pc_set_bit(blk, bitmap);
	}else{
	    bfree++;
	    pc_clear_bit(blk, bitmap);
	}
	/// update progress
	update_pui(&bprog, blk, blk, done);

    }

    if(bfree != fs->super->s_v1.sb_free_blocks)
	log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, free:%i\n", __FILE__, bfree);

    fs_close();
    /// update progress
    update_pui(&bprog, 1, 1, 1);

}
Пример #11
0
///  readbitmap - read bitmap
extern void readbitmap(char* device, image_head image_hdr, char* bitmap, int pui)
{
    reiserfs_bitmap_t    *fs_bitmap;
    reiserfs_tree_t	 *tree;
    reiserfs_block_t	 *node;
    blk_t		 blk;
    unsigned long long 	 bused = 0, bfree = 0;
    int start = 0;
    int bit_size = 1;
    int done = 0;
    
    fs_open(device);
    tree = reiserfs_fs_tree(fs);
    fs_bitmap = tree->fs->bitmap;
    
    /// init progress
    progress_bar   bprog;	/// progress_bar structure defined in progress.h
    progress_init(&bprog, start, fs->super->s_v1.sb_block_count, bit_size);

    for(blk = 0 ; (int)blk < fs->super->s_v1.sb_block_count; blk++){
	if(reiserfs_tools_test_bit(blk, fs_bitmap->bm_map)){
	    bused++;
	    bitmap[blk] = 1;
	}else{
	    bfree++;
	    bitmap[blk] = 0;
	}
	/// update progress
	update_pui(&bprog, blk, done);

    }

    if(bfree != fs->super->s_v1.sb_free_blocks)
	log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, free:%i\n", __FILE__, bfree);

    fs_close();
    /// update progress
    done = 1;
    update_pui(&bprog, 1, done);

}
Пример #12
0
static void create_journal_dev(ext2_filsys fs)
{
	struct progress_struct progress;
	errcode_t		retval;
	char			*buf;
	blk_t			blk;
	int			count;

	retval = ext2fs_create_journal_superblock(fs,
				  fs->super->s_blocks_count, 0, &buf);
	if (retval) {
		com_err("create_journal_dev", retval,
			_("while initializing journal superblock"));
		exit(1);
	}
	if (quiet)
		memset(&progress, 0, sizeof(progress));
	else
		progress_init(&progress, _("Zeroing journal device: "),
			      fs->super->s_blocks_count);

	retval = zero_blocks(fs, 0, fs->super->s_blocks_count,
			     &progress, &blk, &count);
	if (retval) {
		com_err("create_journal_dev", retval,
			_("while zeroing journal device (block %u, count %d)"),
			blk, count);
		exit(1);
	}
	zero_blocks(0, 0, 0, 0, 0, 0);

	retval = io_channel_write_blk(fs->io,
				      fs->super->s_first_data_block+1,
				      1, buf);
	if (retval) {
		com_err("create_journal_dev", retval,
			_("while writing journal superblock"));
		exit(1);
	}
	progress_close(&progress);
}
Пример #13
0
/// readbitmap - read bitmap
extern void readbitmap(char* device, image_head image_hdr, char*bitmap, int pui)
{
    reiser4_bitmap_t       *fs_bitmap;
    unsigned long long     bit, block, bused = 0, bfree = 0;
    int start = 0;
    int bit_size = 1;

    fs_open(device);
    fs_bitmap = reiser4_bitmap_create(reiser4_format_get_len(fs->format));
    reiser4_alloc_extract(fs->alloc, fs_bitmap);

    /// init progress
    progress_bar   prog;	/// progress_bar structure defined in progress.h
    progress_init(&prog, start, image_hdr.totalblock, bit_size);


    for(bit = 0; bit < reiser4_format_get_len(fs->format); bit++){
        block = bit ;
        if(reiser4_bitmap_test(fs_bitmap, bit)){
            bused++;
            bitmap[block] = 1;
            log_mesg(3, 0, 0, fs_opt.debug, "%s: bitmap is used %lli", block, __FILE__);
        } else {
            bitmap[block] = 0;
            bfree++;
            log_mesg(3, 0, 0, fs_opt.debug, "%s: bitmap is free %lli", block, __FILE__);
        }
        /// update progress
        update_pui(&prog, bit, 0);

    }

    if(bfree != reiser4_format_get_free(fs->format))
        log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, bfree:%lli, sfree=%lli\n", __FILE__, bfree, reiser4_format_get_free(fs->format));

    fs_close();
    /// update progress
    update_pui(&prog, bit, 1);
}
Пример #14
0
void ensure_allinstfiles_available(void) {
  struct pkg_array array;
  struct pkginfo *pkg;
  struct progress progress;
  int i;

  if (allpackagesdone) return;
  if (saidread<2) {
    int max = pkg_db_count_pkg();

    saidread=1;
    progress_init(&progress, _("(Reading database ... "), max);
  }

  pkg_array_init_from_db(&array);

  pkg_files_optimize_load(&array);

  for (i = 0; i < array.n_pkgs; i++) {
    pkg = array.pkgs[i];
    ensure_packagefiles_available(pkg);

    if (saidread == 1)
      progress_step(&progress);
  }

  pkg_array_destroy(&array);

  allpackagesdone = true;

  if (saidread==1) {
    progress_done(&progress);
    printf(P_("%d file or directory currently installed.)\n",
              "%d files and directories currently installed.)\n", nfiles),
           nfiles);
    saidread=2;
  }
}
Пример #15
0
/// readbitmap - read bitmap
extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui)
{
    uint32_t current = 0, used_block = 0, free_block = 0, err_block = 0, total = 0, alloc = 0;
    int status = 0;
    int start = 0;
    int bit_size = 1;

    fs_open(device);
    /// init progress
    progress_bar   prog;        /// progress_bar structure defined in progress.h
    progress_init(&prog, start, image_hdr.totalblock, image_hdr.totalblock, BITMAP, bit_size);

    total = fs->fbb->bmh.total_items;
    alloc = vmfs_bitmap_allocated_items(fs->fbb);

    for(current = 0; current < total; current++){
	status = vmfs_block_get_status(fs, VMFS_BLK_FB_BUILD(current));
	if (status == -1) {
	    err_block++;
	    pc_clear_bit(current, bitmap);
	} else if (status == 1){
	    used_block++;
	    pc_set_bit(current, bitmap);
	} else if (status == 0){
	    free_block++;
	    pc_clear_bit(current, bitmap);
	}

	log_mesg(2, 0, 0, fs_opt.debug, "%s: Block 0x%8.8x status: %i\n", __FILE__, current, status);
	update_pui(&prog, current, current, 0);

    }
    fs_close();
    update_pui(&prog, 1, 1, 1);

    log_mesg(0, 0, 0, fs_opt.debug, "%s: Used:%lld, Free:%lld, Status err:%lld\n", __FILE__, used_block, free_block, err_block);

}
Пример #16
0
void paper_coords_test(){
  Img8u image = scene.render(0);
  Array2D<geom::ViewRay> rays = scene.getCamera(0).getAllViewRays();
  progress_init("creating paper-coords image");
  for(int y=0;y<480;y+=2){
    progress(y,479);
    for(int x=0;x<640;x+=2){
      Point32f coords = paper->getPaperCoordinates(rays(x,y));
      if(coords.x > 0){
        image(x,y,0) = 255.0 * coords.x / float(paper->getDimensions().width) ;
        image(x,y,1) = 0;
        image(x,y,2) = 255.0 * coords.y / float(paper->getDimensions().height) ;

        image(x+1,y) = image(x,y);
        image(x+1,y+1) = image(x,y);
        image(x,y+1) = image(x,y);
      }
    }
  }
  progress_finish();

  show(image);
}
Пример #17
0
Файл: main.c Проект: avz/pp
int main(int argc, char *argv[]) {
	int res;
	int src;
	int opt;
	int i;
	char *size_suf = NULL;

	int size_in_lines = -1;
	off_t size_base1000 = 0;
	off_t size_base1024 = 0;
	off_t user_defined_size = 0;
	off_t user_defined_size_lines = 0;

	struct copy_options copy_options;

	copy_options_init(&copy_options);

	copy_options.lines_mode = 0;
	copy_options.read_only = 0;
	copy_options.bar = &PROGRESS;

	while((opt = getopt(argc, argv, "rlhs:")) != -1) {
		switch(opt) {
			case 'r':
				copy_options.read_only = 1;
			break;
			case 'l':
				copy_options.lines_mode = 1;
				if(size_in_lines < 0)
					size_in_lines = 1;
			break;
			case 's':
				size_base1000 = parse_size(optarg, 1000, &size_suf);
				size_base1024 = parse_size(optarg, 1024, &size_suf);
				if(size_base1000 == -1) {
					fprintf(stderr, "Invalid argument: %s\n", optarg);
					exit(255);
				}

				if(strcasecmp(size_suf, "b") == 0) {
					size_in_lines = 0;
				} else if(strcasecmp(size_suf, "ln") == 0 || strcasecmp(size_suf, "l") == 0) {
					size_in_lines = 1;
				} else if(*size_suf != 0) {
					fprintf(stderr, "Invalid argument: %s\n", optarg);
					exit(255);
				}
			break;
			case 'h':
			case '?':
			default:
				usage();
				exit(255);
		}
	}

	if(size_base1000 || size_base1024) {
		if(size_in_lines > 0) {
			if(!copy_options.lines_mode) {
				fprintf(stderr, "Error: size in lines has no effect without -l option!\n");
				exit(255);
			}

			user_defined_size_lines = size_base1000;
		} else {
			user_defined_size = size_base1024;
		}
	}

	signal(SIGALRM, draw_progress);
	alarm(1);

	if(argc > optind) {
		for(i = optind; i < argc; i++) {
			if(argc - optind > 1)
				fprintf(stderr, "File %s:\n", argv[i]);

			while((src = open(argv[i], O_RDONLY)) < 1) {
				if(errno != EINTR) {
					perror(argv[i]);
					exit(errno);
				}
			}

			progress_init(&PROGRESS, STDERR_FILENO);
			PROGRESS.lines_mode = copy_options.lines_mode;
			PROGRESS.size = user_defined_size ? user_defined_size : filesize(src);
			PROGRESS.size_lines = user_defined_size_lines;

			DRAW_PROGRESS = 1;
			progress_draw(&PROGRESS);

			res = copy(src, STDOUT_FILENO, &copy_options);
			if(res >= 0)
				PROGRESS.force_done = 1;

			progress_draw(&PROGRESS);
			DRAW_PROGRESS = 0;

			fputs("\n", stderr);
			if(res < 0) {
				perror("copy");
				exit(errno);
			}
			close(src);
		}
	} else {
		progress_init(&PROGRESS, STDERR_FILENO);
		PROGRESS.lines_mode = copy_options.lines_mode;

		/* if used `pp < file` form */
		PROGRESS.size = user_defined_size ? user_defined_size : filesize(STDIN_FILENO);
		PROGRESS.size_lines = user_defined_size_lines;

		DRAW_PROGRESS = 1;
		progress_draw(&PROGRESS);

		res = copy(STDIN_FILENO, STDOUT_FILENO, &copy_options);
		if(res >= 0)
			PROGRESS.force_done = 1;

		progress_draw(&PROGRESS);
		DRAW_PROGRESS = 0;

		fputs("\n", stderr);
	}

	return EXIT_SUCCESS;
}
Пример #18
0
/// readbitmap - read and check bitmap
extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui)
{
    unsigned long long i = 0;
    int fat_stat = 0;
    unsigned long long block = 0, bfree = 0, bused = 0, DamagedClusters = 0;
    unsigned long long cluster_count = 0;
    unsigned long long total_sector = 0;
    unsigned long long FatReservedBytes = 0;
    int start = 0;
    int bit_size = 1;

    fs_open(device);

    total_sector = get_total_sector();
    cluster_count = get_cluster_count();

    /// init progress
    progress_bar   prog;	/// progress_bar structure defined in progress.h
    progress_init(&prog, start, cluster_count, image_hdr.totalblock, BITMAP, bit_size);

    /// init bitmap
    memset(bitmap, 0xFF, sizeof(unsigned long)*LONGS(total_sector));

    /// A) B) C)
    block = mark_reserved_sectors(bitmap, block);

    /// D) The clusters
    FatReservedBytes = fat_sb.sector_size * fat_sb.reserved;

    /// The first cluster will be seek
    lseek(ret, FatReservedBytes, SEEK_SET);

    /// The second used to check FAT status
    fat_stat = check_fat_status();
    if(fs_opt.ignore_fschk){
        log_mesg(1, 0, 0, fs_opt.debug, "%s: Ignore filesystem check\n", __FILE__);
    }else{
        if (fat_stat == 1)
            log_mesg(0, 1, 1, fs_opt.debug, "%s: Filesystem isn't in valid state. May be it is not cleanly unmounted.\n\n", __FILE__);
        else if (fat_stat == 2)
            log_mesg(0, 1, 1, fs_opt.debug, "%s: I/O error! %X\n", __FILE__);
    }

    for (i=0; i < cluster_count; i++){
        /// If FAT16
        if(FS == FAT_16){
            block = check_fat16_entry(bitmap, block, &bfree, &bused, &DamagedClusters);
        } else if (FS == FAT_32){ /// FAT32
            block = check_fat32_entry(bitmap, block, &bfree, &bused, &DamagedClusters);
        } else if (FS == FAT_12){ /// FAT12
            block = check_fat12_entry(bitmap, block, &bfree, &bused, &DamagedClusters);
        } else 
            log_mesg(2, 0, 0, fs_opt.debug, "%s: error fs\n", __FILE__);
        /// update progress
        update_pui(&prog, i, i, 0);//keep update
    }

    log_mesg(2, 0, 0, fs_opt.debug, "%s: done\n", __FILE__);
    fs_close();

    /// update progress
    update_pui(&prog, 1, 1, 1);//finish
}
Пример #19
0
void nemo_main(void){
   int i,numwritten=0,nummissed=0;
   int numimages=0;
   stream fp_in,fp,fp2;
   string *sp,logic;
   int count,n;
   int edge_dist;             /* exclude sources this many pixels from the edge */
   string inFile;             /* name of input file */
   char line[MAX_LINELEN];    /* a line of text from the inFile */
   int racol,deccol,maxcol;   /* column numbers for ra/dec in file */
   double ra,dec;             /* the values of ra/dec for a given line */
   int nentries;              /* number of valid entries, used for progress tracking */

   inFile    = getparam("in");
   edge_dist = getiparam("edge");
   logic     = getparam("logic");

   sp = burststring(getparam("col"),", \n");
   n  = xstrlen(sp,sizeof(string)) - 1;
   if (n != 2) error("You must specify ra,dec columns for col keyword!");
   racol = natoi(sp[0]) - 1;
   deccol = natoi(sp[1]) - 1;
   freestrings(sp);
   if (racol >= deccol)
      maxcol = racol;
   else
      maxcol = deccol;


   sp = burststring(getparam("fits"),", \n");
   n  = xstrlen(sp,sizeof(string))-1;
   for (i=0; i<n; i++){
      ini_mask(sp[i],i);
      numimages++;
   }
   freestrings(sp);
   
   sp = burststring(getparam("out"),", \n");
   n  = xstrlen(sp,sizeof(string))-1;
   if (n == 1){
      fp  = stropen(sp[0],"w");
      fp2 = stropen("/dev/null","w!");
   } else if (n == 2){
      fp  = stropen(sp[0],"w");
      fp2 = stropen(sp[1],"w");
   }else
      error("You must give one or two output files!\n");
   freestrings(sp);

   nentries = nemo_file_lines(inFile,0);
   progress_init("overlap percent complete:",nentries);
   nentries = 0;
   
   fp_in = stropen(inFile,"r");
   while (fgets(line,MAX_LINELEN,fp_in)){
      progress_update(nentries);
      if (line[0] != '#'){
         nentries += 1;
         sp = burststring(line," \t\n");
         n  = xstrlen(sp,sizeof(string)) - 2; /* zero based */
         if (n < maxcol)
            error("Insufficient columns on line!");
         ra  = natof(sp[racol]);
         dec = natof(sp[deccol]);
         freestrings(sp);
         count = 0;
         for (i=0; i< numimages; i++)
            count+= is_edge(ra,dec,edge_dist,i);
         if(streq(logic,"or") && (count<numimages)){
            fprintf(fp,line);
            numwritten++;
         }
         else if(streq(logic,"and") && (count==0) && (numimages > 0)){
            fprintf(fp,line);
            numwritten++;
         }
         else {
            fprintf(fp2,line);
            nummissed++;
         }
      }
   }
   strclose(fp_in);
   strclose(fp);
   strclose(fp2);
   progress_finish();

   printf("Sources outside regions: %d\n",nummissed);
   printf("Sources inside regions: %d\n",numwritten);
   printf("Number of images: %d\n",numimages);
}
Пример #20
0
extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui)
{

    xfs_agnumber_t  agno = 0;
    xfs_agblock_t   first_agbno;
    xfs_agnumber_t  num_ags;
    ag_header_t     ag_hdr;
    xfs_daddr_t     read_ag_off;
    int             read_ag_length;
    void            *read_ag_buf = NULL;
    xfs_off_t	    read_ag_position;            /* xfs_types.h: typedef __s64 */
    uint64_t	    sk, res, s_pos = 0;
    void            *btree_buf_data = NULL;
    int		    btree_buf_length;
    xfs_off_t	    btree_buf_position;
    xfs_agblock_t   bno;
    uint	    current_level;
    uint	    btree_levels;
    xfs_daddr_t     begin, next_begin, ag_begin, new_begin, ag_end;
						/* xfs_types.h: typedef __s64*/
    xfs_off_t       pos;
    xfs_alloc_ptr_t *ptr;
    xfs_alloc_rec_t *rec_ptr;
    int		    length;
    int		    i;
    uint64_t        size, sizeb;
    xfs_off_t	    w_position;
    int		    w_length;
    int		    wblocks;
    int		    w_size = 1 * 1024 * 1024;
    uint64_t        numblocks = 0;

    xfs_off_t	    logstart, logend;
    xfs_off_t	    logstart_pos, logend_pos;
    int		    log_length;

    struct xfs_btree_block *block;
    uint64_t current_block, block_count, prog_cur_block = 0;

    int start = 0;
    int bit_size = 1;
    progress_bar        prog;

    uint64_t bused = 0;
    uint64_t bfree = 0;

    /// init progress
    progress_init(&prog, start, image_hdr.totalblock, image_hdr.totalblock, BITMAP, bit_size);

    fs_open(device);

    first_agbno = (((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize) + first_residue) / source_blocksize;

    num_ags = mp->m_sb.sb_agcount;

    log_mesg(1, 0, 0, fs_opt.debug, "ags = %i\n", num_ags);
    for (agno = 0; agno < num_ags ; agno++)  {
	/* read in first blocks of the ag */

	/* initial settings */
	log_mesg(2, 0, 0, fs_opt.debug, "read ag %i header\n", agno);

	read_ag_off = XFS_AG_DADDR(mp, agno, XFS_SB_DADDR);
	read_ag_length = first_agbno * source_blocksize;
	read_ag_position = (xfs_off_t) read_ag_off * (xfs_off_t) BBSIZE;
	read_ag_buf = malloc(read_ag_length);
	if(read_ag_buf == NULL){
	    log_mesg(0, 1, 1, fs_opt.debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
	}
	memset(read_ag_buf, 0, read_ag_length);

	log_mesg(2, 0, 0, fs_opt.debug, "seek to read_ag_position %lli\n", read_ag_position);
	sk = lseek(source_fd, read_ag_position, SEEK_SET);
	current_block = (sk/source_blocksize);
	block_count = (read_ag_length/source_blocksize);
	set_bitmap(bitmap, sk, read_ag_length);
	log_mesg(2, 0, 0, fs_opt.debug, "read ag header fd = %llu(%i), length = %i(%i)\n", sk, current_block, read_ag_length, block_count);
	if ((res = read(source_fd, read_ag_buf, read_ag_length)) < 0)  {
	    log_mesg(1, 0, 1, fs_opt.debug, "read failure at offset %lld\n", read_ag_position);
	}

	ag_hdr.xfs_sb = (xfs_dsb_t *) (read_ag_buf);
	ASSERT(be32_to_cpu(ag_hdr.xfs_sb->sb_magicnum) == XFS_SB_MAGIC);
	ag_hdr.xfs_agf = (xfs_agf_t *) (read_ag_buf + source_sectorsize);
	ASSERT(be32_to_cpu(ag_hdr.xfs_agf->agf_magicnum) == XFS_AGF_MAGIC);
	ag_hdr.xfs_agi = (xfs_agi_t *) (read_ag_buf + 2 * source_sectorsize);
	ASSERT(be32_to_cpu(ag_hdr.xfs_agi->agi_magicnum) == XFS_AGI_MAGIC);
	ag_hdr.xfs_agfl = (xfs_agfl_t *) (read_ag_buf + 3 * source_sectorsize);
	log_mesg(2, 0, 0, fs_opt.debug, "ag header read ok\n");


	/* save what we need (agf) in the btree buffer */

	btree_buf_data = malloc(source_blocksize);
	if(btree_buf_data == NULL){
	    log_mesg(0, 1, 1, fs_opt.debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
	}
	memset(btree_buf_data, 0, source_blocksize);
	memmove(btree_buf_data, ag_hdr.xfs_agf, source_sectorsize);
	ag_hdr.xfs_agf = (xfs_agf_t *) btree_buf_data;
	btree_buf_length = source_blocksize;

	///* traverse btree until we get to the leftmost leaf node */

	bno = be32_to_cpu(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi]);
	current_level = 0;
	btree_levels = be32_to_cpu(ag_hdr.xfs_agf->agf_levels[XFS_BTNUM_BNOi]);

	ag_end = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(ag_hdr.xfs_agf->agf_length) - 1) + source_blocksize / BBSIZE;

	for (;;) {
	    /* none of this touches the w_buf buffer */

	    current_level++;

	    btree_buf_position = pos = (xfs_off_t)XFS_AGB_TO_DADDR(mp,agno,bno) << BBSHIFT;
	    btree_buf_length = source_blocksize;

	    sk = lseek(source_fd, btree_buf_position, SEEK_SET);
	    current_block = (sk/source_blocksize);
	    block_count = (btree_buf_length/source_blocksize);
	    set_bitmap(bitmap, sk, btree_buf_length);
	    log_mesg(2, 0, 0, fs_opt.debug, "read btree sf = %llu(%i), length = %i(%i)\n", sk, current_block, btree_buf_length, block_count);
	    read(source_fd, btree_buf_data, btree_buf_length);
	    block = (struct xfs_btree_block *)((char *)btree_buf_data + pos - btree_buf_position);

	    if (be16_to_cpu(block->bb_level) == 0)
		break;

	    ptr = XFS_ALLOC_PTR_ADDR(mp, block, 1, mp->m_alloc_mxr[1]);
	    bno = be32_to_cpu(ptr[0]);
	}
	log_mesg(2, 0, 0, fs_opt.debug, "btree read done\n");

	/* align first data copy but don't overwrite ag header */

	pos = read_ag_position >> BBSHIFT;
	length = read_ag_length >> BBSHIFT;
	next_begin = pos + length;
	ag_begin = next_begin;


	///* handle the rest of the ag */

	for (;;) {
	    if (be16_to_cpu(block->bb_level) != 0)  {
		log_mesg(0, 1, 1, fs_opt.debug, "WARNING:  source filesystem inconsistent.\nA leaf btree rec isn't a leaf. Aborting now.\n");
	    }

	    rec_ptr = XFS_ALLOC_REC_ADDR(mp, block, 1);
	    for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++, rec_ptr++)  {
		/* calculate in daddr's */

		begin = next_begin;

		/*
		 * protect against pathological case of a
		 * hole right after the ag header in a
		 * mis-aligned case
		 */

		if (begin < ag_begin)
		    begin = ag_begin;

		/*
		 * round size up to ensure we copy a
		 * range bigger than required
		 */

		log_mesg(3, 0, 0, fs_opt.debug, "XFS_AGB_TO_DADDR = %llu, agno = %i, be32_to_cpu=%llu\n", XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock)), agno, be32_to_cpu(rec_ptr->ar_startblock));
		sizeb = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock)) - begin;
		size = roundup(sizeb <<BBSHIFT, source_sectorsize);
		log_mesg(3, 0, 0, fs_opt.debug, "BB = %i size %i and sizeb %llu brgin = %llu\n", BBSHIFT, size, sizeb, begin);

		if (size > 0)  {
		    /* copy extent */

		    log_mesg(2, 0, 0, fs_opt.debug, "copy extent\n");
		    w_position = (xfs_off_t)begin << BBSHIFT;

		    while (size > 0)  {
			/*
			 * let lower layer do alignment
			 */
			if (size > w_size)  {
			    w_length = w_size;
			    size -= w_size;
			    sizeb -= wblocks;
			    numblocks += wblocks;
			} else  {
			    w_length = size;
			    numblocks += sizeb;
			    size = 0;
			}

			//read_wbuf(source_fd, &w_buf, mp);
			sk = lseek(source_fd, w_position, SEEK_SET);
			current_block = (sk/source_blocksize);
			block_count = (w_length/source_blocksize);
			set_bitmap(bitmap, sk, w_length);
			log_mesg(2, 0, 0, fs_opt.debug, "read ext sourcefd to w_buf source_fd=%llu(%i), length=%i(%i)\n", sk, current_block, w_length, block_count);
			sk = lseek(source_fd, w_length, SEEK_CUR);

			w_position += w_length;
		    }
		}

		/* round next starting point down */

		new_begin = XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(rec_ptr->ar_startblock) + be32_to_cpu(rec_ptr->ar_blockcount));
		next_begin = rounddown(new_begin, source_sectorsize >> BBSHIFT);
	    }

	    if (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK){
		log_mesg(2, 0, 0, fs_opt.debug, "NULLAGBLOCK\n");
		break;
	    }

	    /* read in next btree record block */

	    btree_buf_position = pos = (xfs_off_t)XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(block->bb_u.s.bb_rightsib)) << BBSHIFT;
	    btree_buf_length = source_blocksize;

	    /* let read_wbuf handle alignment */

	    //read_wbuf(source_fd, &btree_buf, mp);
	    sk = lseek(source_fd, btree_buf_position, SEEK_SET);
	    current_block = (sk/source_blocksize);
	    block_count = (btree_buf_length/source_blocksize);
	    set_bitmap(bitmap, sk, btree_buf_length);
	    log_mesg(2, 0, 0, fs_opt.debug, "read btreebuf fd = %llu(%i), length = %i(%i) \n", sk, current_block, btree_buf_length, block_count);
	    read(source_fd, btree_buf_data, btree_buf_length);

	    block = (struct xfs_btree_block *)((char *) btree_buf_data + pos - btree_buf_position);
	    ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC);

	}
	/*
	 * write out range of used blocks after last range
	 * of free blocks in AG
	 */
	if (next_begin < ag_end)  {
	    begin = next_begin;

	    sizeb = ag_end - begin;
	    size = roundup(sizeb << BBSHIFT, source_sectorsize);

	    if (size > 0)  {
		/* copy extent */

		w_position = (xfs_off_t) begin << BBSHIFT;

		while (size > 0)  {
		    /*
		     * let lower layer do alignment
		     */
		    if (size > w_size)  {
			w_length = w_size;
			size -= w_size;
			sizeb -= wblocks;
			numblocks += wblocks;
		    } else  {
			w_length = size;
			numblocks += sizeb;
			size = 0;
		    }

		    sk = lseek(source_fd, w_position, SEEK_SET);
		    current_block = (sk/source_blocksize);
		    block_count = (w_length/source_blocksize);
		    set_bitmap(bitmap, sk, w_length);
		    log_mesg(2, 0, 0, fs_opt.debug, "read ext fd = %llu(%i), length = %i(%i)\n", sk, current_block, w_length, block_count);
		    //read_wbuf(source_fd, &w_buf, mp);
		    lseek(source_fd, w_length, SEEK_CUR);
		    w_position += w_length;
		}
	    }
	}

	log_mesg(2, 0, 0, fs_opt.debug, "write a clean log\n");
	log_length = 1 * 1024 * 1024;
	logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart) << BBSHIFT;
	logstart_pos = rounddown(logstart, (xfs_off_t)log_length);
	if (logstart % log_length)  {  /* unaligned */
	    sk = lseek(source_fd, logstart_pos, SEEK_SET);
	    current_block = (sk/source_blocksize);
	    block_count = (log_length/source_blocksize);
	    set_bitmap(bitmap, sk, log_length);
	    log_mesg(2, 0, 0, fs_opt.debug, "read log start from %llu(%i) %i(%i)\n", sk, current_block, log_length, block_count);
	    sk = lseek(source_fd, log_length, SEEK_CUR);
	}

	logend = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart) << BBSHIFT;
	logend += XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks);
	logend_pos = rounddown(logend, (xfs_off_t)log_length);
	if (logend % log_length)  {    /* unaligned */
	    sk = lseek(source_fd, logend_pos, SEEK_SET);
	    current_block = (sk/source_blocksize);
	    block_count = (log_length/source_blocksize);
	    set_bitmap(bitmap, sk, log_length);
	    log_mesg(2, 0, 0, fs_opt.debug, "read log end  from %llu(%i) %i(%i)\n", sk, current_block, log_length, block_count);
	    sk = lseek(source_fd, log_length, SEEK_CUR);
	}

	log_mesg(2, 0, 0, fs_opt.debug, "write a clean log done\n");

	prog_cur_block = image_hdr.totalblock/num_ags*(agno+1)-1;
	update_pui(&prog, prog_cur_block, prog_cur_block, 0);
    }

    for(current_block = 0; current_block <= image_hdr.totalblock; current_block++){
	if(pc_test_bit(current_block, bitmap))
	    bused++;
	else
	    bfree++;
    }
    log_mesg(0, 0, 0, fs_opt.debug, "bused = %lli, bfree = %lli\n", bused, bfree);

    fs_close();
    update_pui(&prog, 1, 1, 1);

}
Пример #21
0
/**
 * main functiom - for colne or restore data
 */
int main(int argc, char **argv) {
#ifdef MEMTRACE
    setenv("MALLOC_TRACE", "partclone_mtrace.log", 1);
    mtrace();
#endif
    char*		source;			/// source data
    char*		target;			/// target data
    char*		buffer;			/// buffer data for malloc used
    char*		buffer2;			/// buffer data for malloc used
    int			dfr, dfw;		/// file descriptor for source and target
    int			r_size, w_size;		/// read and write size
    //unsigned long long	block_id, copied = 0;	/// block_id is every block in partition
    /// copied is copied block count
    off_t		offset = 0, sf = 0;	/// seek postition, lseek result
    int			start, stop;		/// start, range, stop number for progress bar
    unsigned long long	total_write = 0;	/// the copied size
    unsigned long long	needed_size = 0;	/// the copied size
    unsigned long long	needed_mem  = 0;	/// the copied size
    char		bitmagic[8] = "BiTmAgIc";// only for check postition
    char		bitmagic_r[8]="00000000";/// read magic string from image
    int			cmp;			/// compare magic string
    unsigned long	*bitmap;		/// the point for bitmap data
    int			debug = 0;		/// debug or not
    unsigned long	crc = 0xffffffffL;	/// CRC32 check code for writint to image
    unsigned long	crc_ck = 0xffffffffL;	/// CRC32 check code for checking
    unsigned long	crc_ck2 = 0xffffffffL;	/// CRC32 check code for checking
    int			c_size;			/// CRC32 code size
    int			n_crc_size = CRC_SIZE;
    char*		crc_buffer;		/// buffer data for malloc crc code
    //int			done = 0;
    int			s_count = 0;
    int			rescue_num = 0;
    unsigned long long			rescue_pos = 0;
    unsigned long long			main_pos = 0;
    int			tui = 0;		/// text user interface
    int			pui = 0;		/// progress mode(default text)
    int                 next=1,next_int=1,next_max_count=7,next_count=7,i;
    unsigned long long  next_block_id;
    char*               cache_buffer;
    int                 nx_current=0;
    char                bbuffer[4096];
    int flag;
    int pres;
    pthread_t prog_thread;
    void *p_result;

    char *bad_sectors_warning_msg =
        "*************************************************************************\n"
        "* WARNING: The disk has bad sector. This means physical damage on the   *\n"
        "* disk surface caused by deterioration, manufacturing faults or other   *\n"
        "* reason. The reliability of the disk may stay stable or degrade fast.  *\n"
        "* Use the --rescue option to efficiently save as much data as possible! *\n"
        "*************************************************************************\n";

    image_head		image_hdr;		/// image_head structure defined in partclone.h
    memset(&image_hdr, 0, sizeof(image_hdr));

    /**
     * get option and assign to opt structure
     * check parameter and read from argv
     */
    parse_options(argc, argv, &opt);

    /**
     * if "-d / --debug" given
     * open debug file in "/var/log/partclone.log" for log message
     */
    memset(&fs_opt, 0, sizeof(fs_cmd_opt));
    debug = opt.debug;
    fs_opt.debug = debug;
    fs_opt.ignore_fschk = opt.ignore_fschk;

    next_max_count = opt.max_block_cache-1;
    next_count = opt.max_block_cache-1;

    //if(opt.debug)
    open_log(opt.logfile);

    /**
     * using Text User Interface
     */
    if (opt.ncurses) {
        pui = NCURSES;
        log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n");
    } else
        pui = TEXT;

    tui = open_pui(pui, opt.fresh);
    if ((opt.ncurses) && (tui == 0)) {
        opt.ncurses = 0;
        log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n");
    }

    /// print partclone info
    print_partclone_info(opt);

    if (geteuid() != 0)
        log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n");
    else
        log_mesg(1, 0, 0, debug, "UID is root.\n");

    /// ignore crc check
    if(opt.ignore_crc)
        log_mesg(1, 0, 1, debug, "Ignore CRC error\n");

    /**
     * open source and target
     * clone mode, source is device and target is image file/stdout
     * restore mode, source is image file/stdin and target is device
     * dd mode, source is device and target is device !!not complete
     */
#ifdef _FILE_OFFSET_BITS
    log_mesg(1, 0, 0, debug, "enable _FILE_OFFSET_BITS %i\n", _FILE_OFFSET_BITS);
#endif
    source = opt.source;
    target = opt.target;
    dfr = open_source(source, &opt);
    if (dfr == -1) {
        log_mesg(0, 1, 1, debug, "Erro EXIT.\n");
    }

    dfw = open_target(target, &opt);
    if (dfw == -1) {
        log_mesg(0, 1, 1, debug, "Error Exit.\n");
    }

    /**
     * get partition information like super block, image_head, bitmap
     * from device or image file.
     */
    if (opt.clone) {

        log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n");
        log_mesg(0, 0, 1, debug, "Reading Super Block\n");

        /// get Super Block information from partition
        initial_image_hdr(source, &image_hdr);

        /// check memory size
        if (check_mem_size(image_hdr, opt, &needed_mem) == -1)
            log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem);

        strncpy(image_hdr.version, IMAGE_VERSION, VERSION_SIZE);

        /// alloc a memory to restore bitmap
        bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock));
        if(bitmap == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        log_mesg(2, 0, 0, debug, "initial main bitmap pointer %i\n", bitmap);
        log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

        /// read and check bitmap from partition
        log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... ");
        readbitmap(source, image_hdr, bitmap, pui);

        needed_size = (unsigned long long)(((image_hdr.block_size+sizeof(unsigned long))*image_hdr.usedblocks)+sizeof(image_hdr)+sizeof(char)*image_hdr.totalblock);
        if (opt.check)
            check_free_space(&dfw, needed_size);

        log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap);

        log_mesg(1, 0, 0, debug, "Writing super block and bitmap... ");
        // write image_head to image file
        w_size = write_all(&dfw, (char *)&image_hdr, sizeof(image_head), &opt);
        if(w_size == -1)
            log_mesg(0, 1, 1, debug, "write image_hdr to image error\n");

        // write bitmap information to image file
        for (i = 0; i < image_hdr.totalblock; i++) {
            if (pc_test_bit(i, bitmap)) {
                bbuffer[i % sizeof(bbuffer)] = 1;
            } else {
                bbuffer[i % sizeof(bbuffer)] = 0;
            }
            if (i % sizeof(bbuffer) == sizeof(bbuffer) - 1 || i == image_hdr.totalblock - 1) {
                w_size = write_all(&dfw, bbuffer, 1 + (i % sizeof(bbuffer)), &opt);
                if(w_size == -1)
                    log_mesg(0, 1, 1, debug, "write bitmap to image error\n");
            }
        }
        log_mesg(0, 0, 1, debug, "done!\n");
    } else if (opt.restore) {

        log_mesg(1, 0, 0, debug, "restore image hdr - get image_head from image file\n");
        log_mesg(1, 0, 1, debug, "Reading Super Block\n");
        /// get image information from image file
        restore_image_hdr(&dfr, &opt, &image_hdr);

        /// check memory size
        if (check_mem_size(image_hdr, opt, &needed_mem) == -1)
            log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem);

        /// alloc a memory to restore bitmap
        bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock));
        if(bitmap == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        /// check the image magic
        if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0)
            log_mesg(0, 1, 1, debug, "This is not partclone image.\n");

        /// check the file system
        //if (strcmp(image_hdr.fs, FS) != 0)
        //    log_mesg(0, 1, 1, debug, "%s can't restore from the image which filesystem is %s not %s\n", argv[0], image_hdr.fs, FS);

        log_mesg(2, 0, 0, debug, "initial main bitmap pointer %lli\n", bitmap);
        log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

        /// read and check bitmap from image file
        log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... ");
        get_image_bitmap(&dfr, opt, image_hdr, bitmap);

        /// check the dest partition size.
        if (opt.restore_row_file)
            check_free_space(&dfw, image_hdr.device_size);
        else if(opt.check)
            check_size(&dfw, image_hdr.device_size);

        log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap);
        log_mesg(0, 0, 1, debug, "done!\n");
    } else if (opt.dd) {
        log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n");
        log_mesg(1, 0, 1, debug, "Reading Super Block\n");

        /// get Super Block information from partition
        initial_image_hdr(source, &image_hdr);

        /// check memory size
        if (check_mem_size(image_hdr, opt, &needed_mem) == -1)
            log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem);

        strncpy(image_hdr.version, IMAGE_VERSION, VERSION_SIZE);

        /// alloc a memory to restore bitmap
        bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock));
        if(bitmap == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        log_mesg(2, 0, 0, debug, "initial main bitmap pointer %i\n", bitmap);
        log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

        /// read and check bitmap from partition
        log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... ");
        readbitmap(source, image_hdr, bitmap, pui);

        /// check the dest partition size.
        if(opt.check) {
            check_size(&dfw, image_hdr.device_size);
        }

        log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap);
        log_mesg(0, 0, 1, debug, "done!\n");
    } else if (opt.domain) {
        log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n");
        log_mesg(1, 0, 1, debug, "Reading Super Block\n");

        /// get Super Block information from partition
        initial_image_hdr(source, &image_hdr);

        /// check memory size
        if (check_mem_size(image_hdr, opt, &needed_mem) == -1)
            log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem);

        strncpy(image_hdr.version, IMAGE_VERSION, VERSION_SIZE);

        /// alloc a memory to restore bitmap
        bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock));
        if(bitmap == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        log_mesg(2, 0, 0, debug, "initial main bitmap pointer %i\n", bitmap);
        log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

        /// read and check bitmap from partition
        log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... ");
        readbitmap(source, image_hdr, bitmap, pui);

        log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap);
        log_mesg(0, 0, 1, debug, "done!\n");
    }

    log_mesg(1, 0, 0, debug, "print image_head\n");

    /// print option to log file
    if (debug)
        print_opt(opt);

    /// print image_head
    print_image_hdr_info(image_hdr, opt);

    /**
     * initial progress bar
     */
    //progress_bar	prog;		/// progress_bar structure defined in progress.h
    start = 0;				/// start number of progress bar
    stop = (image_hdr.usedblocks);	/// get the end of progress number, only used block
    log_mesg(1, 0, 0, debug, "Initial Progress bar\n");
    /// Initial progress bar
    if (opt.no_block_detail)
        flag = NO_BLOCK_DETAIL;
    else
        flag = IO;
    progress_init(&prog, start, stop, image_hdr.totalblock, flag, image_hdr.block_size);
    copied = 0;				/// initial number is 0

    /**
     * thread to print progress
     */
    pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL);

    /**
     * start read and write data between device and image file
     */
    if (opt.clone) {

        w_size = write_all(&dfw, bitmagic, 8, &opt); /// write a magic string

        /// read data from the first block and log the offset
        sf = lseek(dfr, 0, SEEK_SET);
        log_mesg(1, 0, 0, debug, "seek %lli for reading data string\n",sf);
        if (sf == (off_t)-1)
            log_mesg(0, 1, 1, debug, "seek set %lli\n", sf);

        buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data
        if(buffer == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        log_mesg(0, 0, 0, debug, "Total block %i\n", image_hdr.totalblock);


        /// start clone partition to image file
        log_mesg(1, 0, 0, debug, "start backup data...\n");
        for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ) {

            r_size = 0;
            w_size = 0;

            main_pos = lseek(dfr, 0, SEEK_CUR);
            log_mesg(3, 0, 0, debug, "man pos = %lli\n", main_pos);

            if (pc_test_bit(block_id, bitmap)) {
                /// if the block is used
                log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id);
                log_mesg(2, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap));

                offset = (off_t)(block_id * image_hdr.block_size);
#ifdef _FILE_OFFSET_BITS
                sf = lseek(dfr, offset, SEEK_SET);
                if (sf == -1)
                    log_mesg(0, 1, 1, debug, "source seek error = %lli, ",sf);
#endif
                /// read data from source to buffer
                memset(buffer, 0, image_hdr.block_size);
                rescue_pos = lseek(dfr, 0, SEEK_CUR);
                r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt);
                log_mesg(3, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size);
                if (r_size != (int)image_hdr.block_size) {

                    if ((r_size == -1) && (errno == EIO)) {
                        if (opt.rescue) {
                            r_size = 0;
                            for (rescue_num = 0; rescue_num < image_hdr.block_size; rescue_num += SECTOR_SIZE) {
                                rescue_sector(&dfr, rescue_pos + rescue_num, buffer + rescue_num, &opt);
                                r_size+=SECTOR_SIZE;
                            }
                        } else
                            log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg);

                    } else
                        log_mesg(0, 1, 1, debug, "read error: %s(%i) \n", strerror(errno), errno);
                }

                /// write buffer to target
                w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt);
                log_mesg(3, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size);
                if (w_size != (int)image_hdr.block_size)
                    log_mesg(0, 1, 1, debug, "write error %i \n", w_size);

                /// generate crc32 code and write it.
                crc_buffer = (char*)malloc(CRC_SIZE); ///alloc a memory to copy data
                if(crc_buffer == NULL) {
                    log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                }
                crc = crc32(crc, buffer, w_size);
                memcpy(crc_buffer, &crc, CRC_SIZE);
                c_size = write_all(&dfw, crc_buffer, CRC_SIZE, &opt);

                /// free buffer
                free(crc_buffer);

                copied++;					/// count copied block
                total_write += (unsigned long long)(w_size);	/// count copied size
                log_mesg(3, 0, 0, debug, "total=%lli, ", total_write);

                /// read or write error
                if (r_size != w_size)
                    log_mesg(0, 1, 1, debug, "read(%i) and write(%i) different\n", r_size, w_size);
                log_mesg(2, 0, 0, debug, "end\n");
            } else {
#ifndef _FILE_OFFSET_BITS
                /// if the block is not used, I just skip it.
                log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id);
                sf = lseek(dfr, image_hdr.block_size, SEEK_CUR);
                log_mesg(2, 0, 0, debug, "skip seek=%lli, ",sf);
                if (sf == (off_t)-1)
                    log_mesg(0, 1, 1, debug, "clone seek error %lli errno=%i\n", (long long)offset, (int)errno);

                log_mesg(2, 0, 0, debug, "end\n");
#endif
            }
        } /// end of for
        free(buffer);
    } else if (opt.restore) {

        /**
         * read magic string from image file
         * and check it.
         */
        r_size = read_all(&dfr, bitmagic_r, 8, &opt); /// read a magic string
        cmp = memcmp(bitmagic, bitmagic_r, 8);
        if(cmp != 0)
            log_mesg(0, 1, 1, debug, "bitmagic error %i\n", cmp);

        /// seek to the first
        sf = lseek(dfw, 0, SEEK_SET);
        log_mesg(1, 0, 0, debug, "seek %lli for writing dtat string\n",sf);
        if (sf == (off_t)-1)
            log_mesg(0, 1, 1, debug, "seek set %lli\n", sf);

        cache_buffer = (char*)malloc(image_hdr.block_size * (next_max_count+1));
        if(cache_buffer == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data
        if(buffer == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        /// start restore image file to partition
        log_mesg(1, 0, 0, debug, "start restore data...\n");

        for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ) {

            r_size = 0;
            w_size = 0;


            if (pc_test_bit(block_id, bitmap)) {
                /// The block is used
                log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id);
                log_mesg(2, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap));

                memset(buffer, 0, image_hdr.block_size);
                r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt);
                log_mesg(3, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size);
                if (r_size <0)
                    log_mesg(0, 1, 1, debug, "read errno = %i \n", errno);

                /// read crc32 code and check it.
                crc_ck = crc32(crc_ck, buffer, r_size);
                crc_buffer = (char*)malloc(CRC_SIZE); ///alloc a memory to copy data
                if(crc_buffer == NULL) {
                    log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                }
                c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt);
                if (c_size < CRC_SIZE)
                    log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno));

                memcpy(&crc, crc_buffer, CRC_SIZE);
                /*FIX: 64bit image can't ignore crc error*/
                if ((memcmp(&crc, &crc_ck, CRC_SIZE) != 0) && (!opt.ignore_crc)) {
                    log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), enlarge crc size and recheck again....\n ");
                    /// check again
                    buffer2 = (char*)malloc(image_hdr.block_size+CRC_SIZE); ///alloc a memory to copy data
                    if(buffer2 == NULL) {
                        log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                    }
                    memcpy(buffer2, buffer, image_hdr.block_size);
                    memcpy(buffer2+image_hdr.block_size, crc_buffer, CRC_SIZE);
                    memcpy(buffer, buffer2+CRC_SIZE, image_hdr.block_size);

                    crc_ck2 = crc32(crc_ck2, buffer, r_size);
                    c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt);
                    if (c_size < CRC_SIZE)
                        log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno));
                    memcpy(&crc, crc_buffer, CRC_SIZE);
                    if ((memcmp(&crc, &crc_ck2, CRC_SIZE) != 0 )&& (!opt.ignore_crc)) {
                        log_mesg(0, 1, 1, debug, "CRC error again at %i...\n ", sf);
                    } else {
                        crc_ck = crc_ck2;
                    }
                    free(buffer2);
                } else {
                    crc_ck2 = crc_ck;
                }

                if(next != next_count) {
                    memset(cache_buffer, 0, image_hdr.block_size*next_max_count);
                    for (next_int = 1; next_int <= next_max_count; next_int++)
                    {
                        next_block_id = block_id+next_int;
                        if (pc_test_bit(next_block_id, bitmap)) {
                            next++;
                        } else {
                            next_count = next;
                            break;
                        }
                        next_count = next;
                    }
                    log_mesg(1, 0, 0, debug, "next = %i\n",next);
                }

                if ((next == next_count) &&(nx_current < next)) {
                    memcpy(cache_buffer+(image_hdr.block_size*nx_current), buffer, image_hdr.block_size);
                    w_size = 0;
                    nx_current++;
                }

                if ((next == next_count) && (nx_current == next)) {
#ifdef _FILE_OFFSET_BITS
                    offset = (off_t)((block_id-next+1) * image_hdr.block_size);
                    sf = lseek(dfw, offset, SEEK_SET);
                    if (sf == -1)
                        log_mesg(0, 1, 1, debug, "target seek error = %lli, ",sf);
#endif
                    /// write block from buffer to partition
                    w_size = write_all(&dfw, cache_buffer, (image_hdr.block_size*nx_current), &opt);
                    log_mesg(1, 0, 0, debug, "bs=%i and w=%i, ",(image_hdr.block_size*nx_current), w_size);
                    if (w_size != (int)image_hdr.block_size*nx_current)
                        log_mesg(0, 1, 1, debug, "write error %i \n", w_size);
                    next = 1;
                    next_count = next_max_count;
                    nx_current=0;
                }

                /// free buffer
                free(crc_buffer);
                copied++;					/// count copied block
                total_write += (unsigned long long) w_size;	/// count copied size

                /// read or write error
                //if ((r_size != w_size) || (r_size != image_hdr.block_size))
                //	log_mesg(0, 1, 1, debug, "read and write different\n");
                log_mesg(1, 0, 0, debug, "end\n");
            } else {
                /// for restore to row file, mount -o loop used.
                if ((block_id == (image_hdr.totalblock-1)) && (opt.restore_row_file)) {
                    write_last_block(&dfw, image_hdr.block_size, block_id, &opt);

                } else {
#ifndef _FILE_OFFSET_BITS
                    /// if the block is not used, I just skip it.
                    log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id);
                    sf = lseek(dfw, image_hdr.block_size, SEEK_CUR);
                    log_mesg(2, 0, 0, debug, "seek=%lli, ",sf);
                    if (sf == (off_t)-1)
                        log_mesg(0, 1, 1, debug, "seek error %lli errno=%i\n", (long long)offset, (int)errno);
                    log_mesg(2, 0, 0, debug, "end\n");
#endif
                }
            }
        } // end of for
        free(buffer);
    } else if (opt.dd) {
        sf = lseek(dfr, 0, SEEK_SET);
        log_mesg(1, 0, 0, debug, "seek %lli for reading data string\n",sf);
        if (sf == (off_t)-1)
            log_mesg(0, 1, 1, debug, "seek set %lli\n", sf);

        main_pos = lseek(dfr, 0, SEEK_CUR);
        log_mesg(1, 0, 0, debug, "man pos = %lli\n", main_pos);

        log_mesg(0, 0, 0, debug, "Total block %i\n", image_hdr.totalblock);

        buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data
        if(buffer == NULL) {
            log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
        }

        /// start clone partition to image file
        log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n");
        for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ) {
            r_size = 0;
            w_size = 0;

            if (pc_test_bit(block_id, bitmap)) {
                /// if the block is used

                log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id);
                log_mesg(2, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap));
                offset = (off_t)(block_id * image_hdr.block_size);
#ifdef _FILE_OFFSET_BITS
                sf = lseek(dfr, offset, SEEK_SET);
                if (sf == -1)
                    log_mesg(0, 1, 1, debug, "source seek error = %lli, ",sf);
                sf = lseek(dfw, offset, SEEK_SET);
                if (sf == -1)
                    log_mesg(0, 1, 1, debug, "target seek error = %lli, ",sf);
#endif
                /// read data from source to buffer
                memset(buffer, 0, image_hdr.block_size);
                rescue_pos = lseek(dfr, 0, SEEK_CUR);
                r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt);
                log_mesg(3, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size);
                if (r_size != (int)image_hdr.block_size) {
                    if ((r_size == -1) && (errno == EIO)) {
                        if (opt.rescue) {
                            r_size = 0;
                            for (rescue_num = 0; rescue_num < image_hdr.block_size; rescue_num += SECTOR_SIZE) {
                                rescue_sector(&dfr, rescue_pos + rescue_num, buffer + rescue_num, &opt);
                                r_size+=SECTOR_SIZE;
                            }
                        } else
                            log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg);

                    } else
                        log_mesg(0, 1, 1, debug, "read error: %s(%i) \n", strerror(errno), errno);
                }

                /// write buffer to target
                w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt);
                log_mesg(3, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size);
                if (w_size != (int)image_hdr.block_size)
                    log_mesg(0, 1, 1, debug, "write error %i \n", w_size);

                copied++;                                       /// count copied block
                total_write += (unsigned long long)(w_size);    /// count copied size
                log_mesg(2, 0, 0, debug, "total=%lli, ", total_write);
                /// read or write error
                if (r_size != w_size)
                    log_mesg(0, 1, 1, debug, "read and write different\n");
                log_mesg(1, 0, 0, debug, "end\n");
            } else {
#ifndef _FILE_OFFSET_BITS
                /// if the block is not used, I just skip it.
                log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id);
                sf = lseek(dfr, image_hdr.block_size, SEEK_CUR);
                log_mesg(2, 0, 0, debug, "skip source seek=%lli, ",sf);
                sf = lseek(dfw, image_hdr.block_size, SEEK_CUR);
                log_mesg(2, 0, 0, debug, "skip target seek=%lli, ",sf);
                if (sf == (off_t)-1)
                    log_mesg(0, 1, 1, debug, "clone seek error %lli errno=%i\n", (long long)offset, (int)errno);
#endif
            }
        } /// end of for
        free(buffer);
    } else if (opt.domain) {
        log_mesg(0, 0, 0, debug, "Total block %i\n", image_hdr.totalblock);
        log_mesg(1, 0, 0, debug, "start writing domain log...\n");
        // write domain log comment and status line
        dprintf(dfw, "# Domain logfile created by %s v%s\n", EXECNAME, VERSION);
        dprintf(dfw, "# Source: %s\n", opt.source);
        dprintf(dfw, "# Offset: 0x%08llX\n", opt.offset_domain);
        dprintf(dfw, "# current_pos  current_status\n");
        dprintf(dfw, "0x%08llX     ?\n",
                opt.offset_domain + (image_hdr.totalblock * image_hdr.block_size));
        dprintf(dfw, "#      pos        size  status\n");
        // start logging the used/unused areas
        next_block_id = 0;
        cmp = pc_test_bit(0, bitmap);
        for( block_id = 0; block_id <= image_hdr.totalblock; block_id++ ) {
            if (block_id < image_hdr.totalblock) {
                nx_current = pc_test_bit(block_id, bitmap);
                if (nx_current == 1)
                    copied++;
            } else
                nx_current = -1;
            if (nx_current != cmp) {
                dprintf(dfw, "0x%08llX  0x%08llX  %c\n",
                        opt.offset_domain + (next_block_id * image_hdr.block_size),
                        (block_id - next_block_id) * image_hdr.block_size,
                        cmp ? '+' : '?');
                next_block_id = block_id;
                cmp = nx_current;
            }
            // don't bother updating progress
        } /// end of for
    }

    done = 1;
    pres = pthread_join(prog_thread, &p_result);
    update_pui(&prog, copied, block_id, done);
    sync_data(dfw, &opt);
    print_finish_info(opt);

    close (dfr);    /// close source
    close (dfw);    /// close target
    free(bitmap);   /// free bitmp
    close_pui(pui);
    printf("Cloned successfully.\n");
    if(opt.debug)
        close_log();
#ifdef MEMTRACE
    muntrace();
#endif
    return 0;	    /// finish
}
Пример #22
0
void toc_extract( WINDOW * win )
{
  static const char * ext[] = { "avr", "raw", "raw", "wav" };
  char pathname[ 256 ];
  char prog_info[ 64 ];
  char buf[ 128 ];
  struct avr_header * avrh;
  struct wave_header * wavh;
  struct audio_entry entry;
  struct audio_stream * as;
  struct _toc_data * data;
  struct device_info * info;
  OBJECT * ck;
  int format, i, max, track_no;
  int fd, swap;
  long offset, length, position, end, progress, total_length;
  long max_buf_blocks, nblocks;
  void * buffer;

  if( !fileselect( preferences.toc_dest, "", "TXT_EXTDEST" ) )
    return;
  strrchr( preferences.toc_dest, '\\' )[1] = '\0';

  data = DataSearch( win, TW_MAGIC );
  max = data->n_tracks;
  format = fmt_popup.selected;
  total_length = 0;
  buffer = alloc_comm_buffer( BUFSIZE );
  if( !buffer )
    return;
  for( i = 0; i < max; i++ )
  {
    ck = data->tree + 1 + TF_CK + i * data->n_obj;
    if( ! (ck->ob_state & SELECTED) )
      continue;
    offset = toc_address( data->f[i].beg_time );
    length = toc_address( data->f[i].end_time ) + 1 - offset;
    if( length > 0 )
      total_length += length;
  }
  max_buf_blocks = BUFSIZE / 2352;

  progress = 0;
  progress_init( get_string( "TXT_EXTMSG" ), total_length );
  progress_activate_cancel( 1 );
  progress_init_timer();

  log_begin();
  log_printf( "*** Begin of a track extraction session\n\n" );
  as = NULL;
  for( i = 0; i < max; i++ )
  {
    ck = data->tree + 1 + TF_CK + i * data->n_obj;
    if( ! (ck->ob_state & SELECTED) )
      continue;
    offset = toc_address( data->f[i].beg_time );
    length = toc_address( data->f[i].end_time ) + 1 - offset;
    if( length <= 0 )
      continue;
    track_no = i + 1;
    position = get_track_offset( &data->toc, track_no, &end );
    if( toc_popup.selected == 0 )
      gen_daoimg_entry( &entry, toc_info.toc_file, track_no,
                        offset - position, end - offset - length );
    else
    {
      info = (struct device_info*)toc_popup.item[toc_popup.selected].info;
      gen_cd_entry( &entry, info, track_no, offset - position, end - offset - length );
    }
    if( as )
      as = audio_reopen( as, &entry );
    else
      as = audio_open( &entry );
    if( as == NULL )
      continue;

    sprintf( prog_info, get_string( "TXT_EXTTRK" ), track_no );
    progress_setinfo( prog_info );

    sprintf( pathname, "%strack%02d.%s", preferences.toc_dest, track_no, ext[ format ] );
    fd = open( pathname, O_WRONLY|O_CREAT|O_TRUNC );
    if( fd == -1 )
    {
      audio_close( as );
      alert_msg( "AL_FILERR", 1, pathname );
      goto error;
    }
    switch( format )
    {
    case 0:        /* AVR */
      avrh = (struct avr_header *) buf;
      avrh->avr_id = '2BIT';
      memset( avrh->name, 0, 8 );
      avrh->num_voices = 0xFFFF;
      avrh->num_bits = 16;
      avrh->signe = 0xffff;
      avrh->loop = 0;
      avrh->midi = 0xffff;
      avrh->freq_type.frequence = 0xff00ac44L;
      avrh->length = length * (2352 / 2);
      avrh->beg_loop = 0;
      avrh->end_loop = avrh->length;
      memset( avrh->reserved, 0, 26 + 64 );
      write( fd, avrh, sizeof( *avrh ) );
      swap = as->little_endian;
      break;
    case 1:        /* RAW big-endian */
      swap = as->little_endian;
      break;
    case 2:        /* RAW little-endian */
      swap = !as->little_endian;
      break;
    case 3:        /* WAVE */
      wavh = (struct wave_header *) buf;
      wavh->riff_id = 'RIFF';
      wavh->riff_len = swap_long( length * 2352 + 36 );
      wavh->wave_id = 'WAVE';
      wavh->fmt_id = 'fmt ';
      wavh->fmt_size = 0x10000000L;
      wavh->fmt_compression_code = 0x0100;
      wavh->fmt_channels = 0x0200;
      wavh->fmt_freq = 0x44ac0000L;
      wavh->fmt_bytes_sec = 0x10b10200L;
      wavh->fmt_block_align = 0x0400;
      wavh->fmt_num_bits = 0x1000;
      wavh->data_id = 'data';
      wavh->data_size = swap_long( length * 2352 );
      write( fd, wavh, sizeof( *wavh ) );
      swap = !as->little_endian;
      break;
    }
    while( length > 0 )
    {
      if( yield() )
      {
        audio_close( as );
        alert_msg( "AL_EXTINT", 1 );
        goto error;
      }
      nblocks = MIN( length, max_buf_blocks );
      if( audio_read( as, buffer, nblocks ) == 0 )
      {
        audio_close( as );
        goto error;
      }
      if( swap )
        swap_endian( buffer, nblocks * 2352 );
      if( write( fd, buffer, nblocks * 2352 ) == -1 )
      {
        close( fd );
        audio_close( as );
        alert_msg( "AL_FWRTERR", 1, pathname );
        goto error;
      }
      length -= nblocks;
      progress += nblocks;
      progress_setcount( progress );
    }
    close( fd );
  }
  audio_close( as );
error:
  log_printf( "*** End of the track extraction session\n\n" );
  log_end();
  progress_exit();
  free_comm_buffer( buffer );

}
Пример #23
0
int main(int argc, char *argv[])
{
    SDL_Joystick *joy = NULL;
    int t1, t0;

    if (!fs_init(argv[0]))
    {
        fprintf(stderr, "Failure to initialize virtual file system (%s)\n",
                fs_error());
        return 1;
    }

    opt_parse(argc, argv);

    config_paths(opt_data);
    log_init("Neverball", "neverball.log");
    make_dirs_and_migrate();

    /* Initialize SDL. */

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) == -1)
    {
        log_printf("Failure to initialize SDL (%s)\n", SDL_GetError());
        return 1;
    }

    /* Intitialize configuration. */

    config_init();
    config_load();

    /* Initialize localization. */

    lang_init();

    /* Initialize joystick. */

    if (config_get_d(CONFIG_JOYSTICK) && SDL_NumJoysticks() > 0)
    {
        joy = SDL_JoystickOpen(config_get_d(CONFIG_JOYSTICK_DEVICE));
        if (joy)
            SDL_JoystickEventState(SDL_ENABLE);
    }

    /* Initialize audio. */

    audio_init();
    tilt_init();

    /* Initialize video. */

    if (!video_init())
        return 1;

    /* Material system. */

    mtrl_init();

    /* Screen states. */

    init_state(&st_null);

    /* Initialize demo playback or load the level. */

    if (opt_replay &&
        fs_add_path(dir_name(opt_replay)) &&
        progress_replay(base_name(opt_replay)))
    {
        demo_play_goto(1);
        goto_state(&st_demo_play);
    }
    else if (opt_level)
    {
        const char *path = fs_resolve(opt_level);
        int loaded = 0;

        if (path)
        {
            /* HACK: must be around for the duration of the game. */
            static struct level level;

            if (level_load(path, &level))
            {
                progress_init(MODE_STANDALONE);

                if (progress_play(&level))
                {
                    goto_state(&st_level);
                    loaded = 1;
                }
            }
        }
        else log_printf("File %s is not in game path\n", opt_level);

        if (!loaded)
            goto_state(&st_title);
    }
    else
        goto_state(&st_title);

    /* Run the main game loop. */

    t0 = SDL_GetTicks();

    while (loop())
    {
        if ((t1 = SDL_GetTicks()) > t0)
        {
            /* Step the game state. */

            st_timer(0.001f * (t1 - t0));

            t0 = t1;

            /* Render. */

            hmd_step();
            st_paint(0.001f * t0);
            video_swap();

            if (config_get_d(CONFIG_NICE))
                SDL_Delay(1);
        }
    }

    config_save();

    mtrl_quit();

    if (joy)
        SDL_JoystickClose(joy);

    tilt_free();
    hmd_free();
    SDL_Quit();

    return 0;
}
Пример #24
0
void match_ctx_init(match_ctx ctx,      /* IN/OUT */
                    struct membuf *inbuf,   /* IN */
                    int max_offset)
{
    struct match_node *np;
    struct progress prog[1];

    int buf_len = membuf_memlen(inbuf);
    const unsigned char *buf = membuf_get(inbuf);

    int c, i;
    int val;

    ctx->info = calloc(buf_len + 1, sizeof(*ctx->info));
    ctx->rle = calloc(buf_len + 1, sizeof(*ctx->rle));
    ctx->rle_r = calloc(buf_len + 1, sizeof(*ctx->rle_r));

    chunkpool_init(ctx->m_pool, sizeof(match));

    ctx->max_offset = max_offset;

    ctx->buf = buf;
    ctx->len = buf_len;

    val = buf[0];
    for (i = 1; i < buf_len; ++i)
    {
        if (buf[i] == val)
        {
            int len = ctx->rle[i - 1] + 1;
            if(len > 65535)
            {
                len = 0;
            }
            ctx->rle[i] = len;
        } else
        {
            ctx->rle[i] = 0;
        }
        val = buf[i];
    }

    for (i = buf_len - 2; i >= 0; --i)
    {
        if (ctx->rle[i] < ctx->rle[i + 1])
        {
            ctx->rle_r[i] = ctx->rle_r[i + 1] + 1;
        } else
        {
            ctx->rle_r[i] = 0;
        }
    }

    /* add extra nodes to rle sequences */
    for(c = 0; c < 256; ++c)
    {
        static char rle_map[65536];
        struct match_node *prev_np;
        unsigned short int rle_len;

        /* for each possible rle char */
        memset(rle_map, 0, sizeof(rle_map));
        prev_np = NULL;
        for (i = 0; i < buf_len; ++i)
        {
            /* must be the correct char */
            if(buf[i] != c)
            {
                continue;
            }

            rle_len = ctx->rle[i];
            if(!rle_map[rle_len] && ctx->rle_r[i] > 16)
            {
                /* no previous lengths and not our primary length*/
                continue;
            }

            np = chunkpool_malloc(ctx->m_pool);
            np->index = i;
            np->next = NULL;
            rle_map[rle_len] = 1;

            LOG(LOG_DUMP, ("0) c = %d, added np idx %d -> %d\n", c, i, 0));

            /* if we have a previous entry, let's chain it together */
            if(prev_np != NULL)
            {
                LOG(LOG_DUMP, ("1) c = %d, pointed np idx %d -> %d\n",
                                c, prev_np->index, i));
                prev_np->next = np;
            }

            ctx->info[i]->single = np;
            prev_np = np;
        }

        memset(rle_map, 0, sizeof(rle_map));
        prev_np = NULL;
        for (i = buf_len - 1; i >= 0; --i)
        {
            /* must be the correct char */
            if(buf[i] != c)
            {
                continue;
            }

            rle_len = ctx->rle_r[i];
            np = ctx->info[i]->single;
            if(np == NULL)
            {
                if(rle_map[rle_len] && prev_np != NULL && rle_len > 0)
                {
                    np = chunkpool_malloc(ctx->m_pool);
                    np->index = i;
                    np->next = prev_np;
                    ctx->info[i]->single = np;

                    LOG(LOG_DEBUG, ("2) c = %d, added np idx %d -> %d\n",
                                    c, i, prev_np->index));
                }
            }
            else
            {
                prev_np = np;
            }

            if(ctx->rle_r[i] > 0)
            {
                continue;
            }
            rle_len = ctx->rle[i] + 1;
            rle_map[rle_len] = 1;
        }
    }

    progress_init(prog, "building.directed.acyclic.graph.", buf_len - 1, 0);

    for (i = buf_len - 1; i >= 0; --i)
    {
        const_matchp matches;

        /* let's populate the cache */
        matches = matches_calc(ctx, i);

        /* add to cache */
        ctx->info[i]->cache = matches;

        progress_bump(prog, i);
    }

    LOG(LOG_NORMAL, ("\n"));

    progress_free(prog);
}
Пример #25
0
/// readbitmap - cread and heck bitmap, reference dumpe2fs
extern void readbitmap(char* device, image_head image_hdr, unsigned long* bitmap, int pui){
    errcode_t retval;
    unsigned long group;
    unsigned long long current_block, block;
    unsigned long long free, gfree;
    char *block_bitmap=NULL;
    int block_nbytes;
    unsigned long long blk_itr;
    int bg_flags = 0;
    int start = 0;
    int bit_size = 1;
    int B_UN_INIT = 0;
    int ext4_gfree_mismatch = 0;

    log_mesg(2, 0, 0, fs_opt.debug, "%s: readbitmap %p\n", __FILE__, bitmap);

    fs_open(device);
    retval = ext2fs_read_bitmaps(fs); /// open extfs bitmap
    if (retval)
	log_mesg(0, 1, 1, fs_opt.debug, "%s: Couldn't find valid filesystem bitmap.\n", __FILE__);

    block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
    if (fs->block_map)
	block_bitmap = malloc(block_nbytes);

    /// initial image bitmap as 1 (all block are used)
    memset(bitmap, 0xFF, sizeof(unsigned long)*LONGS(image_hdr.totalblock));

    free = 0;
    current_block = 0;
    blk_itr = fs->super->s_first_data_block;

    /// init progress
    progress_bar	prog;		/// progress_bar structure defined in progress.h
    progress_init(&prog, start, image_hdr.totalblock, image_hdr.totalblock, BITMAP, bit_size);

    /// each group
    for (group = 0; group < fs->group_desc_count; group++) {

	gfree = 0;
	B_UN_INIT = 0;

	if (block_bitmap) {
	    ext2fs_get_block_bitmap_range(fs->block_map, blk_itr, block_nbytes << 3, block_bitmap);

	    if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM){
#ifdef EXTFS_1_41		
		    bg_flags = fs->group_desc[group].bg_flags;
#else
		    bg_flags = ext2fs_bg_flags(fs, group);
#endif
		    if (bg_flags&EXT2_BG_BLOCK_UNINIT){
			log_mesg(1, 0, 0, fs_opt.debug, "%s: BLOCK_UNINIT for group %lu\n", __FILE__, group);
			B_UN_INIT = 1;
		    } else {
			log_mesg(2, 0, 0, fs_opt.debug, "%s: BLOCK_INIT for group %lu\n", __FILE__, group);
		    }
	    }
	    /// each block in group
	    for (block = 0; ((block < fs->super->s_blocks_per_group) && (current_block < (image_hdr.totalblock-1))); block++) {
		current_block = block + blk_itr;

		/// check block is used or not
		if ((!in_use (block_bitmap, block)) || (B_UN_INIT)) {
		    free++;
		    gfree++;
		    pc_clear_bit(current_block, bitmap);
		    log_mesg(3, 0, 0, fs_opt.debug, "%s: free block %llu at group %lu init %i\n", __FILE__, current_block, group, (int)B_UN_INIT);
		} else {
		    pc_set_bit(current_block, bitmap);
		    log_mesg(3, 0, 0, fs_opt.debug, "%s: used block %llu at group %lu\n", __FILE__, current_block, group);
		}
		/// update progress
		update_pui(&prog, current_block, current_block, 0);//keep update
	    }
	    blk_itr += fs->super->s_blocks_per_group;
	}
	/// check free blocks in group
#ifdef EXTFS_1_41		
	if (gfree != fs->group_desc[group].bg_free_blocks_count){	
#else
	if (gfree != ext2fs_bg_free_blocks_count(fs, group)){
#endif
	    if (!B_UN_INIT)
		log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap error at %lu group.\n", __FILE__, group);
	    else
		ext4_gfree_mismatch = 1;
	}
    }
    /// check all free blocks in partition
    if (free != fs->super->s_free_blocks_count) {
	if ((fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && (ext4_gfree_mismatch))
	    log_mesg(1, 0, 0, fs_opt.debug, "%s: EXT4 bitmap metadata mismatch\n", __FILE__);
	else
	    log_mesg(0, 1, 1, fs_opt.debug, "%s: bitmap free count err, free:%llu\n", __FILE__, free);
    }

    fs_close();
    /// update progress
    update_pui(&prog, 1, 1, 1);//finish
}

/// get extfs type
static int test_extfs_type(char* device){
    int ext2 = 1;
    int ext3 = 2;
    int ext4 = 3;
    int device_type;

    fs_open(device);
    if(fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM){
	log_mesg(1, 0, 0, fs_opt.debug, "%s: test feature as EXT4\n", __FILE__);
	device_type = ext4;
    } else if (fs->super->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL){
	log_mesg(1, 0, 0, fs_opt.debug, "%s: test feature as EXT3\n", __FILE__);
	device_type = ext3;
    } else {
	log_mesg(1, 0, 0, fs_opt.debug, "%s: test feature as EXT2\n", __FILE__);
	device_type = ext2;
    }
    fs_close();
    return device_type;
}
Пример #26
0
/**
 * main functiom - for colne or restore data
 */
int main(int argc, char **argv){ 

    char*		source;			/// source data
    char*		target;			/// target data
    char*		buffer;			/// buffer data for malloc used
    char*		buffer2;			/// buffer data for malloc used
    int			dfr, dfw;		/// file descriptor for source and target
    int			r_size, w_size;		/// read and write size
    unsigned long long	block_id, copied = 0;	/// block_id is every block in partition
    /// copied is copied block count
    off_t		offset = 0, sf = 0;	/// seek postition, lseek result
    int			start, stop;		/// start, range, stop number for progress bar
    unsigned long long	total_write = 0;	/// the copied size 
    unsigned long long	needed_size = 0;	/// the copied size 
    unsigned long long	needed_mem  = 0;	/// the copied size 
    char		bitmagic[8] = "BiTmAgIc";// only for check postition
    char		bitmagic_r[8];		/// read magic string from image
    int			cmp;			/// compare magic string
    char		*bitmap;		/// the point for bitmap data
    int			debug = 0;		/// debug or not
    unsigned long	crc = 0xffffffffL;	/// CRC32 check code for writint to image
    unsigned long	crc_ck = 0xffffffffL;	/// CRC32 check code for checking
    unsigned long	crc_ck2 = 0xffffffffL;	/// CRC32 check code for checking
    int			c_size;			/// CRC32 code size
    char*		crc_buffer;		/// buffer data for malloc crc code
    int			done = 0;
    int			s_count = 0;
    int			tui = 0;		/// text user interface
    int			pui = 0;		/// progress mode(default text)
    int			raw = 0;
    char		image_hdr_magic[512];

    progress_bar	prog;			/// progress_bar structure defined in progress.h
    image_head		image_hdr;		/// image_head structure defined in partclone.h

    /**
     * get option and assign to opt structure
     * check parameter and read from argv
     */
    parse_options(argc, argv, &opt);

    /**
     * if "-d / --debug" given
     * open debug file in "/var/log/partclone.log" for log message 
     */
    debug = opt.debug;
    //if(opt.debug)
    open_log(opt.logfile);

    /**
     * using Text User Interface
     */
    if (opt.ncurses){
        pui = NCURSES;
        log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n");
    } else if (opt.dialog){
        pui = DIALOG;
        log_mesg(1, 0, 0, debug, "Using Dialog User Interface mode.\n");
    } else
        pui = TEXT;

    tui = open_pui(pui, opt.fresh);
    if ((opt.ncurses) && (tui == 0)){
        opt.ncurses = 0;
        log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n");
    } else if ((opt.dialog) && (tui == 1)){
        m_dialog.percent = 1;
    }

    /// print partclone info
    print_partclone_info(opt);

    if (geteuid() != 0)
        log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); 
    else
        log_mesg(1, 0, 0, debug, "UID is root.\n");

    /// ignore crc check
    if(opt.ignore_crc)
	log_mesg(1, 0, 1, debug, "Ignore CRC error\n");

    /**
     * open source and target 
     * clone mode, source is device and target is image file/stdout
     * restore mode, source is image file/stdin and target is device
     * dd mode, source is device and target is device !!not complete
     */
#ifdef _FILE_OFFSET_BITS
    log_mesg(1, 0, 0, debug, "enable _FILE_OFFSET_BITS %i\n", _FILE_OFFSET_BITS);
#endif
    source = opt.source;
    target = opt.target;
    dfr = open_source(source, &opt);
    if (dfr == -1) {
        log_mesg(0, 1, 1, debug, "Erro EXIT.\n");
    }

    dfw = open_target(target, &opt);
    if (dfw == -1) {
        log_mesg(0, 1, 1, debug, "Error Exit.\n");
    }

    /**
     * get partition information like super block, image_head, bitmap
     * from device or image file.
     */

    if (opt.restore){

        log_mesg(1, 0, 0, debug, "restore image hdr - get image_head from image file\n");
        /// get first 512 byte
        r_size = read_all(&dfr, image_hdr_magic, 512, &opt);

        /// check the image magic
        if (memcmp(image_hdr_magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) == 0){
            restore_image_hdr_sp(&dfr, &opt, &image_hdr, image_hdr_magic);

            /// check memory size
            if (check_mem_size(image_hdr, opt, &needed_mem) == -1)
                log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %i bytes memory\n", needed_mem);

            /// alloc a memory to restore bitmap
            bitmap = (char*)malloc(sizeof(char)*image_hdr.totalblock);
            if(bitmap == NULL){
                log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
            }

            /// check the file system
            //if (strcmp(image_hdr.fs, FS) != 0)
            //    log_mesg(0, 1, 1, debug, "%s can't restore from the image which filesystem is %s not %s\n", argv[0], image_hdr.fs, FS);

            log_mesg(2, 0, 0, debug, "initial main bitmap pointer %lli\n", bitmap);
            log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

            /// read and check bitmap from image file
            log_mesg(0, 0, 1, debug, "Calculating bitmap... ");
            log_mesg(0, 0, 1, debug, "Please wait... ");
            get_image_bitmap(&dfr, opt, image_hdr, bitmap);

            /// check the dest partition size.
            if(opt.check){
                check_size(&dfw, image_hdr.device_size);
            }

            log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap);
            log_mesg(0, 0, 1, debug, "done!\n");
        }else{
            log_mesg(1, 0, 0, debug, "This is not partclone image.\n");
            raw = 1;
            //sf = lseek(dfr, 0, SEEK_SET);

            log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n");

            /// get Super Block information from partition
            initial_dd_hdr(dfr, &image_hdr);

            /// check the dest partition size.
            if(opt.check){
                check_size(&dfw, image_hdr.device_size);
            }
        }
    }

    log_mesg(1, 0, 0, debug, "print image_head\n");

    /// print option to log file
    if (debug)
        print_opt(opt);

    /// print image_head
    print_image_hdr_info(image_hdr, opt);

    /**
     * initial progress bar
     */
    start = 0;				/// start number of progress bar
    stop = (image_hdr.usedblocks+1);	/// get the end of progress number, only used block
    log_mesg(1, 0, 0, debug, "Initial Progress bar\n");
    /// Initial progress bar
    progress_init(&prog, start, stop, image_hdr.block_size);
    copied = 0;				/// initial number is 0

    /**
     * start read and write data between device and image file
     */
    if ((opt.restore) && (!raw)) {

        /**
         * read magic string from image file
         * and check it.
         */
        r_size = read_all(&dfr, bitmagic_r, 8, &opt); /// read a magic string
        cmp = memcmp(bitmagic, bitmagic_r, 8);
        if(cmp != 0)
            log_mesg(0, 1, 1, debug, "bitmagic error %i\n", cmp);

        /// seek to the first
        sf = lseek(dfw, 0, SEEK_SET);
        log_mesg(1, 0, 0, debug, "seek %lli for writing dtat string\n",sf);
        if (sf == (off_t)-1)
            log_mesg(0, 1, 1, debug, "seek set %lli\n", sf);

        /// start restore image file to partition
        for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ){

            r_size = 0;
            w_size = 0;

            if (bitmap[block_id] == 1){ 
                /// The block is used
                log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id);
                log_mesg(1, 0, 0, debug, "bitmap=%i, ",bitmap[block_id]);

                offset = (off_t)(block_id * image_hdr.block_size);
#ifdef _FILE_OFFSET_BITS
                sf = lseek(dfw, offset, SEEK_SET);
                if (sf == -1)
                    log_mesg(0, 1, 1, debug, "target seek error = %lli, ",sf);
#endif
                buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data
                if(buffer == NULL){
                    log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                }
                r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt);
                log_mesg(1, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size);
                if (r_size <0)
                    log_mesg(0, 1, 1, debug, "read errno = %i \n", errno);

                /// read crc32 code and check it.
                crc_ck = crc32(crc_ck, buffer, r_size);
                crc_buffer = (char*)malloc(CRC_SIZE); ///alloc a memory to copy data
                if(crc_buffer == NULL){
                    log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                }
                c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt);
                if (c_size < CRC_SIZE)
                    log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno));
                memcpy(&crc, crc_buffer, CRC_SIZE);
		/*FIX: 64bit image can't ignore crc error*/
                if ((memcmp(&crc, &crc_ck, CRC_SIZE) != 0) && (!opt.ignore_crc) ){
                    log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), enlarge crc size and recheck again....\n ");
                    /// check again
                    buffer2 = (char*)malloc(image_hdr.block_size+CRC_SIZE); ///alloc a memory to copy data
                    if(buffer2 == NULL){
                        log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                    }
                    memcpy(buffer2, buffer, image_hdr.block_size);
                    memcpy(buffer2+image_hdr.block_size, crc_buffer, CRC_SIZE);
                    memcpy(buffer, buffer2+CRC_SIZE, image_hdr.block_size);

                    crc_ck2 = crc32(crc_ck2, buffer, r_size);
                    c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt);
                    if (c_size < CRC_SIZE)
                        log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno));
                    memcpy(&crc, crc_buffer, CRC_SIZE);
                    if ((memcmp(&crc, &crc_ck2, CRC_SIZE) != 0) && (!opt.ignore_crc)){
                        log_mesg(0, 1, 1, debug, "CRC error again at %i...\n ", sf);
                    } else {
                        crc_ck = crc_ck2;
                    }
                    free(buffer2);

                } else {
                    crc_ck2 = crc_ck;
                }


                /// write block from buffer to partition
                w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt);
                log_mesg(1, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size);
                if (w_size != (int)image_hdr.block_size)
                    log_mesg(0, 1, 1, debug, "write error %i \n", w_size);
                /// free buffer
                free(buffer);
                free(crc_buffer);


                copied++;					/// count copied block
                total_write += (unsigned long long) w_size;	/// count copied size

                /// read or write error
                //if ((r_size != w_size) || (r_size != image_hdr.block_size))
                //	log_mesg(0, 1, 1, debug, "read and write different\n");
                log_mesg(1, 0, 0, debug, "end\n");
            } else {
#ifndef _FILE_OFFSET_BITS
                /// if the block is not used, I just skip it.
                log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id);
                sf = lseek(dfw, image_hdr.block_size, SEEK_CUR);
                log_mesg(2, 0, 0, debug, "seek=%lli, ",sf);
                if (sf == (off_t)-1)
                    log_mesg(0, 1, 1, debug, "seek error %lli errno=%i\n", (long long)offset, (int)errno);
                log_mesg(2, 0, 0, debug, "end\n");
#endif
            }
	    update_pui(&prog, copied, done);
        } // end of for
	done = 1;
	update_pui(&prog, copied, done);
        sync_data(dfw, &opt);	
    } else if ((opt.restore) && (raw)){
        /// start clone partition to image file

        //write image_head to image file
        w_size = write_all(&dfw, image_hdr_magic, 512, &opt);
        if(w_size == -1)
            log_mesg(0, 1, 1, debug, "write image_hdr to image error\n");

        block_id = 1;
        do {

            log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id);

            buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data
            if(buffer == NULL){
                log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
            }

            /// read data from source to buffer
            r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt);
            log_mesg(1, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size);
            if (r_size != (int)image_hdr.block_size){
                log_mesg(0, 1, 1, debug, "read error %i \n", r_size);
            }

            if (r_size == image_hdr.block_size){
                /// write buffer to target
                w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt);
                log_mesg(2, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size);
                if (w_size != (int)image_hdr.block_size)
                    log_mesg(0, 1, 1, debug, "write error %i \n", w_size);
            } else {
                w_size = 0;
            }

            /// free buffer
            free(buffer);

            /// read or write error
            if (r_size != w_size)
                log_mesg(0, 1, 1, debug, "read and write different\n");
            log_mesg(1, 0, 0, debug, "end\n");
            block_id++;
            r_size = 0;
            w_size = 0;
            copied++;					/// count copied block
            total_write += (unsigned long long)(w_size);	/// count copied size
            log_mesg(1, 0, 0, debug, "total=%lli, ", total_write);

            update_pui(&prog, copied, done);
	    if(copied == image_hdr.totalblock){
		done = 1;	
	    }

        } while (done == 0);/// end of for    
        sync_data(dfw, &opt);	

    }

    print_finish_info(opt);

    close (dfr);    /// close source
    close (dfw);    /// close target
    free(bitmap);   /// free bitmp
    close_pui(pui);
    printf("Cloned successfully.\n");
    if(opt.debug)
        close_log();
    return 0;	    /// finish
}
Пример #27
0
struct search_node*
search_buffer(match_ctx ctx,       /* IN */
              encode_match_f * f,  /* IN */
              encode_match_data emd,       /* IN */
              int use_literal_sequences)
{
    struct progress prog[1];
    struct search_node *sn_arr;
    const_matchp mp = NULL;
    struct search_node *snp;
    struct search_node *best_copy_snp;
    int best_copy_len;

    struct search_node *best_rle_snp;

    int len = ctx->len + 1;

    progress_init(prog, "finding.shortest.path.",len, 0);

    sn_arr = malloc(len * sizeof(struct search_node));
    memset(sn_arr, 0, len * sizeof(struct search_node));

    --len;
    snp = &sn_arr[len];
    snp->index = len;
    snp->match->offset = 0;
    snp->match->len = 0;
    snp->total_offset = 0;
    snp->total_score = 0;
    snp->prev = NULL;

    best_copy_snp = snp;
    best_copy_len = 0.0;

    best_rle_snp = NULL;

    /* think twice about changing this code,
     * it works the way it is. The last time
     * I examined this code I was certain it was
     * broken and broke it myself, trying to fix it. */
    while (len > 0 && (mp = matches_get(ctx, len - 1)) != NULL)
    {
        float prev_score;
        float prev_offset_sum;

        if(use_literal_sequences)
        {
            /* check if we can do even better with copy */
            snp = &sn_arr[len];
            if(best_copy_snp->total_score+best_copy_len * 8.0 -
               snp->total_score > 0.0 || best_copy_len > 65535)
            {
                /* found a better copy endpoint */
                LOG(LOG_DEBUG,
                    ("best copy start moved to index %d\n", snp->index));
                best_copy_snp = snp;
                best_copy_len = 0.0;
            } else
            {
                float copy_score = best_copy_len * 8.0 + (1.0 + 17.0 + 17.0);
                float total_copy_score = best_copy_snp->total_score +
                                         copy_score;

                LOG(LOG_DEBUG,
                    ("total score %0.1f, copy total score %0.1f\n",
                     snp->total_score, total_copy_score));

                if(snp->total_score > total_copy_score )
                {
                    match local_mp;
                    /* here it is good to just copy instead of crunch */

                    LOG(LOG_DEBUG,
                        ("copy index %d, len %d, total %0.1f, copy %0.1f\n",
                         snp->index, best_copy_len,
                         snp->total_score, total_copy_score));

                    local_mp->len = best_copy_len;
                    local_mp->offset = 0;
                    local_mp->next = NULL;
                    snp->total_score = total_copy_score;
                    snp->total_offset = best_copy_snp->total_offset;
                    snp->prev = best_copy_snp;
                    *snp->match = *local_mp;
                }
            }
            /* end of copy optimization */
        }

        /* check if we can do rle */
        snp = &sn_arr[len];
        if(best_rle_snp == NULL ||
           snp->index + 65535 < best_rle_snp->index ||
           snp->index + ctx->rle_r[snp->index] < best_rle_snp->index)
        {
            /* best_rle_snp can't be reached by rle from snp, reset it*/
            if(ctx->rle[snp->index] > 0)
            {
                best_rle_snp = snp;
                LOG(LOG_DEBUG, ("resetting best_rle at index %d, len %d\n",
                                 snp->index, ctx->rle[snp->index]));
            }
            else
            {
                best_rle_snp = NULL;
            }
        }
        else if(ctx->rle[snp->index] > 0 &&
                snp->index + ctx->rle_r[snp->index] >= best_rle_snp->index)
        {
            float best_rle_score;
            float total_best_rle_score;
            float snp_rle_score;
            float total_snp_rle_score;
            match rle_mp;

            LOG(LOG_DEBUG, ("challenger len %d, index %d, "
                             "ruling len %d, index %d\n",
                             ctx->rle_r[snp->index], snp->index,
                             ctx->rle_r[best_rle_snp->index],
                             best_rle_snp->index));

            /* snp and best_rle_snp is the same rle area,
             * let's see which is best */
            rle_mp->len = ctx->rle[best_rle_snp->index];
            rle_mp->offset = 1;
            best_rle_score = f(rle_mp, emd, NULL);
            total_best_rle_score = best_rle_snp->total_score +
                best_rle_score;

            rle_mp->len = ctx->rle[snp->index];
            rle_mp->offset = 1;
            snp_rle_score = f(rle_mp, emd, NULL);
            total_snp_rle_score = snp->total_score + snp_rle_score;

            if(total_snp_rle_score <= total_best_rle_score)
            {
                /* yes, the snp is a better rle than best_rle_snp */
                LOG(LOG_DEBUG, ("prospect len %d, index %d, (%0.1f+%0.1f) "
                                 "ruling len %d, index %d (%0.1f+%0.1f)\n",
                                 ctx->rle[snp->index], snp->index,
                                 snp->total_score, snp_rle_score,
                                 ctx->rle[best_rle_snp->index],
                                 best_rle_snp->index,
                                 best_rle_snp->total_score, best_rle_score));
                best_rle_snp = snp;
                LOG(LOG_DEBUG, ("setting current best_rle: "
                                 "index %d, len %d\n",
                                 snp->index, rle_mp->len));
            }
        }
        if(best_rle_snp != NULL && best_rle_snp != snp)
        {
            float rle_score;
            float total_rle_score;
            /* check if rle is better */
            match local_mp;
            local_mp->len = best_rle_snp->index - snp->index;
            local_mp->offset = 1;

            rle_score = f(local_mp, emd, NULL);
            total_rle_score = best_rle_snp->total_score + rle_score;

            LOG(LOG_DEBUG, ("comparing index %d (%0.1f) with "
                             "rle index %d, len %d, total score %0.1f %0.1f\n",
                             snp->index, snp->total_score,
                             best_rle_snp->index, local_mp->len,
                             best_rle_snp->total_score, rle_score));

            if(snp->total_score > total_rle_score)
            {
                /*here it is good to do rle instead of crunch */
                LOG(LOG_DEBUG,
                    ("rle index %d, len %d, total %0.1f, rle %0.1f\n",
                     snp->index, local_mp->len,
                     snp->total_score, total_rle_score));

                snp->total_score = total_rle_score;
                snp->total_offset = best_rle_snp->total_offset + 1;
                snp->prev = best_rle_snp;

                *snp->match = *local_mp;
            }
        }
        /* end of rle optimization */

        LOG(LOG_DUMP,
            ("matches for index %d with total score %0.1f\n",
             len - 1, snp->total_score));

        prev_score = sn_arr[len].total_score;
        prev_offset_sum = sn_arr[len].total_offset;
        while (mp != NULL)
        {
            matchp next;
            int end_len;
            match tmp;
            int bucket_len_start;
            float score;

            next = mp->next;
            end_len = 1;
            *tmp = *mp;
            tmp->next = NULL;
            bucket_len_start = 0;
            for(tmp->len = mp->len; tmp->len >= end_len; --(tmp->len))
            {
                float total_score;
                unsigned int total_offset;
                struct encode_match_buckets match_buckets;

                LOG(LOG_DUMP, ("mp[%d, %d], tmp[%d, %d]\n",
                               mp->offset, mp->len,
                               tmp->offset, tmp->len));
                if (bucket_len_start == 0 ||
                    tmp->len < 3 ||
                    tmp->len < bucket_len_start)
                {
                    score = f(tmp, emd, &match_buckets);
                    bucket_len_start = match_buckets.len.start;
                }

                total_score = prev_score + score;
                total_offset = prev_offset_sum + tmp->offset;
                snp = &sn_arr[len - tmp->len];

                LOG(LOG_DUMP,
                    ("[%05d] cmp [%05d, %05d score %.1f + %.1f] with %.1f",
                     len, tmp->offset, tmp->len,
                     prev_score, score, snp->total_score));

                if ((total_score < 100000000.0) &&
                    (snp->match->len == 0 ||
                     total_score < snp->total_score ||
                     (total_score == snp->total_score &&
                      (tmp->offset == 0 ||
                       (snp->match->len == tmp->len &&
                        (total_offset <= snp->total_offset))))))
                {
                    LOG(LOG_DUMP, (", replaced"));
                    snp->index = len - tmp->len;

                    *snp->match = *tmp;
                    snp->total_offset = total_offset;
                    snp->total_score = total_score;
                    snp->prev = &sn_arr[len];
                }
                LOG(LOG_DUMP, ("\n"));
            }
            LOG(LOG_DUMP, ("tmp->len %d, ctx->rle[%d] %d\n",
                           tmp->len, len - tmp->len,
                           ctx->rle[len - tmp->len]));

            mp = next;
        }

        /* slow way to get to the next node for cur */
        --len;
        ++best_copy_len;
        if(sn_arr[len].match == NULL)
        {
            LOG(LOG_ERROR, ("Found unreachable node at len %d.\n", len));
        }

        progress_bump(prog, len);
    }
    if(len > 0 && mp == NULL)
    {
        LOG(LOG_ERROR, ("No matches at len %d.\n", len));
    }
    LOG(LOG_NORMAL, ("\n"));

    progress_free(prog);

    return sn_arr;
}
Пример #28
0
/**
 * main function - for clone or restore data
 */
int main(int argc, char **argv) {
#ifdef MEMTRACE
	setenv("MALLOC_TRACE", "partclone_mtrace.log", 1);
	mtrace();
#endif
	char*			source;			/// source data
	char*			target;			/// target data
	int			dfr, dfw;		/// file descriptor for source and target
	int			r_size, w_size;		/// read and write size
	unsigned		cs_size = 0;		/// checksum_size
	int			cs_reseed = 1;
	int			start, stop;		/// start, range, stop number for progress bar
	unsigned long *bitmap = NULL;		/// the point for bitmap data
	int			debug = 0;		/// debug level
	int			tui = 0;		/// text user interface
	int			pui = 0;		/// progress mode(default text)
	
	int			flag;
	int			pres = 0;
	pthread_t		prog_thread;
	void			*p_result;

	static const char *const bad_sectors_warning_msg =
		"*************************************************************************\n"
		"* WARNING: The disk has bad sectors. This means physical damage on the  *\n"
		"* disk surface caused by deterioration, manufacturing faults, or        *\n"
		"* another reason. The reliability of the disk may remain stable or      *\n"
		"* degrade quickly. Use the --rescue option to efficiently save as much  *\n"
		"* data as possible!                                                     *\n"
		"*************************************************************************\n";

	file_system_info fs_info;   /// description of the file system
	image_options    img_opt;

	init_fs_info(&fs_info);
	init_image_options(&img_opt);

	/**
	 * get option and assign to opt structure
	 * check parameter and read from argv
	 */
	parse_options(argc, argv, &opt);

	/**
	 * if "-d / --debug" given
	 * open debug file in "/var/log/partclone.log" for log message 
	 */
	memset(&fs_opt, 0, sizeof(fs_cmd_opt));
	debug = opt.debug;
	fs_opt.debug = debug;
	fs_opt.ignore_fschk = opt.ignore_fschk;

	//if(opt.debug)
	open_log(opt.logfile);

	/**
	 * using Text User Interface
	 */
	if (opt.ncurses) {
		pui = NCURSES;
		log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n");
	} else
		pui = TEXT;

	tui = open_pui(pui, opt.fresh);
	if ((opt.ncurses) && (!tui)) {
		opt.ncurses = 0;
		pui = TEXT;
		log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n");
	}

	/// print partclone info
	print_partclone_info(opt);

#ifndef CHKIMG
	if (geteuid() != 0)
		log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n");
	else
		log_mesg(1, 0, 0, debug, "UID is root.\n");
#endif

	/// ignore crc check
	if (opt.ignore_crc)
		log_mesg(1, 0, 1, debug, "Ignore CRC errors\n");

	/**
	 * open source and target
	 * clone mode, source is device and target is image file/stdout
	 * restore mode, source is image file/stdin and target is device
	 * dd mode, source is device and target is device !!not complete
	 */
	source = opt.source;
	target = opt.target;
	log_mesg(1, 0, 0, debug, "source=%s, target=%s \n", source, target);
	dfr = open_source(source, &opt);
	if (dfr == -1) {
		log_mesg(0, 1, 1, debug, "Error exit\n");
	}

#ifndef CHKIMG
	dfw = open_target(target, &opt);
	if (dfw == -1) {
		log_mesg(0, 1, 1, debug, "Error exit\n");
	}
#else
	dfw = -1;
#endif

	/**
	 * get partition information like super block, bitmap from device or image file.
	 */
	if (opt.clone) {

		log_mesg(1, 0, 0, debug, "Initiate image options - version %s\n", IMAGE_VERSION_CURRENT);

		img_opt.checksum_mode = opt.checksum_mode;
		img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug);
		img_opt.blocks_per_checksum = opt.blocks_per_checksum;
		img_opt.reseed_checksum = opt.reseed_checksum;

		cs_size = img_opt.checksum_size;
		cs_reseed = img_opt.reseed_checksum;

		log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n");
		log_mesg(0, 0, 1, debug, "Reading Super Block\n");

		/// get Super Block information from partition
		read_super_blocks(source, &fs_info);

		if (img_opt.checksum_mode != CSM_NONE && img_opt.blocks_per_checksum == 0) {

			const unsigned int buffer_capacity = opt.buffer_size > fs_info.block_size
				? opt.buffer_size / fs_info.block_size : 1; // in blocks

			img_opt.blocks_per_checksum = buffer_capacity;

		}
		log_mesg(1, 0, 0, debug, "%u blocks per checksum\n", img_opt.blocks_per_checksum);

		check_mem_size(fs_info, img_opt, opt);

		/// alloc a memory to store bitmap
		bitmap = pc_alloc_bitmap(fs_info.totalblock);
		if (bitmap == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap);
		log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

		/// read and check bitmap from partition
		log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... \n");
		read_bitmap(source, fs_info, bitmap, pui);
		update_used_blocks_count(&fs_info, bitmap);

		if (opt.check) {

			unsigned long long needed_space = 0;

			needed_space += sizeof(image_head) + sizeof(file_system_info) + sizeof(image_options);
			needed_space += get_bitmap_size_on_disk(&fs_info, &img_opt, &opt);
			needed_space += cnv_blocks_to_bytes(0, fs_info.usedblocks, fs_info.block_size, &img_opt);

			check_free_space(&dfw, needed_space);
		}

		log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap);
		log_mesg(1, 0, 0, debug, "Writing super block and bitmap...\n");

		write_image_desc(&dfw, fs_info, img_opt, &opt);
		write_image_bitmap(&dfw, fs_info, img_opt, bitmap, &opt);

		log_mesg(0, 0, 1, debug, "done!\n");

	} else if (opt.restore) {

		image_head_v2 img_head;

		log_mesg(1, 0, 0, debug, "restore image hdr - get information from image file\n");
		log_mesg(1, 0, 1, debug, "Reading Super Block\n");

		/// get image information from image file
		load_image_desc(&dfr, &opt, &img_head, &fs_info, &img_opt);
		cs_size = img_opt.checksum_size;
		cs_reseed = img_opt.reseed_checksum;

		check_mem_size(fs_info, img_opt, opt);

		/// alloc a memory to restore bitmap
		bitmap = pc_alloc_bitmap(fs_info.totalblock);
		if (bitmap == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap);
		log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

		/// read and check bitmap from image file
		log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait...\n");
		load_image_bitmap(&dfr, opt, fs_info, img_opt, bitmap);

#ifndef CHKIMG
		/// check the dest partition size.
		if (opt.restore_raw_file)
			check_free_space(&dfw, fs_info.device_size);
		else if (opt.check)
			check_size(&dfw, fs_info.device_size);
#endif

		log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap);
		log_mesg(0, 0, 1, debug, "done!\n");

	} else if (opt.dd || opt.domain) {

		log_mesg(1, 0, 0, debug, "Initiate image options - version %s\n", IMAGE_VERSION_CURRENT);
		img_opt.checksum_mode = opt.checksum_mode;
		img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug);
		img_opt.blocks_per_checksum = opt.blocks_per_checksum;
		img_opt.reseed_checksum = opt.reseed_checksum;
		log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n");
		log_mesg(1, 0, 1, debug, "Reading Super Block\n");

		/// get Super Block information from partition
		read_super_blocks(source, &fs_info);

		check_mem_size(fs_info, img_opt, opt);

		/// alloc a memory to restore bitmap
		bitmap = pc_alloc_bitmap(fs_info.totalblock);
		if (bitmap == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap);
		log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

		/// read and check bitmap from partition
		log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... ");
		read_bitmap(source, fs_info, bitmap, pui);

		/// check the dest partition size.
		if (opt.dd && opt.check) {
			check_size(&dfw, fs_info.device_size);
		}

		log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap);
		log_mesg(0, 0, 1, debug, "done!\n");
	} else if (opt.ddd){

		if (dfr != 0)
		    read_super_blocks(source, &fs_info);
		else
		    read_super_blocks(target, &fs_info);

		img_opt.checksum_mode = opt.checksum_mode;
		img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug);
		img_opt.blocks_per_checksum = opt.blocks_per_checksum;
		check_mem_size(fs_info, img_opt, opt);

		/// alloc a memory to restore bitmap
		bitmap = pc_alloc_bitmap(fs_info.totalblock);
		if (bitmap == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap);
		log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

		/// read and check bitmap from partition
		log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... ");
		read_bitmap(source, fs_info, bitmap, pui);

		/// check the dest partition size.
		if (opt.check) {

		    struct stat target_stat;
		    if ((stat(opt.target, &target_stat) != -1) && (strcmp(opt.target, "-") != 0)) {
			if (S_ISBLK(target_stat.st_mode)) 
			    check_size(&dfw, fs_info.device_size);
			else {
			    unsigned long long needed_space = 0;

			    needed_space += sizeof(image_head) + sizeof(file_system_info) + sizeof(image_options);
			    needed_space += get_bitmap_size_on_disk(&fs_info, &img_opt, &opt);
			    needed_space += cnv_blocks_to_bytes(0, fs_info.usedblocks, fs_info.block_size, &img_opt);

			    check_free_space(&dfw, needed_space);
			}
		    }
		}

		log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap);
		log_mesg(0, 0, 1, debug, "done!\n");
    
	}

	log_mesg(1, 0, 0, debug, "print image information\n");

	/// print option to log file
	if (debug)
		print_opt(opt);

	print_file_system_info(fs_info, opt);

	/**
	 * initial progress bar
	 */
	start = 0;				/// start number of progress bar
	stop = (fs_info.usedblocks);		/// get the end of progress number, only used block
	log_mesg(1, 0, 0, debug, "Initial Progress bar\n");
	/// Initial progress bar
	if (opt.no_block_detail)
		flag = NO_BLOCK_DETAIL;
	else
		flag = IO;
	progress_init(&prog, start, stop, fs_info.totalblock, flag, fs_info.block_size);
	copied = 0;				/// initial number is 0

	/**
	 * thread to print progress
	 */
	pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL);
	if(pres)
	    log_mesg(0, 1, 1, debug, "%s, %i, thread create error\n", __func__, __LINE__);


	/**
	 * start read and write data between source and destination
	 */
	if (opt.clone) {

		const unsigned long long blocks_total = fs_info.totalblock;
		const unsigned int block_size = fs_info.block_size;
		const unsigned int buffer_capacity = opt.buffer_size > block_size ? opt.buffer_size / block_size : 1; // in blocks
		unsigned char checksum[cs_size];
		unsigned int blocks_in_cs, blocks_per_cs, write_size;
		char *read_buffer, *write_buffer;

		blocks_per_cs = img_opt.blocks_per_checksum;

		log_mesg(1, 0, 0, debug, "#\nBuffer capacity = %u, Blocks per cs = %u\n#\n", buffer_capacity, blocks_per_cs);

		write_size = cnv_blocks_to_bytes(0, buffer_capacity, block_size, &img_opt);

		read_buffer = (char*)malloc(buffer_capacity * block_size);
		write_buffer = (char*)malloc(write_size + cs_size);

		if (read_buffer == NULL || write_buffer == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		/// read data from the first block
		if (lseek(dfr, 0, SEEK_SET) == (off_t)-1)
			log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno));

		log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total);

		/// start clone partition to image file
		log_mesg(1, 0, 0, debug, "start backup data...\n");

		blocks_in_cs = 0;
		init_checksum(img_opt.checksum_mode, checksum, debug);

		block_id = 0;
		do {
			/// scan bitmap
			unsigned long long i, blocks_skip, blocks_read;
			unsigned int cs_added = 0, write_offset = 0;
			off_t offset;

			/// skip unused blocks
			for (blocks_skip = 0;
			     block_id + blocks_skip < blocks_total &&
			     !pc_test_bit(block_id + blocks_skip, bitmap);
			     blocks_skip++);
			if (block_id + blocks_skip == blocks_total)
				break;

			if (blocks_skip)
				block_id += blocks_skip;

			/// read blocks
			for (blocks_read = 0;
			     block_id + blocks_read < blocks_total && blocks_read < buffer_capacity &&
			     pc_test_bit(block_id + blocks_read, bitmap);
			     ++blocks_read);
			if (!blocks_read)
				break;

			offset = (off_t)(block_id * block_size);
			if (lseek(dfr, offset, SEEK_SET) == (off_t)-1)
				log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno));

			r_size = read_all(&dfr, read_buffer, blocks_read * block_size, &opt);
			if (r_size != (int)(blocks_read * block_size)) {
				if ((r_size == -1) && (errno == EIO)) {
					if (opt.rescue) {
						memset(read_buffer, 0, blocks_read * block_size);
						for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE)
							rescue_sector(&dfr, offset + r_size, read_buffer + r_size, &opt);
					} else
						log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg);
				} else
					log_mesg(0, 1, 1, debug, "read error: %s\n", strerror(errno));
			}

			/// calculate checksum
			log_mesg(2, 0, 0, debug, "blocks_read = %i\n", blocks_read);
			for (i = 0; i < blocks_read; ++i) {

				memcpy(write_buffer + write_offset,
					read_buffer + i * block_size, block_size);

				write_offset += block_size;

				update_checksum(checksum, read_buffer + i * block_size, block_size);

				if (blocks_per_cs > 0 && ++blocks_in_cs == blocks_per_cs) {
				    log_mesg(3, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]);

					memcpy(write_buffer + write_offset, checksum, cs_size);

					++cs_added;
					write_offset += cs_size;

					blocks_in_cs = 0;
					if (cs_reseed)
						init_checksum(img_opt.checksum_mode, checksum, debug);
				}
			}

			/// write buffer to target
			w_size = write_all(&dfw, write_buffer, write_offset, &opt);
			if (w_size != write_offset)
				log_mesg(0, 1, 1, debug, "image write ERROR:%s\n", strerror(errno));

			/// count copied block
			copied += blocks_read;
			log_mesg(2, 0, 0, debug, "copied = %lld\n", copied);

			/// next block
			block_id += blocks_read;

			/// read or write error
			if (r_size + cs_added * cs_size != w_size)
				log_mesg(0, 1, 1, debug, "read(%i) and write(%i) different\n", r_size, w_size);

		} while (1);

		if (blocks_in_cs > 0) {

			// Write the checksum for the latest blocks
			log_mesg(1, 0, 0, debug, "Write the checksum for the latest blocks. size = %i\n", cs_size);
			log_mesg(3, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]);
			w_size = write_all(&dfw, (char*)checksum, cs_size, &opt);
			if (w_size != cs_size)
				log_mesg(0, 1, 1, debug, "image write ERROR:%s\n", strerror(errno));
		}

		free(write_buffer);
		free(read_buffer);

	// check only the size when the image does not contains checksums and does not
	// comes from a pipe
	} else if (opt.chkimg && img_opt.checksum_mode == CSM_NONE
		&& strcmp(opt.source, "-") != 0) {

		unsigned long long total_offset = (fs_info.usedblocks - 1) * fs_info.block_size;
		char last_block[fs_info.block_size];
		off_t partial_offset = INT32_MAX;

		while (total_offset) {

			if (partial_offset > total_offset)
				partial_offset = total_offset;

			if (lseek(dfr, partial_offset, SEEK_CUR) == (off_t)-1)
				log_mesg(0, 1, 1, debug, "source seek ERROR: %s\n", strerror(errno));

			total_offset -= partial_offset;
		}

		if (read_all(&dfr, last_block, fs_info.block_size, &opt) != fs_info.block_size)
			log_mesg(0, 1, 1, debug, "ERROR: source image too short\n");

	} else if (opt.restore) {

		const unsigned long long blocks_total = fs_info.totalblock;
		const unsigned int block_size = fs_info.block_size;
		const unsigned int buffer_capacity = opt.buffer_size > block_size ? opt.buffer_size / block_size : 1; // in blocks
		const unsigned int blocks_per_cs = img_opt.blocks_per_checksum;
		unsigned long long blocks_used = fs_info.usedblocks;
		unsigned int blocks_in_cs, buffer_size, read_offset;
		unsigned char checksum[cs_size];
		char *read_buffer, *write_buffer;
		unsigned long long blocks_used_fix = 0, test_block = 0;

		log_mesg(1, 0, 0, debug, "#\nBuffer capacity = %u, Blocks per cs = %u\n#\n", buffer_capacity, blocks_per_cs);

		// fix some super block record incorrect
		for (test_block = 0; test_block < blocks_total; ++test_block)
			if (pc_test_bit(test_block, bitmap))
				blocks_used_fix++;

		if (blocks_used_fix != blocks_used) {
			blocks_used = blocks_used_fix;
			log_mesg(1, 0, 0, debug, "info: fixed used blocks count\n");
		}
		buffer_size = cnv_blocks_to_bytes(0, buffer_capacity, block_size, &img_opt);

		if (img_opt.image_version != 0x0001)
			read_buffer = (char*)malloc(buffer_size);
		else {
			// Allocate more memory in case the image is affected by the 64 bits bug
			read_buffer = (char*)malloc(buffer_size + buffer_capacity * cs_size);
		}
		write_buffer = (char*)malloc(buffer_capacity * block_size);
		if (read_buffer == NULL || write_buffer == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

#ifndef CHKIMG
		/// seek to the first
		if (lseek(dfw, opt.offset, SEEK_SET) == (off_t)-1)
			log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno));
#endif

		/// start restore image file to partition
		log_mesg(1, 0, 0, debug, "start restore data...\n");

		blocks_in_cs = 0;
		if (!opt.ignore_crc)
			init_checksum(img_opt.checksum_mode, checksum, debug);

		block_id = 0;
		do {
			unsigned int i;
			unsigned long long blocks_written, bytes_skip;
			unsigned int read_size;
			// max chunk to read using one read(2) syscall
			int blocks_read = copied + buffer_capacity < blocks_used ?
				buffer_capacity : blocks_used - copied;
			if (!blocks_read)
				break;

			log_mesg(1, 0, 0, debug, "blocks_read = %d and copied = %lld\n", blocks_read, copied);
			read_size = cnv_blocks_to_bytes(copied, blocks_read, block_size, &img_opt);

			// increase read_size to make room for the oversized checksum
			if (blocks_per_cs && blocks_read < buffer_capacity &&
					(blocks_read % blocks_per_cs) && (blocks_used % blocks_per_cs)) {
				/// it is the last read and there is a partial chunk at the end
				log_mesg(1, 0, 0, debug, "# PARTIAL CHUNK\n");
				read_size += cs_size;
			}

			// read chunk from image
			log_mesg(1, 0, 0, debug, "read more: ");

			r_size = read_all(&dfr, read_buffer, read_size, &opt);
			if (r_size != read_size)
				log_mesg(0, 1, 1, debug, "read ERROR:%s\n", strerror(errno));

			// read buffer is the follows:
			// <blocks_per_cs><cs1><blocks_per_cs><cs2>...

			// write buffer should be the following:
			// <block1><block2>...

			read_offset = 0;
			for (i = 0; i < blocks_read; ++i) {

				memcpy(write_buffer + i * block_size,
					read_buffer + read_offset, block_size);

				if (opt.ignore_crc) {
					read_offset += block_size;
					if (++blocks_in_cs == blocks_per_cs)
						read_offset += cs_size;
					continue;
				}

				update_checksum(checksum, read_buffer + read_offset, block_size);

				if (++blocks_in_cs == blocks_per_cs) {

				    unsigned char checksum_orig[cs_size];
				    memcpy(checksum_orig, read_buffer + read_offset + block_size, cs_size);
				    log_mesg(3, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]);
				    log_mesg(3, 0, 0, debug, "CRC.orig = %x%x%x%x \n", checksum_orig[0], checksum_orig[1], checksum_orig[2], checksum_orig[3]);
					if (memcmp(read_buffer + read_offset + block_size, checksum, cs_size)) {
					    log_mesg(0, 1, 1, debug, "CRC error, block_id=%llu...\n ", block_id + i);
					}

					read_offset += cs_size;

					blocks_in_cs = 0;
					if (cs_reseed)
						init_checksum(img_opt.checksum_mode, checksum, debug);
				}

				read_offset += block_size;
			}
			if (blocks_in_cs && blocks_per_cs && blocks_read < buffer_capacity &&
					(blocks_read % blocks_per_cs)) {

			    log_mesg(1, 0, 0, debug, "check latest chunk's checksum covering %u blocks\n", blocks_in_cs);
			    if (memcmp(read_buffer + read_offset, checksum, cs_size)){
				unsigned char checksum_orig[cs_size];
				memcpy(checksum_orig, read_buffer + read_offset, cs_size);
				log_mesg(1, 0, 0, debug, "CRC = %x%x%x%x \n", checksum[0], checksum[1], checksum[2], checksum[3]);
				log_mesg(1, 0, 0, debug, "CRC.orig = %x%x%x%x \n", checksum_orig[0], checksum_orig[1], checksum_orig[2], checksum_orig[3]);
				log_mesg(0, 1, 1, debug, "CRC error, block_id=%llu...\n ", block_id + i);
			    }

			}


			blocks_written = 0;
			do {
				int blocks_write;

				/// count bytes to skip
				for (bytes_skip = 0;
				     block_id < blocks_total &&
				     !pc_test_bit(block_id, bitmap);
				     block_id++, bytes_skip += block_size);

#ifndef CHKIMG
				/// skip empty blocks
				if (bytes_skip > 0 && lseek(dfw, (off_t)bytes_skip, SEEK_CUR) == (off_t)-1)
					log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno));
#endif

				/// blocks to write
				for (blocks_write = 0;
				     block_id + blocks_write < blocks_total &&
				     blocks_written + blocks_write < blocks_read &&
				     pc_test_bit(block_id + blocks_write, bitmap);
				     blocks_write++);

#ifndef CHKIMG
				// write blocks
				if (blocks_write > 0) {
					w_size = write_all(&dfw, write_buffer + blocks_written * block_size,
						blocks_write * block_size, &opt);
					if (w_size != blocks_write * block_size) {
						if (!opt.skip_write_error)
							log_mesg(0, 1, 1, debug, "write block %llu ERROR:%s\n", block_id + blocks_written, strerror(errno));
						else
							log_mesg(0, 0, 1, debug, "skip write block %llu error:%s\n", block_id + blocks_written, strerror(errno));
					}
				}
#endif

				blocks_written += blocks_write;
				block_id += blocks_write;
				copied += blocks_write;
			} while (blocks_written < blocks_read);

		} while(1);
		free(write_buffer);
		free(read_buffer);

#ifndef CHKIMG
		/// restore_raw_file option
		if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) {
			if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1)
				log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno));
		}
#endif

	} else if (opt.dd) {

		char *buffer;
		int block_size = fs_info.block_size;
		unsigned long long blocks_total = fs_info.totalblock;
		int buffer_capacity = block_size < opt.buffer_size ? opt.buffer_size / block_size : 1;

		buffer = (char*)malloc(buffer_capacity * block_size);
		if (buffer == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		block_id = 0;

		if (lseek(dfr, 0, SEEK_SET) == (off_t)-1)
			log_mesg(0, 1, 1, debug, "source seek ERROR:%d\n", strerror(errno));

		log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total);

		/// start clone partition to partition
		log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n");
		do {
			/// scan bitmap
			unsigned long long blocks_skip, blocks_read;
			off_t offset;

			/// skip unused blocks
			for (blocks_skip = 0;
			     block_id + blocks_skip < blocks_total &&
			     !pc_test_bit(block_id + blocks_skip, bitmap);
			     blocks_skip++);

			if (block_id + blocks_skip == blocks_total)
				break;

			if (blocks_skip)
				block_id += blocks_skip;

			/// read chunk from source
			for (blocks_read = 0;
			     block_id + blocks_read < blocks_total && blocks_read < buffer_capacity &&
			     pc_test_bit(block_id + blocks_read, bitmap);
			     ++blocks_read);

			if (!blocks_read)
				break;

			offset = (off_t)(block_id * block_size);
			if (lseek(dfr, offset, SEEK_SET) == (off_t)-1)
				log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno));
			if (lseek(dfw, offset + opt.offset, SEEK_SET) == (off_t)-1)
				log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno));

			r_size = read_all(&dfr, buffer, blocks_read * block_size, &opt);
			if (r_size != (int)(blocks_read * block_size)) {
				if ((r_size == -1) && (errno == EIO)) {
					if (opt.rescue) {
						memset(buffer, 0, blocks_read * block_size);
						for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE)
							rescue_sector(&dfr, offset + r_size, buffer + r_size, &opt);
					} else
						log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg);
				} else
					log_mesg(0, 1, 1, debug, "source read ERROR %s\n", strerror(errno));
			}

			/// write buffer to target
			w_size = write_all(&dfw, buffer, blocks_read * block_size, &opt);
			if (w_size != (int)(blocks_read * block_size)) {
				if (opt.skip_write_error)
					log_mesg(0, 0, 1, debug, "skip write block %lli error:%s\n", block_id, strerror(errno));
				else
					log_mesg(0, 1, 1, debug, "write block %lli ERROR:%s\n", block_id, strerror(errno));
			}

			/// count copied block
			copied += blocks_read;

			/// next block
			block_id += blocks_read;

			/// read or write error
			if (r_size != w_size) {
				if (opt.skip_write_error)
					log_mesg(0, 0, 1, debug, "read and write different\n");
				else
					log_mesg(0, 1, 1, debug, "read and write different\n");
			}
		} while (1);

		free(buffer);

		/// restore_raw_file option
		if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) {
			if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1)
				log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno));
		}

	} else if (opt.domain) {

		int cmp, nx_current = 0;
		unsigned long long next_block_id = 0;
		log_mesg(0, 0, 0, debug, "Total block %i\n", fs_info.totalblock);
		log_mesg(1, 0, 0, debug, "start writing domain log...\n");
		// write domain log comment and status line
		dprintf(dfw, "# Domain logfile created by %s v%s\n", get_exec_name(), VERSION);
		dprintf(dfw, "# Source: %s\n", opt.source);
		dprintf(dfw, "# Offset: 0x%08llX\n", opt.offset_domain);
		dprintf(dfw, "# current_pos  current_status\n");
		dprintf(dfw, "0x%08llX     ?\n", opt.offset_domain + (fs_info.totalblock * fs_info.block_size));
		dprintf(dfw, "#      pos        size  status\n");
		// start logging the used/unused areas
		cmp = pc_test_bit(0, bitmap);
		for (block_id = 0; block_id <= fs_info.totalblock; block_id++) {
			if (block_id < fs_info.totalblock) {
				nx_current = pc_test_bit(block_id, bitmap);
				if (nx_current)
					copied++;
			} else
				nx_current = -1;
			if (nx_current != cmp) {
				dprintf(dfw, "0x%08llX  0x%08llX  %c\n",
					opt.offset_domain + (next_block_id * fs_info.block_size),
					(block_id - next_block_id) * fs_info.block_size,
					cmp ? '+' : '?');
				next_block_id = block_id;
				cmp = nx_current;
			}
			// don't bother updating progress
		} /// end of for
	} else if (opt.ddd) {

		char *buffer;
		int block_size = fs_info.block_size;
		unsigned long long blocks_total = fs_info.totalblock;
		int blocks_in_buffer = block_size < opt.buffer_size ? opt.buffer_size / block_size : 1;

		buffer = (char*)malloc(blocks_in_buffer * block_size);
		if (buffer == NULL) {
			log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__);
		}

		block_id = 0;


		log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total);

		/// start clone partition to partition
		log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n");
		do {
			/// scan bitmap
			unsigned long long blocks_read;

			/// read chunk from source
			for (blocks_read = 0;
			     block_id + blocks_read < blocks_total && blocks_read < blocks_in_buffer &&
			     pc_test_bit(block_id + blocks_read, bitmap);
			     blocks_read++);

			if (!blocks_read)
				break;

			r_size = read_all(&dfr, buffer, blocks_read * block_size, &opt);
			if (r_size != (int)(blocks_read * block_size)) {
				if ((r_size == -1) && (errno == EIO)) {
					if (opt.rescue) {
						memset(buffer, 0, blocks_read * block_size);
						for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE)
							rescue_sector(&dfr, r_size, buffer + r_size, &opt);
					} else
						log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg);
				} else if (r_size == 0){ // done for ddd
				    /// write buffer to target
				    w_size = write_all(&dfw, buffer, rescue_write_size, &opt);
				    break;
				} else
					log_mesg(0, 1, 1, debug, "source read ERROR %s\n", strerror(errno));
			}

			/// write buffer to target
			w_size = write_all(&dfw, buffer, blocks_read * block_size, &opt);
			if (w_size != (int)(blocks_read * block_size)) {
				if (opt.skip_write_error)
					log_mesg(0, 0, 1, debug, "skip write block %lli error:%s\n", block_id, strerror(errno));
				else
					log_mesg(0, 1, 1, debug, "write block %lli ERROR:%s\n", block_id, strerror(errno));
			}

			/// count copied block
			copied += blocks_read;

			/// next block
			block_id += blocks_read;

			/// read or write error
			if (r_size != w_size) {
				if (opt.skip_write_error)
					log_mesg(0, 0, 1, debug, "read and write different\n");
				else
					log_mesg(0, 1, 1, debug, "read and write different\n");
			}
		} while (1);

		free(buffer);

		/// restore_raw_file option
		if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) {
			if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1)
				log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno));
		}



	}

	done = 1;
	pres = pthread_join(prog_thread, &p_result);
	if(pres)
	    log_mesg(0, 1, 1, debug, "%s, %i, thread join error\n", __func__, __LINE__);
	update_pui(&prog, copied, block_id, done);
#ifndef CHKIMG
	sync_data(dfw, &opt);
#endif
	print_finish_info(opt);

	/// close source
	close(dfr);
	/// close target
	if (dfw != -1)
		close(dfw);
	/// free bitmp
	free(bitmap);
	close_pui(pui);
#ifndef CHKIMG
	fprintf(stderr, "Cloned successfully.\n");
#else
	printf("Checked successfully.\n");
#endif
	if (opt.debug)
		close_log();
#ifdef MEMTRACE
	muntrace();
#endif
	return 0;      /// finish
}
Пример #29
0
/**
 * main functiom - for colne or restore data
 */
int main(int argc, char **argv){ 

    int			dfr;		/// file descriptor for source and target
    int			r_size;		/// read and write size
    char*		buffer;		/// buffer data
    char*		buffer2;		/// buffer data
    //unsigned long long	block_id, copied = 0;	/// block_id is every block in partition
    /// copied is copied block count
    off_t		offset = 0, sf = 0;	/// seek postition, lseek result
    int			start, stop;		/// start, range, stop number for progress bar
    char		bitmagic[8] = "BiTmAgIc";// only for check postition
    char		bitmagic_r[8];		/// read magic string from image
    int			cmp;			/// compare magic string
    unsigned long	*bitmap;		/// the point for bitmap data
    int			debug = 0;		/// debug or not
    unsigned long	crc = 0xffffffffL;	/// CRC32 check code for writint to image
    unsigned long	crc_ck = 0xffffffffL;	/// CRC32 check code for checking
    unsigned long	crc_ck2 = 0xffffffffL;	/// CRC32 check code for checking
    int			c_size;			/// CRC32 code size
    //int			done = 0;
    int			tui = 0;		/// text user interface
    int			pui = 0;		/// progress mode(default text)
    int			flag = 0;

    int pres;
    pthread_t prog_thread;
    void *p_result;

    //progress_bar	prog;			/// progress_bar structure defined in progress.h
    image_head		image_hdr;		/// image_head structure defined in partclone.h

    /**
     * get option and assign to opt structure
     * check parameter and read from argv
     */
    parse_option_chkimg(argc, argv, &opt);

    /**
     * if "-d / --debug" given
     * open debug file in "/var/log/partclone.log" for log message 
     */
    debug = opt.debug;
    open_log(opt.logfile);

    /**
     * using Text User Interface
     */
    if (opt.ncurses){
        pui = NCURSES;
        log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n");
    } else
        pui = TEXT;

    tui = open_pui(pui, opt.fresh);
    if ((opt.ncurses) && (tui == 0)){
        opt.ncurses = 0;
        log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n");
    }

    /// print partclone info
    print_partclone_info(opt);

    /*
    if (geteuid() != 0)
        log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); 
    else
        log_mesg(1, 0, 0, debug, "UID is root.\n");
     */
    /// ignore crc check
    if(opt.ignore_crc)
	log_mesg(1, 0, 1, debug, "Ignore CRC\n");

    /**
     * open source and target 
     * clone mode, source is device and target is image file/stdout
     * restore mode, source is image file/stdin and target is device
     * dd mode, source is device and target is device !!not complete
     */
#ifdef _FILE_OFFSET_BITS
    log_mesg(1, 0, 0, debug, "enable _FILE_OFFSET_BITS %i\n", _FILE_OFFSET_BITS);
#endif
    dfr = open_source(opt.source, &opt);
    if (dfr == -1) {
        log_mesg(0, 1, 1, debug, "Erro EXIT.\n");
    }

    /**
     * get partition information like super block, image_head, bitmap
     * from device or image file.
     */


    log_mesg(1, 0, 0, debug, "Checking image hdr - get image_head from image file\n");

    restore_image_hdr(&dfr, &opt, &image_hdr);
    /// check the image magic
    if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0)
        log_mesg(0, 1, 1, debug, "The Image magic error. This file is NOT partclone Image\n");

    /// alloc a memory to restore bitmap
    bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock));
    if(bitmap == NULL){
        log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
    }

    log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap);
    log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n");

    /// read and check bitmap from image file
    log_mesg(0, 0, 1, debug, "Calculating bitmap... ");
    log_mesg(0, 0, 1, debug, "Please wait... ");
    get_image_bitmap(&dfr, opt, image_hdr, bitmap);

    log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap);
    log_mesg(0, 0, 1, debug, "done!\n");

    log_mesg(1, 0, 0, debug, "print image_head\n");

    /// print option to log file
    if (debug)
        print_opt(opt);

    /// print image_head
    print_image_hdr_info(image_hdr, opt);

    /**
     * initial progress bar
     */
    start = 0;				/// start number of progress bar
    stop = image_hdr.usedblocks;	/// get the end of progress number, only used block
    log_mesg(1, 0, 0, debug, "Initial Progress bar\n");
    /// Initial progress bar
    if (opt.no_block_detail)
	flag = NO_BLOCK_DETAIL;
    else
	flag = IO;
    progress_init(&prog, start, stop, image_hdr.totalblock, flag, image_hdr.block_size);
    copied = 0;

    /**
     * thread to print progress
     */
    pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL);

    /**
     * start read and write data between device and image file
     */

    /**
     * read magic string from image file
     * and check it.
     */
    r_size = read_all(&dfr, bitmagic_r, 8, &opt); /// read a magic string
    cmp = memcmp(bitmagic, bitmagic_r, 8);
    if(cmp != 0)
        log_mesg(0, 1, 1, debug, "bitmagic error %i\n", cmp);

    /// start restore image file to partition
    for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ){

        r_size = 0;

        if (pc_test_bit(block_id, bitmap)){
            /// The block is used
            log_mesg(2, 0, 0, debug, "block_id=%llu, ",block_id);
            log_mesg(1, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap));

            offset = (off_t)(block_id * image_hdr.block_size);
            buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data
            if(buffer == NULL){
                log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
            }
            r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt);
            log_mesg(1, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size);
            if (r_size <0)
                log_mesg(0, 1, 1, debug, "read errno = %i \n", errno);

            /// read crc32 code and check it.
            crc_ck = crc32(crc_ck, buffer, r_size);
            char crc_buffer[CRC_SIZE];
            c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt);
            if (c_size < CRC_SIZE){
                log_mesg(0, 0, 1, debug, "read CRC error, please check your image file. \n");
                log_mesg(0, 0, 1, debug, "read CRC size (%i), %s. \n", c_size, strerror(errno));
		lseek(dfr, (int)(CRC_SIZE-c_size), SEEK_CUR);
		}
            if ((memcmp(crc_buffer, &crc_ck, CRC_SIZE) != 0) && (!opt.ignore_crc)){
		log_mesg(1, 0, 0, debug, "Ignore_crc 2 %i\n ", opt.ignore_crc);

                log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), enlarge crc size and recheck again....\n ");
                /// check again
                buffer2 = (char*)malloc(image_hdr.block_size+CRC_SIZE); ///alloc a memory to copy data
                if(buffer2 == NULL){
                    log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno));
                }
                memcpy(buffer2, buffer, image_hdr.block_size);
                memcpy(buffer2+image_hdr.block_size, crc_buffer, CRC_SIZE);
                memcpy(buffer, buffer2+CRC_SIZE, image_hdr.block_size);

                crc_ck2 = crc32(crc_ck2, buffer, r_size);
                c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt);
                if (c_size < CRC_SIZE)
                    log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno));
                memcpy(&crc, crc_buffer, CRC_SIZE);
                if ((memcmp(&crc, &crc_ck2, CRC_SIZE) != 0) && (!opt.ignore_crc)){
                    log_mesg(0, 1, 1, debug, "CRC error again at %ji...\n ", (intmax_t)sf);
                } else {
                    crc_ck = crc_ck2;
                }
                free(buffer2);

            } else {
                crc_ck2 = crc_ck;
            }

            /// free buffer
            free(buffer);
            copied++;					/// count copied block
            log_mesg(1, 0, 0, debug, "end\n");
        }

	//update_pui(&prog, copied, block_id, done);
    } // end of for
    done = 1;
    pres = pthread_join(prog_thread, &p_result);
    update_pui(&prog, copied, block_id, done);
    print_finish_info(opt);

    close (dfr);    /// close source
    free(bitmap);   /// free bitmp
    close_pui(pui);
    printf("Checked successfully.\n");
    if(opt.debug)
        close_log();
    return 0;	    /// finish
}
Пример #30
0
/* 
 * Download firmware stored in buf to cam_dev. If simulation mode
 * is enabled, only show what packet sizes would be sent to the 
 * device but do not sent any actual packets
 */
static int
fw_download_img(struct cam_device *cam_dev, const struct fw_vendor *vp,
    char *buf, int img_size, int sim_mode, int printerrors, int retry_count,
    int timeout, const char *imgname, const char *type)
{
	struct scsi_write_buffer cdb;
	progress_t progress;
	int size;
	union ccb *ccb;
	int pkt_count = 0;
	int max_pkt_size;
	u_int32_t pkt_size = 0;
	char *pkt_ptr = buf;
	u_int32_t offset;
	int last_pkt = 0;
	int16_t *ptr;

	if ((ccb = cam_getccb(cam_dev)) == NULL) {
		warnx("Could not allocate CCB");
		return (1);
	}
	if (strcmp(type, "scsi") == 0) {
		scsi_test_unit_ready(&ccb->csio, 0, NULL, MSG_SIMPLE_Q_TAG,
		    SSD_FULL_SIZE, 5000);
	} else if (strcmp(type, "ata") == 0) {
		/* cam_getccb cleans up the header, caller has to zero the payload */
		bzero(&(&ccb->ccb_h)[1],
		      sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));

		ptr = (uint16_t *)malloc(sizeof(struct ata_params));

		if (ptr == NULL) {
			cam_freeccb(ccb);
			warnx("can't malloc memory for identify\n");
			return(1);
		}
		bzero(ptr, sizeof(struct ata_params));
		cam_fill_ataio(&ccb->ataio,
                      1,
                      NULL,
                      /*flags*/CAM_DIR_IN,
                      MSG_SIMPLE_Q_TAG,
                      /*data_ptr*/(uint8_t *)ptr,
                      /*dxfer_len*/sizeof(struct ata_params),
                      timeout ? timeout : 30 * 1000);
		ata_28bit_cmd(&ccb->ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
	} else {
		warnx("weird disk type '%s'", type);
		return 1;
	}
	/* Disable freezing the device queue. */
	ccb->ccb_h.flags |= CAM_DEV_QFRZDIS;
	if (cam_send_ccb(cam_dev, ccb) < 0) {
		warnx("Error sending identify/test unit ready");
		if (printerrors)
			cam_error_print(cam_dev, ccb, CAM_ESF_ALL,
			    CAM_EPF_ALL, stderr);
		cam_freeccb(ccb);
		return(1);
	}
	if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
		warnx("Device is not ready");
		if (printerrors)
			cam_error_print(cam_dev, ccb, CAM_ESF_ALL,
			    CAM_EPF_ALL, stderr);
		cam_freeccb(ccb);
		return (1);
	}
	max_pkt_size = vp->max_pkt_size;
	if (vp->max_pkt_size == 0 && strcmp(type, "ata") == 0) {
		max_pkt_size = UNKNOWN_MAX_PKT_SIZE;
	}
	pkt_size = vp->max_pkt_size;
	progress_init(&progress, imgname, size = img_size);
	/* Download single fw packets. */
	do {
		if (img_size <= max_pkt_size) {
			last_pkt = 1;
			pkt_size = img_size;
		}
		progress_update(&progress, size - img_size);
		progress_draw(&progress);
		bzero(&cdb, sizeof(cdb));
		if (strcmp(type, "scsi") == 0) {
			cdb.opcode  = WRITE_BUFFER;
			cdb.control = 0;
			/* Parameter list length. */
			scsi_ulto3b(pkt_size, &cdb.length[0]);
			offset = vp->inc_cdb_offset ? (pkt_ptr - buf) : 0;
			scsi_ulto3b(offset, &cdb.offset[0]);
			cdb.byte2 = last_pkt ? vp->cdb_byte2_last : vp->cdb_byte2;
			cdb.buffer_id = vp->inc_cdb_buffer_id ? pkt_count : 0;
			/* Zero out payload of ccb union after ccb header. */
			bzero((u_char *)ccb + sizeof(struct ccb_hdr),
			    sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
			/* Copy previously constructed cdb into ccb_scsiio struct. */
			bcopy(&cdb, &ccb->csio.cdb_io.cdb_bytes[0],
			    sizeof(struct scsi_write_buffer));
			/* Fill rest of ccb_scsiio struct. */
			if (!sim_mode) {
				cam_fill_csio(&ccb->csio,		/* ccb_scsiio	*/
				    retry_count,			/* retries	*/
				    NULL,				/* cbfcnp	*/
				    CAM_DIR_OUT | CAM_DEV_QFRZDIS,	/* flags	*/
				    CAM_TAG_ACTION_NONE,		/* tag_action	*/
				    (u_char *)pkt_ptr,			/* data_ptr	*/
				    pkt_size,				/* dxfer_len	*/
				    SSD_FULL_SIZE,			/* sense_len	*/
				    sizeof(struct scsi_write_buffer),	/* cdb_len	*/
				    timeout ? timeout : CMD_TIMEOUT);	/* timeout	*/
			}
		} else if (strcmp(type, "ata") == 0) {
			bzero(&(&ccb->ccb_h)[1],
			      sizeof(struct ccb_ataio) - sizeof(struct ccb_hdr));
			if (!sim_mode) {
				uint32_t	off;

				cam_fill_ataio(&ccb->ataio,
					(last_pkt) ? 256 : retry_count,
					NULL,
					/*flags*/CAM_DIR_OUT | CAM_DEV_QFRZDIS,
					CAM_TAG_ACTION_NONE,
					/*data_ptr*/(uint8_t *)pkt_ptr,
					/*dxfer_len*/pkt_size,
					timeout ? timeout : 30 * 1000);
				off = (uint32_t)(pkt_ptr - buf);
				ata_28bit_cmd(&ccb->ataio, ATA_DOWNLOAD_MICROCODE,
					USE_OFFSETS_FEATURE,
					ATA_MAKE_LBA(off, pkt_size),
					ATA_MAKE_SECTORS(pkt_size));
			}
		}
		if (!sim_mode) {
			/* Execute the command. */
			if (cam_send_ccb(cam_dev, ccb) < 0 ||
			    (ccb->ccb_h.status & CAM_STATUS_MASK) !=
			    CAM_REQ_CMP) {
				warnx("Error writing image to device");
				if (printerrors)
					cam_error_print(cam_dev, ccb, CAM_ESF_ALL,
						   CAM_EPF_ALL, stderr);
				goto bailout;
			}
		}
		/* Prepare next round. */
		pkt_count++;
		pkt_ptr += pkt_size;
		img_size -= pkt_size;
	} while(!last_pkt);
	progress_complete(&progress, size - img_size);
	cam_freeccb(ccb);
	return (0);
bailout:
	progress_complete(&progress, size - img_size);
	cam_freeccb(ccb);
	return (1);
}