Esempio n. 1
0
void
combine_entry(partition_map *entry)
{
    partition_map *p;
    u32 end;

    if (entry == NULL
	    || istrncmp(entry->data->dpme_type, kFreeType, DPISTRLEN) != 0) {
	return;
    }
    if (entry->next_by_base != NULL) {
	p = entry->next_by_base;
	if (istrncmp(p->data->dpme_type, kFreeType, DPISTRLEN) != 0) {
	    // next is not free
	} else if (entry->data->dpme_pblock_start + entry->data->dpme_pblocks
		!= p->data->dpme_pblock_start) {
	    // next is not contiguous (XXX this is bad)
	    printf("next entry is not contiguous\n");
	    // start is already minimum
	    // new end is maximum of two ends
	    end = p->data->dpme_pblock_start + p->data->dpme_pblocks;
	    if (end > entry->data->dpme_pblock_start + entry->data->dpme_pblocks) {
	    	entry->data->dpme_pblocks = end - entry->data->dpme_pblock_start;
	    }
	    entry->data->dpme_lblocks = entry->data->dpme_pblocks;
	    delete_entry(p);
	} else {
	    entry->data->dpme_pblocks += p->data->dpme_pblocks;
	    entry->data->dpme_lblocks = entry->data->dpme_pblocks;
	    delete_entry(p);
	}
    }
    if (entry->prev_by_base != NULL) {
	p = entry->prev_by_base;
	if (istrncmp(p->data->dpme_type, kFreeType, DPISTRLEN) != 0) {
	    // previous is not free
	} else if (p->data->dpme_pblock_start + p->data->dpme_pblocks
		!= entry->data->dpme_pblock_start) {
	    // previous is not contiguous (XXX this is bad)
	    printf("previous entry is not contiguous\n");
	    // new end is maximum of two ends
	    end = p->data->dpme_pblock_start + p->data->dpme_pblocks;
	    if (end < entry->data->dpme_pblock_start + entry->data->dpme_pblocks) {
		end = entry->data->dpme_pblock_start + entry->data->dpme_pblocks;
	    }
	    entry->data->dpme_pblocks = end - p->data->dpme_pblock_start;
	    // new start is previous entry's start
	    entry->data->dpme_pblock_start = p->data->dpme_pblock_start;
	    entry->data->dpme_lblocks = entry->data->dpme_pblocks;
	    delete_entry(p);
	} else {
	    entry->data->dpme_pblock_start = p->data->dpme_pblock_start;
	    entry->data->dpme_pblocks += p->data->dpme_pblocks;
	    entry->data->dpme_lblocks = entry->data->dpme_pblocks;
	    delete_entry(p);
	}
    }
    entry->contains_driver = contains_driver(entry);
}
Esempio n. 2
0
void
resize_map(unsigned long new_size, partition_map_header *map)
{
    partition_map * entry;
    partition_map * next;
    unsigned int incr;

    // find map entry
    entry = find_entry_by_type(kMapType, map);

    if (entry == NULL) {
	printf("Couldn't find entry for map!\n");
	return;
    }
    next = entry->next_by_base;

	// same size
    if (new_size == entry->data->dpme_pblocks) {
	// do nothing
	return;
    }

	// make it smaller
    if (new_size < entry->data->dpme_pblocks) {
	if (next == NULL
		|| istrncmp(next->data->dpme_type, kFreeType, DPISTRLEN) != 0) {
	    incr = 1;
	} else {
	    incr = 0;
	}
	if (new_size < map->blocks_in_map + incr) {
	    printf("New size would be too small\n");
	    return;
	}
	goto doit;
    }

	// make it larger
    if (next == NULL
	    || istrncmp(next->data->dpme_type, kFreeType, DPISTRLEN) != 0) {
	printf("No free space to expand into\n");
	return;
    }
    if (entry->data->dpme_pblock_start + entry->data->dpme_pblocks
	    != next->data->dpme_pblock_start) {
	printf("No contiguous free space to expand into\n");
	return;
    }
    if (new_size > entry->data->dpme_pblocks + next->data->dpme_pblocks) {
	printf("No enough free space\n");
	return;
    }
doit:
    entry->data->dpme_type[0] = 0;
    delete_partition_from_map(entry);
    add_partition_to_map("Apple", kMapType, 1, new_size, map);
    map->maximum_in_map = new_size;
}
Esempio n. 3
0
int
add_data_to_map(struct dpme *data, long ix, partition_map_header *map)
{
    partition_map *entry;

//printf("add data %d to map\n", ix);
    entry = (partition_map *) malloc(sizeof(partition_map));
    if (entry == NULL) {
	error(errno, "can't allocate memory for map entries");
	return 0;
    }
    entry->next_on_disk = NULL;
    entry->prev_on_disk = NULL;
    entry->next_by_base = NULL;
    entry->prev_by_base = NULL;
    entry->disk_address = ix;
    entry->the_map = map;
    entry->data = data;
    entry->contains_driver = contains_driver(entry);
    entry->HFS_name = get_HFS_name(entry, &entry->HFS_kind);

    insert_in_disk_order(entry);
    insert_in_base_order(entry);

    map->blocks_in_map++;
    if (map->maximum_in_map < 0) {
	if (istrncmp(data->dpme_type, kMapType, DPISTRLEN) == 0) {
	    map->maximum_in_map = data->dpme_pblocks;
	}
    }

    return 1;
}
Esempio n. 4
0
partition_map *
find_entry_by_type(const char *type_name, partition_map_header *map)
{
    partition_map * cur;

    cur = map->base_order;
    while (cur != NULL) {
	if (istrncmp(cur->data->dpme_type, type_name, DPISTRLEN) == 0) {
	    break;
	}
	cur = cur->next_by_base;
    }
    return cur;
}
Esempio n. 5
0
void
dpme_init_flags(DPME *data)
{
    if (istrncmp(data->dpme_type, kHFSType, DPISTRLEN) == 0) { /* XXX this is gross, fix it! */
	data->dpme_flags = APPLE_HFS_FLAGS_VALUE;
    }
    else {
	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, 1);
	dpme_valid_set(data, 1);
    }
}
Esempio n. 6
0
void
delete_partition_from_map(partition_map *entry)
{
    partition_map_header *map;
    DPME *data;

    if (istrncmp(entry->data->dpme_type, kMapType, DPISTRLEN) == 0) {
	printf("Can't delete entry for the map itself\n");
	return;
    }
    if (entry->contains_driver) {
	printf("This program can't install drivers\n");
	if (get_okay("are you sure you want to delete this driver? [n/y]: ", 0) != 1) {
	    return;
	}
    }
    // if past end of disk, delete it completely
    if (entry->next_by_base == NULL &&
	entry->data->dpme_pblock_start >= entry->the_map->media_size) {
      if (entry->contains_driver) {
	remove_driver(entry);	// update block0 if necessary
      }
      delete_entry(entry);
      return;
    }
    // If at end of disk, incorporate extra disk space to partition
    if (entry->next_by_base == NULL) {
      entry->data->dpme_pblocks =
	 entry->the_map->media_size - entry->data->dpme_pblock_start;
    }
    data = create_data(kFreeName, kFreeType,
	    entry->data->dpme_pblock_start, entry->data->dpme_pblocks);
    if (data == NULL) {
	return;
    }
    if (entry->contains_driver) {
    	remove_driver(entry);	// update block0 if necessary
    }
    free(entry->data);
    free(entry->HFS_name);
    entry->HFS_kind = kHFS_not;
    entry->HFS_name = 0;
    entry->data = data;
    combine_entry(entry);
    map = entry->the_map;
    renumber_disk_addresses(map);
    map->changed = 1;
}
Esempio n. 7
0
void
do_update_dpme(partition_map *entry)
{
    int slice = 0;
    if (!entry) return;
    dpme_init_flags(entry->data);
    entry->HFS_name = get_HFS_name(entry, &entry->HFS_kind);
    if (istrncmp(entry->data->dpme_type, kUnixType, DPISTRLEN) == 0) {
	printf("Available partition slices for %s:\n",entry->data->dpme_type);
	printf("  a   root partition\n");
	printf("  b   swap partition\n");
	printf("  c   do not set any bzb bits\n");
	printf("  g   user partition\n");
	printf("Other lettered values will create user partitions\n");
	get_command("Select a slice for default bzb values: ",0,&slice);
    }
    bzb_init_slice((BZB *)entry->data->dpme_bzb,slice);
    entry->the_map->changed = 1;
}
Esempio n. 8
0
int main() {
  char *str1 = istring_mk(NULL);
  char *str2 = istring_mk("Anders");  
  char *str3 = istring_mk("Alander");  
  char *str4 = istring_mk(" ");  
  char *str9 = istring_to_string(str2);
  char *str5 = istrcat(str9,str4);  
  char *str11 = istring_to_string(str5);
  char *str6 = istrcat(str11, str3);
  char *str7 = istring_to_string(str6);
  char *str8 = istring_mk("Erik");
  char *str10 = istring_to_string(str5);
  char *str12 = "Anders Ålander";
  char *str13 = istrncat(str9, str3,2);

  printf("An empty istring has length %zu\n", istrlen(str1));
  printf("My first name is %s\n",str2);
  printf("My last  name is %s\n",str3);
  printf("My name concatenated is %s\n", str6);
  printf("%s concatenated with the first %d chars from %s is %s\n", str2, 2, str3, str13);
  printf("%s has length %zu\n", str6, istrlen(str6));
  printf("%s is my name stored as normal string, it also has length %zu\n", str7, strlen(str7));
  printf("An istring's length can be changed without touching the string itself. %s has length %zu\n", str2, istrlen(str2));
  str2 = istrslen(str2, 15);
  printf("but we can change it to %zu\n", istrlen(str2));
  printf("Returns a pointer to the first given character in %s, for example a pointer to 's'gives %s\n", str2, istrchr(str2,'s'));
  printf("Same as above but from the end of %s. Pointer to 's' gives %s\n", str2, istrrchr(str2, 's'));
  printf("Are the strings %s and %s equal? %s\n", str2, str3, istrcmp(str2,str3)?"no":"yes");
  printf("Which one of %s and %s is greatest? %s\n", str2, str3, istrcmp(str2,str3)<0?str2:str3);
  printf("Compares the first %d characters in %s and %s. The substring of %s is greatest\n", 3, str2, str3, istrncmp(str2, str3, 3) > 0?str3:str2);
  printf("The result of copying %s into %s is %s\n", str8, str12, istrcpy(str7, str8));
  printf("The result of copying %d chars from %s into %s is %s\n", 3, str8, str12, istrncpy(str7,str8,3));

  istring_rm(str1);
  istring_rm(str2);
  istring_rm(str3);
  istring_rm(str4);
  istring_rm(str5);
  istring_rm(str6);
  free(str7);
  istring_rm(str8);
  free(str9);
  free(str10);
  free(str11);
  istring_rm(str13);
  return 0;
}
Esempio n. 9
0
void
do_create_partition(partition_map_header *map, int get_type)
{
    long base;
    long length;
    char *name = 0;
    char *type_name = 0;

    if (map == NULL) {
	bad_input("No partition map exists");
	return;
    }
    if (!rflag && map->writable == 0) {
	printf("The map is not writable.\n");
    }
// XXX add help feature (i.e. '?' in any argument routine prints help string)
    if (get_base_argument(&base, map) == 0) {
	return;
    }
    if (get_size_argument(&length, map) == 0) {
	return;
    }

    if (get_string_argument("Name of partition: ", &name, 1) == 0) {
	bad_input("Bad name");
	return;
    }
    if (get_type == 0) {
	add_partition_to_map(name, kUnixType, base, length, map);
#if 0 /* this check is not found in linux fdisk-0.1 */
	if (map->blocks_in_map > MAX_LINUX_MAP) {
	    error(-1, "Map contains more than %d blocks - Linux may have trouble", MAX_LINUX_MAP);
	}
	goto xit1;
#endif
    } else if (get_string_argument("Type of partition: ", &type_name, 1) == 0) {
	bad_input("Bad type");
	goto xit1;
    } else {
	if (istrncmp(type_name, kFreeType, DPISTRLEN) == 0) {
	    bad_input("Can't create a partition with the Free type");
	    goto xit2;
	}
	if (istrncmp(type_name, kMapType, DPISTRLEN) == 0) {
	    bad_input("Can't create a partition with the Map type");
	    goto xit2;
	}
	add_partition_to_map(name, type_name, base, length, map);
#if 0 /* this check is not found in linux fdisk-0.1 */
	if (map->blocks_in_map > MAX_LINUX_MAP) {
	    error(-1, "Map contains more than %d blocks - Linux may have trouble", MAX_LINUX_MAP);
	}
#endif
    }
    do_update_dpme(find_entry_by_base(base,map));
xit2:
    if (type_name)
        free(type_name);
xit1:
    if (name)
        free(name);
    return;
}
Esempio n. 10
0
int
add_partition_to_map(const char *name, const char *dptype, u32 base, u32 length,
	partition_map_header *map)
{
    partition_map * cur;
    DPME *data;
    enum add_action act;
    int limit;
    u32 adjusted_base = 0;
    u32 adjusted_length = 0;
    u32 new_base = 0;
    u32 new_length = 0;

	// find a block that starts includes base and length
    cur = map->base_order;
    while (cur != NULL) {
	if (cur->data->dpme_pblock_start <= base 
		&& (base + length) <=
		    (cur->data->dpme_pblock_start + cur->data->dpme_pblocks)) {
	    break;
	} else {
	  // check if request is past end of existing partitions, but on disk
	  if ((cur->next_by_base == NULL) &&
	      (base + length <= map->media_size)) {
	    // Expand final free partition
	    if ((istrncmp(cur->data->dpme_type, kFreeType, DPISTRLEN) == 0) &&
		base >= cur->data->dpme_pblock_start) {
	      cur->data->dpme_pblocks =
		map->media_size - cur->data->dpme_pblock_start;
	      break;
	    }
	    // create an extra free partition
	    if (base >= cur->data->dpme_pblock_start + cur->data->dpme_pblocks) {
	      if (map->maximum_in_map < 0) {
		limit = map->media_size;
	      } else {
		limit = map->maximum_in_map;
	      }
	      if (map->blocks_in_map + 1 > limit) {
		printf("the map is not big enough\n");
		return 0;
	      }
	      data = create_data(kFreeName, kFreeType,
		  cur->data->dpme_pblock_start + cur->data->dpme_pblocks,
		  map->media_size - (cur->data->dpme_pblock_start + cur->data->dpme_pblocks));
	      if (data != NULL) {
		if (add_data_to_map(data, cur->disk_address, map) == 0) {
		  free(data);
		}
	      }
	    }
	  }
	  cur = cur->next_by_base;
	}
    }
	// if it is not Extra then punt
    if (cur == NULL
	    || istrncmp(cur->data->dpme_type, kFreeType, DPISTRLEN) != 0) {
	printf("requested base and length is not "
		"within an existing free partition\n");
	return 0;
    }
	// figure out what to do and sizes
    data = cur->data;
    if (data->dpme_pblock_start == base) {
	// replace or add
	if (data->dpme_pblocks == length) {
	    act = kReplace;
	} else {
	    act = kAdd;
	    adjusted_base = base + length;
	    adjusted_length = data->dpme_pblocks - length;
	}
    } else {
	// split or add
	if (data->dpme_pblock_start + data->dpme_pblocks == base + length) {
	    act = kAdd;
	    adjusted_base = data->dpme_pblock_start;
	    adjusted_length = base - adjusted_base;
	} else {
	    act = kSplit;
	    new_base = data->dpme_pblock_start;
	    new_length = base - new_base;
	    adjusted_base = base + length;
	    adjusted_length = data->dpme_pblocks - (length + new_length);
	}
    }
	// if the map will overflow then punt
    if (map->maximum_in_map < 0) {
	limit = map->media_size;
    } else {
	limit = map->maximum_in_map;
    }
    if (map->blocks_in_map + (int)act > limit) {
	printf("the map is not big enough\n");
	return 0;
    }

    data = create_data(name, dptype, base, length);
    if (data == NULL) {
	return 0;
    }
    if (act == kReplace) {
	free(cur->data);
	cur->data = data;
    } else {
	    // adjust this block's size
	cur->data->dpme_pblock_start = adjusted_base;
	cur->data->dpme_pblocks = adjusted_length;
	cur->data->dpme_lblocks = adjusted_length;
	    // insert new with block address equal to this one
	if (add_data_to_map(data, cur->disk_address, map) == 0) {
	    free(data);
	} else if (act == kSplit) {
	    data = create_data(kFreeName, kFreeType, new_base, new_length);
	    if (data != NULL) {
		    // insert new with block address equal to this one
		if (add_data_to_map(data, cur->disk_address, map) == 0) {
		    free(data);
		}
	    }
	}
    }
	// renumber disk addresses
    renumber_disk_addresses(map);
	// mark changed
    map->changed = 1;
    return 1;
}