Example #1
0
long
close_deblock_media(MEDIA m)
{
    DEBLOCK_MEDIA a;
    
    a = (DEBLOCK_MEDIA) m;
    if (a == 0) {
	return 0;
    } else if (a->m.kind != deblock_info.kind) {
	/* XXX need to error here - this is an internal problem */
	return 0;
    }
    
    close_media(a->next_media);
    free(a->buffer);
    return 1;
}
Example #2
0
void
close_partition_map(partition_map_header *map)
{
    partition_map * entry;
    partition_map * next;

    if (map == NULL) {
	return;
    }

    free(map->misc);

    for (entry = map->disk_order; entry != NULL; entry = next) {
	next = entry->next_on_disk;
	free(entry->data);
	free(entry);
    }
    close_media(map->fd);
    free(map);
}
Example #3
0
void
list_all_disks(void)
{
    MEDIA_ITERATOR iter;
    MEDIA m;
    DPME * data;
    char *name;
    long mark;

    data = (DPME *) malloc(PBLOCK_SIZE);
    if (data == NULL) {
	error(errno, "can't allocate memory for try buffer");
	return;
    }
    
    for (iter = first_media_kind(&mark); iter != 0; iter = next_media_kind(&mark)) {

    	while ((name = step_media_iterator(iter)) != 0) {

	    if ((m = open_pathname_as_media(name, O_RDONLY)) == 0) {
#if defined(__linux__) || defined(__unix__)
		error(errno, "can't open file '%s'", name);
#endif
	    } else {
		close_media(m);

		dump(name);
	    }
	    free(name);
	}

	delete_media_iterator(iter);
    }

    free(data);
}
Example #4
0
void
validate_map(partition_map_header *map)
{
    range_list *list;
    char *name;
    unsigned int i;
    u32 limit;
    int printed;
    
    //printf("Validation not implemented yet.\n");
    
    if (map == NULL) {
    	the_map = 0;
	if (get_string_argument("Name of device: ", &name, 1) == 0) {
	    bad_input("Bad name");
	    return;
	}
	the_media = open_pathname_as_media(name, O_RDONLY);
	if (the_media == 0) {
	    error(errno, "can't open file '%s'", name);
	    free(name);
	    return;
	}
	g = media_granularity(the_media);
	if (g < PBLOCK_SIZE) {
	    g = PBLOCK_SIZE;
	}
   	the_media = open_deblock_media(PBLOCK_SIZE, the_media);

	buffer = malloc(PBLOCK_SIZE);
	if (buffer == NULL) {
	    error(errno, "can't allocate memory for disk buffer");
	    goto done;
	}

    } else {
    	name = 0;
	the_map = map;
	g = map->logical_block;
    }

    initialize_list(&list);

    // get block 0
    if (get_block_zero() == 0) {
	printf("unable to read block 0\n");
	goto check_map;
    }
    // XXX signature valid
    // XXX size & count match DeviceCapacity
    // XXX number of descriptors matches array size
    // XXX each descriptor wholly contained in a partition
    // XXX the range below here is in physical blocks but the map is in logical blocks!!!
    add_range(&list, 1, b0->sbBlkCount-1, 0);	/* subtract one since args are base & len */

check_map:
    // compute size of map
    if (map != NULL) {
	limit = the_map->blocks_in_map;
    } else {
	if (get_block_n(1) == 0) {
	    printf("unable to get first block\n");
	    goto done;
	} else {
	    if (mb->dpme_signature != DPME_SIGNATURE) {
	        limit = -1;
	    } else {
		limit = mb->dpme_map_entries;
	    }
	}
    }

    // for each entry
    for (i = 1; ; i++) {
#if 0
	if (limit < 0) {
	    /* XXX what to use for end of list? */
	    if (i > 5) {
	    	break;
	    }
	} else
#endif
	if (i > limit) {
	    break;
	}

	printf("block %d:\n", i);

	// get entry
	if (get_block_n(i) == 0) {
	    printf("\tunable to get\n");
	    goto post_processing;
	}
	printed = 0;
	
	// signature matches
	if (mb->dpme_signature != DPME_SIGNATURE) {
	    printed = 1;
	    printf("\tsignature is 0x%x, should be 0x%x\n", mb->dpme_signature, DPME_SIGNATURE);
	}
	// reserved1 == 0
	if (mb->dpme_reserved_1 != 0) {
	    printed = 1;
	    printf("\treserved word is 0x%x, should be 0\n", mb->dpme_reserved_1);
	}
	// entry count matches
#if 0
	if (limit < 0) {
	    printed = 1;
	    printf("\tentry count is 0x%lx, real value unknown\n", mb->dpme_map_entries);
	} else
#endif
	if (mb->dpme_map_entries != limit) {
	    printed = 1;
	    printf("\tentry count is 0x%lx, should be %ld\n", mb->dpme_map_entries, limit);
	}
	// lblocks contained within physical
	if (mb->dpme_lblock_start >= mb->dpme_pblocks
		|| mb->dpme_lblocks > mb->dpme_pblocks - mb->dpme_lblock_start) {
	    printed = 1;
	    printf("\tlogical blocks (%ld for %ld) not within physical size (%ld)\n",
		    mb->dpme_lblock_start, mb->dpme_lblocks, mb->dpme_pblocks);
	}
	// remember stuff for post processing
	add_range(&list, mb->dpme_pblock_start, mb->dpme_pblocks, 1);
	
	// XXX type is known type?
	// XXX no unknown flags?
	// XXX boot blocks either within or outside of logical
	// XXX checksum matches contents
	// XXX other fields zero if boot_bytes  is zero
	// XXX processor id is known value?
	// XXX no data in reserved3
	if (printed == 0) {
	    printf("\tokay\n");
	}
    }

post_processing:
    // properties of whole map
    
    // every block on disk in one & only one partition
    coalesce_list(list);
    print_range_list(list);
    // there is a partition for the map
    // map fits within partition that contains it
    
    // try to detect 512/2048 mixed partition map?

done:
    if (map == NULL) {
	close_media(the_media);
	free(buffer);
	free(name);
    }
}
Example #5
0
partition_map_header *
create_partition_map(char *name, partition_map_header *oldmap)
{
    media *fd;
    partition_map_header * map;
    DPME *data;
    unsigned long number;
    int size;
#ifdef __linux__
    struct stat info;
#endif

    fd = open_media(name, (rflag)?O_RDONLY:O_RDWR);
    if (fd == 0) {
	error(errno, "can't open file '%s' for %sing", name,
		(rflag)?"read":"writ");
	return NULL;
    }

    map = (partition_map_header *) malloc(sizeof(partition_map_header));
    if (map == NULL) {
	error(errno, "can't allocate memory for open partition map");
	close_media(fd);
	return NULL;
    }
    map->fd = fd;
    map->name = name;
    map->writeable = (rflag)?0:1;
    map->changed = 1;
    map->disk_order = NULL;
    map->base_order = NULL;

    if (oldmap != NULL) {
	size = oldmap->physical_block;
    } else {
	size = fd->block_size;
	if (interactive) {
	    printf("A physical block is %d bytes: ", size);
	    flush_to_newline(0);
	    get_number_argument("what should be the physical block size? ",
		    (long *)&size, size);
	    size = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
	}
    }
    map->physical_block = size;
    // printf("block size is %d\n", map->physical_block);

    if (oldmap != NULL) {
	size = oldmap->logical_block;
    } else {
	size = PBLOCK_SIZE;
	if (interactive) {
	    printf("A logical block is %d bytes: ", size);
	    flush_to_newline(0);
	    get_number_argument("what should be the logical block size? ",
		    (long *)&size, size);
	    size = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
	}
    }
    map->logical_block = size;
    if (map->logical_block > MAXIOSIZE) {
	map->logical_block = MAXIOSIZE;
    }
    if (map->logical_block > map->physical_block) {
	map->physical_block = map->logical_block;
    }
    map->blocks_in_map = 0;
    map->maximum_in_map = -1;

    number = compute_device_size(map, oldmap);
    if (interactive) {
	printf("size of 'device' is %lu blocks (%d byte blocks): ",
		number, map->logical_block);
	flush_to_newline(0);
	get_number_argument("what should be the size? ", 
			    (long *)&number, number);
	if (number < 4) {
	    number = 4;
	}
	printf("new size of 'device' is %lu blocks (%d byte blocks)\n",
		number, map->logical_block);
    }
    map->media_size = number;

#ifdef __linux__
    if (fstat(fd, &info) < 0) {
	error(errno, "can't stat file '%s'", name);
	map->regular_file = 0;
    } else {
	map->regular_file = S_ISREG(info.st_mode);
    }
#else
    map->regular_file = 0;
#endif

    map->misc = (Block0 *) malloc(PBLOCK_SIZE);
    if (map->misc == NULL) {
	error(errno, "can't allocate memory for block zero buffer");
    } else {
	// got it!
	coerce_block0(map);
	sync_device_size(map);
	
	data = (DPME *) calloc(1, PBLOCK_SIZE);
	if (data == NULL) {
	    error(errno, "can't allocate memory for disk buffers");
	} else {
	    // set data into entry
	    data->dpme_signature = DPME_SIGNATURE;
	    data->dpme_map_entries = 1;
	    data->dpme_pblock_start = 1;
	    data->dpme_pblocks = map->media_size - 1;
	    strncpy(data->dpme_name, kFreeName, DPISTRLEN);
	    strncpy(data->dpme_type, kFreeType, DPISTRLEN);
	    data->dpme_lblock_start = 0;
	    data->dpme_lblocks = data->dpme_pblocks;
	    dpme_writable_set(data, 1);
	    dpme_readable_set(data, 1);
	    dpme_bootable_set(data, 0);
	    dpme_in_use_set(data, 0);
	    dpme_allocated_set(data, 0);
	    dpme_valid_set(data, 1);

	    if (add_data_to_map(data, 1, map) == 0) {
		free(data);
	    } else {
		return map;
	    }
	}
    }
    close_partition_map(map);
    return NULL;
}
Example #6
0
void
write_partition_map(partition_map_header *map)
{
    int fd;
    char *block;
    partition_map * entry;
    int i = 0;

    fd = map->fd->fd;
    if (map->misc != NULL) {
	convert_block0(map->misc, 0);
	write_block(map, 0, (char *)map->misc);
	convert_block0(map->misc, 1);
    } else {
	block = (char *) calloc(1, PBLOCK_SIZE);
	if (block != NULL) {
	    write_block(map, 0, block);
	    free(block);
	}
    }
    for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
	convert_dpme(entry->data, 0);
	write_block(map, entry->disk_address, (char *)entry->data);
	convert_dpme(entry->data, 1);
	i = entry->disk_address;
    }

#ifdef __linux__
	// zap the block after the map (if possible) to get around a bug.
    if (map->maximum_in_map > 0 &&  i < map->maximum_in_map) {
	i += 1;
	block = (char *) malloc(PBLOCK_SIZE);
	if (block != NULL) {
	    if (read_block(map, i, block, 1)) {
		block[0] = 0;
		write_block(map, i, block);
	    }
	    free(block);
	}
    }
#endif /* __linux __ */

    if (interactive)
	printf("The partition table has been altered!\n\n");

#ifdef __linux__
    if (map->regular_file) {
	close_media(map->fd);
    } else {
	// printf("Calling ioctl() to re-read partition table.\n"
	//       "(Reboot to ensure the partition table has been updated.)\n");
	sync();
	sleep(2);
	if ((i = ioctl(fd, BLKRRPART)) != 0) {
	    saved_errno = errno;
	} else {
	    // some kernel versions (1.2.x) seem to have trouble
	    // rereading the partition table, but if asked to do it
	    // twice, the second time works. - [email protected] */
	    sync();
	    sleep(2);
	    if ((i = ioctl(fd, BLKRRPART)) != 0) {
		saved_errno = errno;
	    }
	}
	close_media(map->fd);

	// printf("Syncing disks.\n");
	sync();
	sleep(4);		/* for sync() */

	if (i < 0) {
	    error(saved_errno, "Re-read of partition table failed");
	    printf("Reboot your system to ensure the "
		    "partition table is updated.\n");
	}
    }
#else
    close_media(map->fd);
#endif
    map->fd = open_media(map->name, (map->writeable)?O_RDWR:O_RDONLY);
    if (map->fd == 0) {
	fatal(errno, "can't re-open file '%s' for %sing", map->name,
		(rflag)?"read":"writ");
    }

}
Example #7
0
//
// Routines
//
partition_map_header *
open_partition_map(char *name, int *valid_file, int ask_logical_size)
{
    media *fd;
    partition_map_header * map;
    int writeable;
#ifdef __linux__
    struct stat info;
#endif
    int size;

    fd = open_media(name, (rflag)?O_RDONLY:O_RDWR);
    if (fd == 0) {
	fd = open_media(name, O_RDONLY);
	if (fd == 0) {
	    error(errno, "can't open file '%s'", name);
	    *valid_file = 0;
	    return NULL;
	} else {
	    writeable = 0;
	}
    } else {
	writeable = 1;
    }
    *valid_file = 1;

    map = (partition_map_header *) malloc(sizeof(partition_map_header));
    if (map == NULL) {
	error(errno, "can't allocate memory for open partition map");
	close_media(fd);
	return NULL;
    }
    map->fd = fd;
    map->name = name;
    map->writeable = (rflag)?0:writeable;
    map->changed = 0;
    map->disk_order = NULL;
    map->base_order = NULL;

    map->physical_block = fd->block_size;	/* preflight */
    map->misc = (Block0 *) malloc(PBLOCK_SIZE);
    if (map->misc == NULL) {
	error(errno, "can't allocate memory for block zero buffer");
	close_media(map->fd);
	free(map);
	return NULL;
    } else if (read_media(map->fd, 0, (char *)map->misc, 0) == 0
	    || convert_block0(map->misc, 1)
	    || coerce_block0(map)) {
	// if I can't read block 0 I might as well give up
	close_partition_map(map);
	return NULL;
    }
    map->physical_block = map->misc->sbBlkSize;
    // printf("physical block size is %d\n", map->physical_block);

    if (ask_logical_size && interactive) {
	size = PBLOCK_SIZE;
	printf("A logical block is %d bytes: ", size);
	flush_to_newline(0);
	get_number_argument("what should be the logical block size? ",
		(long *)&size, size);
	map->logical_block = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
    } else {
	map->logical_block = PBLOCK_SIZE;
    }
    if (map->logical_block > MAXIOSIZE) {
	map->logical_block = MAXIOSIZE;
    }
    if (map->logical_block > map->physical_block) {
	map->physical_block = map->logical_block;
    }
    map->blocks_in_map = 0;
    map->maximum_in_map = -1;
    map->media_size = compute_device_size(map, map);
    sync_device_size(map);

#ifdef __linux__
    if (fstat(fd, &info) < 0) {
	error(errno, "can't stat file '%s'", name);
	map->regular_file = 0;
    } else {
	map->regular_file = S_ISREG(info.st_mode);
    }
#else
    map->regular_file = 0;
#endif

    if (read_partition_map(map) < 0) {
	// some sort of failure reading the map
    } else {
	// got it!
	;
	return map;
    }
    close_partition_map(map);
    return NULL;
}
Example #8
0
void
do_display_block(partition_map_header *map, char *alt_name)
{
    MEDIA m;
    long number;
    char *name;
    static unsigned char *display_block;
    static int display_g;
    int g;
    static long next_number = -1;

    if (map != NULL) {
    	name = 0;
	m = map->m;
	g = map->logical_block;
    } else {
	if (alt_name == 0) {
	    if (get_string_argument("Name of device: ", &name, 1) == 0) {
		bad_input("Bad name");
		return;
	    }
	} else {
	    name = strdup(alt_name);
	}
	m = open_pathname_as_media(name, O_RDONLY);
	if (m == 0) {
	    error(errno, "can't open file '%s'", name);
	    free(name);
	    return;
	}
	g = media_granularity(m);
	if (g < PBLOCK_SIZE) {
	    g = PBLOCK_SIZE;
	}
    }
    if (get_number_argument("Block number: ", &number, next_number) == 0) {
	bad_input("Bad block number");
	goto xit;
    }
    if (display_block == NULL || display_g < g) {
    	if (display_block != NULL) {
    	    free(display_block);
    	    display_g = 0;
	}
	display_block = (unsigned char *) malloc(g);
	if (display_block == NULL) {
	    error(errno, "can't allocate memory for display block buffer");
	    goto xit;
	}
	display_g = g;
    }
    if (read_media(m, ((long long)number) * g, g, (char *)display_block) != 0) {
	printf("block %ld -", number);
	dump_block((unsigned char*) display_block, g);
	next_number = number + 1;
    }

xit:
    if (name) {
	close_media(m);
	free(name);
    }
    return;
}
Example #9
0
partition_map_header *
create_partition_map(char *name, partition_map_header *oldmap, int oflag)
{
    MEDIA m;
    partition_map_header * map;
    DPME *data;
    unsigned long default_number;
    unsigned long number;
    long size;
    unsigned long multiple;

    m = open_pathname_as_media(name, oflag);
    if (m == 0) {
	error(errno, "can't open file '%s' for %sing", name,
		(oflag == O_RDONLY)?"read":"writ");
	return NULL;
    }

    map = (partition_map_header *) malloc(sizeof(partition_map_header));
    if (map == NULL) {
	error(errno, "can't allocate memory for open partition map");
	close_media(m);
	return NULL;
    }
    map->name = name;
    map->writable = (oflag == O_RDONLY)?0:1;
    map->changed = 1;
    map->disk_order = NULL;
    map->base_order = NULL;

    if (oldmap != NULL) {
	size = oldmap->physical_block;
    } else {
	size = media_granularity(m);
    }
    m = open_deblock_media(PBLOCK_SIZE, m);
    map->m = m;
    if (interactive) {
	printf("A physical block is %ld bytes: ", size);
	flush_to_newline(0);
	get_number_argument("what should be the physical block size? ",
		&size, size);
	size = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
	if (size < PBLOCK_SIZE) {
	    size = PBLOCK_SIZE;
	}
    }
    if (map->physical_block > MAXIOSIZE) {
	map->physical_block = MAXIOSIZE;
    }
    map->physical_block = size;
    // printf("block size is %d\n", map->physical_block);

    if (oldmap != NULL) {
	size = oldmap->logical_block;
    } else {
	size = PBLOCK_SIZE;
    }
    if (interactive) {
	printf("A logical block is %ld bytes: ", size);
	flush_to_newline(0);
	get_number_argument("what should be the logical block size? ",
		&size, size);
	size = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
	if (size < PBLOCK_SIZE) {
	    size = PBLOCK_SIZE;
	}
    }
#if 0
    if (size > map->physical_block) {
	size = map->physical_block;
    }
#endif
    map->logical_block = size;

    map->blocks_in_map = 0;
    map->maximum_in_map = -1;

    number = compute_device_size(map, oldmap);
    if (interactive) {
	printf("size of 'device' is %lu blocks (%d byte blocks): ",
		number, map->logical_block);
	default_number = number;
	flush_to_newline(0);
	do {
	    if (get_number_argument("what should be the size? ", 
		    (long *)&number, default_number) == 0) {
		printf("Not a number\n");
		flush_to_newline(1);
		number = 0;
	    } else {
		multiple = get_multiplier(map->logical_block);
		if (multiple == 0) {
		    printf("Bad multiplier\n");
		    number = 0;
		} else if (multiple != 1) {
		    if (0xFFFFFFFF/multiple < number) {
			printf("Number too large\n");
			number = 0;
		    } else {
			number *= multiple;
		    }
		}
	    }
	    default_number = kDefault;
	} while (number == 0);

	if (number < 4) {
	    number = 4;
	}
	printf("new size of 'device' is %lu blocks (%d byte blocks)\n",
		number, map->logical_block);
    }
    map->media_size = number;

    map->misc = (Block0 *) calloc(1, PBLOCK_SIZE);
    if (map->misc == NULL) {
	error(errno, "can't allocate memory for block zero buffer");
    } else {
	// got it!
	coerce_block0(map);
	sync_device_size(map);
	
	data = (DPME *) calloc(1, PBLOCK_SIZE);
	if (data == NULL) {
	    error(errno, "can't allocate memory for disk buffers");
	} else {
	    // set data into entry
	    data->dpme_signature = DPME_SIGNATURE;
	    data->dpme_map_entries = 1;
	    data->dpme_pblock_start = 1;
	    data->dpme_pblocks = map->media_size - 1;
	    strncpy(data->dpme_name, kFreeName, DPISTRLEN);
	    strncpy(data->dpme_type, kFreeType, DPISTRLEN);
	    data->dpme_lblock_start = 0;
	    data->dpme_lblocks = data->dpme_pblocks;
	    dpme_writable_set(data, 1);
	    dpme_readable_set(data, 1);
	    dpme_bootable_set(data, 0);
	    dpme_in_use_set(data, 0);
	    dpme_allocated_set(data, 0);
	    dpme_valid_set(data, 1);

	    if (add_data_to_map(data, 1, map) == 0) {
		free(data);
	    } else {
		return map;
	    }
	}
    }
    close_partition_map(map);
    return NULL;
}
Example #10
0
//
// Routines
//
partition_map_header *
open_partition_map(char *name, int *valid_file, int ask_logical_size, int oflag)
{
    MEDIA m;
    partition_map_header * map;
    int writable;
    long size;

    m = open_pathname_as_media(name, oflag);
    if (m == 0) {
	m = open_pathname_as_media(name, O_RDONLY);
	if (m == 0) {
	    error(errno, "can't open file '%s'", name);
	    *valid_file = 0;
	    return NULL;
	} else {
	    writable = 0;
	}
    } else {
	writable = 1;
    }
    *valid_file = 1;

    map = (partition_map_header *) malloc(sizeof(partition_map_header));
    if (map == NULL) {
	error(errno, "can't allocate memory for open partition map");
	close_media(m);
	return NULL;
    }
    map->name = name;
    map->writable = (oflag == O_RDONLY)?0:writable;
    map->changed = 0;
    map->written = 0;
    map->disk_order = NULL;
    map->base_order = NULL;

    map->physical_block = media_granularity(m);	/* preflight */
    m = open_deblock_media(PBLOCK_SIZE, m);
    map->m = m;
    map->misc = (Block0 *) malloc(PBLOCK_SIZE);
    if (map->misc == NULL) {
	error(errno, "can't allocate memory for block zero buffer");
	close_media(map->m);
	free(map);
	return NULL;
    } else if (read_media(map->m, (long long) 0, PBLOCK_SIZE, (char *)map->misc) == 0
	    || convert_block0(map->misc, 1)
	    || coerce_block0(map)) {
	// if I can't read block 0 I might as well give up
	error(-1, "Can't read block 0 from '%s'", name);
	close_partition_map(map);
	return NULL;
    }
    map->physical_block = map->misc->sbBlkSize;
    //printf("physical block size is %d\n", map->physical_block);

    if (ask_logical_size && interactive) {
	size = PBLOCK_SIZE;
	printf("A logical block is %ld bytes: ", size);
	flush_to_newline(0);
	get_number_argument("what should be the logical block size? ",
		&size, size);
	size = (size / PBLOCK_SIZE) * PBLOCK_SIZE;
	if (size < PBLOCK_SIZE) {
	    size = PBLOCK_SIZE;
	}
	map->logical_block = size;
    } else {
	map->logical_block = PBLOCK_SIZE;
    }
    if (map->logical_block > MAXIOSIZE) {
	map->logical_block = MAXIOSIZE;
    }
    if (map->logical_block > map->physical_block) {
	map->physical_block = map->logical_block;
    }
    map->blocks_in_map = 0;
    map->maximum_in_map = -1;
    map->media_size = compute_device_size(map, map);

    if (read_partition_map(map) < 0) {
	// some sort of failure reading the map
    } else {
	// got it!
	;
	return map;
    }
    close_partition_map(map);
    return NULL;
}