acorn-fdisk-3.0.6.orig/0042755000000000000000000000000007373253470013375 5ustar rootrootacorn-fdisk-3.0.6.orig/Makefile0100644000000000000000000000150506722736123015027 0ustar rootrootSTRIP =strip #CFLAGS =-DUNIX -DVERSION=\"$(VERSION)\" -O2 -Wall -fomit-frame-pointer -Ilib -pipe CFLAGS =-DUNIX -DVERSION=\"$(VERSION)\" -O2 -Wall -g -Ilib -pipe LDFLAGS =-N LIBS =lib/part.a lib/scheme.a lib/blkio.a lib/util.a TAR =tar VERSION =3.0.6 FDISKOBJS =fdisk.o #partitions.o utils.o all: fdisk clean:; $(RM) fdisk *.o @$(MAKE) $@ -C lib/part @$(MAKE) $@ -C lib/scheme @$(MAKE) $@ -C lib/blkio @$(MAKE) $@ -C lib/util tar: clean (cd ..; $(TAR) zcf arm-fdisk-$(VERSION).tar.gz arm-fdisk-$(VERSION)) fdisk: $(FDISKOBJS) $(LIBS) $(CC) $(LDFLAGS) -o $@ $(FDISKOBJS) $(LIBS) $(STRIP) --discard-locals $@ .PHONY: lib/part.a lib/scheme.a lib/blkio.a lib/util.a lib/part.a:; @$(MAKE) -C lib/part lib/scheme.a:; @$(MAKE) -C lib/scheme lib/blkio.a:; @$(MAKE) -C lib/blkio lib/util.a:; @$(MAKE) -C lib/util acorn-fdisk-3.0.6.orig/fdisk.c0100644000000000000000000012355506721535402014641 0ustar rootroot/* * Changelog: * 25/03/1998 RMK Added option for selecting partitioning scheme */ #include #include #include #include #include #include #include #include #include #include #include #include #include "part/part.h" #include "util/error.h" #define NR_DEVICES 12 #define DEFAULT_DEVICE "/dev/hda" #define ALTERNATE_DEVICE "/dev/sda" static const char *part_devs[NR_DEVICES] = { "/dev/hda", "/dev/hdb", "/dev/hdc", "/dev/hdd", "/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd", "/dev/sde", "/dev/sdf", "/dev/sdg", "/dev/sdh" }; #if 1 #include static const char *device; static const char *progname; static const char *dev_part_type = ""; static part_t *part; typedef enum { mode_partition, mode_version, mode_help, mode_list, mode_size, mode_illegal } prog_mode_t; static struct option options[] = { { "help", no_argument, NULL, 'h' }, { "list", no_argument, NULL, 'l' }, { "size", required_argument, NULL, 's' }, { "type", required_argument, NULL, 't' }, { "version", no_argument, NULL, 'v' }, { NULL, no_argument, NULL, 0 } }; #define is_extended(x) ((x) == ptyp_dos_extended || (x) == ptyp_linux_extended) static prog_mode_t parse_args(int argc, char *argv[]) { prog_mode_t mode = mode_partition; int opt; do { opt = getopt_long(argc, argv, "s:l", options, NULL); switch(opt) { case 'h': mode = mode_help; opt = EOF; break; case 'v': mode = mode_version; opt = EOF; break; case 'l': mode = mode_list; break; case 's': mode = mode_size; device = optarg; break; case 't': dev_part_type = optarg; break; case EOF: break; default: mode = mode_illegal; opt = EOF; break; } } while (opt != EOF); return mode; } static char buf[16]; static const char * read_line(const char *msg, ...) { va_list ap; char *p; buf[0] = '\0'; do { va_start(ap, msg); vprintf(msg, ap); va_end(ap); fgets(buf, sizeof(buf) - 1, stdin); } while (!feof(stdin) && buf[0] == '\0'); p = strchr(buf, '\n'); if (p) *p = '\0'; return buf; } static char read_char(const char *msg) { return read_line(msg)[0]; } static void list_types(u_int parn, ptyp_t next) { ptyp_t types[256], cur; u_int idx = 0, last[4], done = 0, nxt; int i; do { cur = next; next = part_nexttype(part, parn, cur, -1); } while (cur != next); do { cur = next; types[idx++] = cur; next = part_nexttype(part, parn, cur, +1); } while (cur != next); for (i = 3; i >= 0; i--) last[3 - i] = done += (idx + i - done) / (i + 1); i = nxt = done = 0; do { printf("%c%3x %-15.15s", i ? ' ' : '\n', types[nxt], part_typename(part, types[nxt])); nxt = last[i++] + done; if (i > 3 || nxt >= last[i]) { i = 0; nxt = ++done; } } while (done < last[0]); putchar('\n'); } static ptyp_t read_type(u_int parn, ptyp_t old_type, const char *prompt) { int hex; while (1) { const char *line = read_line(prompt); if (tolower(line[0]) == 'l') list_types(parn, old_type); else if (isxdigit(line[0])) { hex = (int)strtoul(line, NULL, 16); break; } } return (ptyp_t)hex; } static u_int get_part_nr(void) { buf[0] = '\0'; do { fputs("Which partition? ", stdout); fgets(buf, sizeof(buf) - 1, stdin); } while (!feof(stdin) && buf[0] == '\0'); return atoi(buf); } static u_int display_factor = 1; /* in units/sector */ static u_int full_bits = 0; /* 1024 cylinders in sectors */ static bool_t unit_flag = 1; static u_int rounded(u_int calcul, u_int start) { u_int i; if (!full_bits) return calcul; while ((i = calcul + full_bits) <= start) calcul = i; return calcul; } static void update_units(part_t *part) { geometry_t geo; part_getgeometry(part, &geo); full_bits = 1024 * geo.heads * geo.sectors; if (unit_flag && full_bits) display_factor = full_bits >> 10; else display_factor = 1; } static void change_units(part_t *part) { unit_flag = !unit_flag; if (part) update_units(part); printf("Changing display/entry units to %ss\n", unit_flag ? "cylinder" : "sector"); } static u_int sectors_to_units(u_int sectors) { return (sectors + (unit_flag ? display_factor - 1 : 0)) / display_factor; } static u_int units_to_sectors(u_int units) { return units * display_factor; } static inline u_int calculate(part_t *part, u_int head, u_int sect, u_int cyl) { geometry_t geo; part_getgeometry(part, &geo); return sect - 1 + geo.sectors * (head + geo.heads * cyl); } static void delete_partition(void) { partinfo_t info; u_int part_no, found = 0, partition = get_part_nr(); for (part_no = 0; part_getpartinfo(part, part_no, &info); part_no += 1) if (info.kern_part_no == partition) { found = 1; break; } if (!found) { printf("Bad partition number `%d'\n", partition); return; } if (!part_validops(part, part_no, &info) & VALIDOPS_DELETE) { printf("Partition %d cannot be deleted.\n", info.kern_part_no); return; } if (!part_delete(part, part_no)) printf("Unable to delete partition `%d': %s\n", partition, get_error()); else printf("Partition `%d' deleted\n", partition); } struct regions { struct { u_int start; u_int end; } region[16]; u_int nr; }; static void add_region(struct regions *region, partinfo_t *info) { u_int i; for (i = 0; i < region->nr; i++) { if (region->region[i].start > info->blk_start) { memmove(®ion->region[i + 1], ®ion->region[i], (region->nr - i) * sizeof(region->region[0])); region->region[i].start = info->blk_start; region->region[i].end = info->blk_end + 1; region->nr += 1; goto added; } } region->region[region->nr].start = info->blk_start; region->region[region->nr].end = info->blk_end + 1; region->nr += 1; added: for (i = 1; i < region->nr;) { if (region->region[i].start == region->region[i - 1].end) { region->region[i - 1].end = region->region[i].end; memmove(®ion->region[i], ®ion->region[i+1], (region->nr - i) * sizeof(region->region[0])); region->nr -= 1; } else i += 1; } } static void get_regions(struct regions *region) { partinfo_t info; u_int parn = 0; region->nr = 0; while (part_getpartinfo(part, parn++, &info)) { if (!info.type) continue; add_region(region, &info); } } static void new_partition(void) { partinfo_t info; geometry_t geo; struct regions regions; u_int parn, total, first = 1, i; char *units; update_units(part); part_getgeometry(part, &geo); total = geo.sectors * geo.heads * geo.cylinders; if (unit_flag) units = "cylinder"; else units = "sector"; printf("\nUnits are %ss of %d * %d bytes\nDisk space used:", units, display_factor, 512); get_regions(®ions); for (i = 0; i < regions.nr; i++) printf("%s %d - %d", i ? "," : "", sectors_to_units(regions.region[i].start), sectors_to_units(regions.region[i].end)); printf("\nTotal disk: %d\n\n", sectors_to_units(total)); parn = part_allocate(part, &info); if (parn == PARN_ERROR) { printf("Unable to allocate a new partition slot: %s\n", get_error()); return; } printf("Allocating partition %s%d\n\n", device, info.kern_part_no); do { const char *l; l = read_line(first ? "Start %s : " : "Start %s (%u) : ", units, sectors_to_units(info.blk_start)); if (isdigit(l[0])) info.blk_start = units_to_sectors(strtoul(l, NULL, 10)); else if (first || l[0] == 'q') { printf("\nPartition not created\n"); return; } l = read_line(first ? "End %s : " : "End %s (%u) : ", units, sectors_to_units(info.blk_end + 1)); if (l[0] == '+') info.blk_end = info.blk_start + units_to_sectors(strtoul(l + 1, NULL, 10)) - 1; else if (isdigit(l[0])) info.blk_end = units_to_sectors(strtoul(l, NULL, 10)) - 1; else if (first || l[0] == 'q') { printf("\nPartition not created\n"); return; } info.chs_valid = 0; first = 0; if (info.blk_end > info.blk_start && info.blk_end < total) { if (part_create(part, parn, &info)) { printf("\nPartition %d created\n", parn); return; } else printf("\nUnable to create partition: %s\n\n", get_error()); } else printf("\nInvalid partition start/end\n\n"); } while (1); } static void change_type(void) { partinfo_t info; u_int part_no, found = 0, partition = get_part_nr(); ptyp_t old_type, new_type; for (part_no = 0; part_getpartinfo(part, part_no, &info); part_no += 1) if (info.kern_part_no == partition) { found = 1; break; } if (!found) { printf("Bad partition number `%d'\n", partition); return; } if (!part_validops(part, part_no, &info) & VALIDOPS_UPDATE) { printf("Partition %d cannot be altered.\n", info.kern_part_no); return; } old_type = info.type; if (is_extended(info.type)) { printf("Partition %d is extended. Delete it\n", info.kern_part_no); return; } new_type = read_type(part_no, old_type, "Hex code (type L to list codes):"); if (is_extended(new_type)) { printf("You may not change a partition " "to be an extended partition\n"); return; } info.type = new_type; if (!part_setpartinfo(part, part_no, &info)) printf("Unable to change partition %d type: %s\n", partition, get_error()); else printf("Partition `%d' type changed from %X (%s) to %X (%s)\n", partition, old_type, part_typename(part, old_type), new_type, part_typename(part, new_type)); } typedef enum { LIST_NORMAL, LIST_EXTENDED_NORMAL, LIST_EXTENDED_EXTENDED } list_t; static inline int is_displayable_partition(ptyp_t type) { return type != ptyp_none && type != ptyp_pc_table; } static void list_table(list_t list_type) { partinfo_t info; geometry_t geo; int i, w = 0; update_units(part); part_getgeometry(part, &geo); printf("\nDisk %s: %d heads, %d sectors, %d cylinders\n", device, geo.heads, geo.sectors, geo.cylinders); if (list_type == LIST_NORMAL) { printf("Units = %ss of ", unit_flag ? "cylinder" : "sector"); if (display_factor > 1) printf("%d * ", display_factor); printf("512 bytes\n\n"); w = strlen(device) + 1; if (w < 6) w = 6; printf("%*s Boot Begin Start End Blocks Id System\n", w, "Device"); } else printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); i = 0; while (part_getpartinfo(part, i++, &info)) { if (list_type == LIST_NORMAL && !is_displayable_partition(info.type)) continue; if (list_type == LIST_NORMAL) { printf("%*s%-2d %c%9d%9d%9d%9d%c %3x %s\n", w - 1, device, info.kern_part_no, ' ', sectors_to_units(calculate(part, info.chs_start.head, info.chs_start.sector, info.chs_start.cylinder)), sectors_to_units(info.blk_start), sectors_to_units(info.blk_end + (info.blk_end & 1 ? 0 : 1)), (info.blk_end - info.blk_start + 1) / 2, (info.blk_end - info.blk_start + 1) & 1 ? '+' : ' ', info.type, part_typename(part, info.type)); // check_consistency (part, p); } else { printf("%2d %02x%4d%4d%5d%4d%4d%5d%8d%8d %03x\n", info.kern_part_no, 0, info.chs_start.head, info.chs_start.sector, info.chs_start.cylinder, info.chs_end.head, info.chs_end.sector, info.chs_end.cylinder, info.blk_start, info.blk_end - info.blk_start + 1, info.type); // if (info.type != ptyp_none) // check_consistency (part, p); } } } typedef enum { pps_ret_ok, pps_ret_open_error, pps_ret_not_found } pps_ret_t; static pps_ret_t print_part_size(const char *device) { pps_ret_t ret = pps_ret_not_found; char dev_nam[16], *p; part_t *part; int partition; strncpy(dev_nam, device, 15); dev_nam[15] = '\0'; for (p = dev_nam; *p && !isdigit(*p); p++); partition = atoi(p); *p = '\0'; part = part_open(dev_nam, dev_part_type); if (part) { int i = 0; partinfo_t info; while(part_getpartinfo(part, i, &info)) { if (info.kern_part_no == partition) { printf("%d\n", (info.blk_end - info.blk_start + 1) / 2); ret = pps_ret_ok; break; } i += 1; } part = part_close(part); } else ret = pps_ret_not_found; return ret; } /* Prototype: int print_part_tables(int nr, const char **parts) * Purpose : Display a list of partition tables * Params : nr - number of partition tables to display * : parts - pointers to partition table names * Returns : 0 if success */ static int print_part_tables(int nr, const char **parts) { int i, ret = 1; for(i = 0; i < nr; i++) { device = parts[i]; part = part_open(device, dev_part_type); if (part) { list_table(LIST_NORMAL); part = part_close(part); ret = 0; } } return ret; } static void write_tables(void) { const char *l; int i, error = 0; printf("\nWriting the partition tables is dangerous and" "\ncan result in loss of data. Please confirm" "\nthat you really want to do this by typing 'YES'" "\nexactly as shown\n\n"); l = read_line("Confirm: "); if (strcmp(l, "YES")) { printf("\nCONFIRMATION NOT GIVEN - not updating partition table\n"); return; } if (!part_sync(part)) { printf("\nERROR occurred while updating partition tables: %s\n", get_error()); return; } printf("The partition table has been altered!\n\n"); printf("Syncing disks..."); fflush(stdout); sync(); sleep(2); sync(); printf("OK\nRe-reading the partition table..."); fflush(stdout); i = ioctl(part->blkio->fd, BLKRRPART); if (i != 0) error = errno; else { printf(" resyncing..."); fflush(stdout); sync(); sleep(2); i = ioctl(part->blkio->fd, BLKRRPART); if (i != 0) error = errno; } if (i < 0) printf("FAILED!\n"); printf("Syncing disks..."); fflush(stdout); sync(); sleep(4); printf("OK\n"); if (i < 0) printf("\n*** Re-read table failed with error %d: %s ***\n" " Reboot your system to ensure the partition table is\n" " updated.\n", error, strerror(error)); exit(0); } static void show_main_menu (void) { printf("\nCommand action\n" " d delete a partition\n" // " l list known partition types\n" " m print this menu\n" " n add a new partition\n" " p print the partition table\n" " q quit without saving changes\n" " r reopen partition, specifing type\n" " t change a partition's system id\n" " u change display/entry units\n" // " v verify the partition table\n" " w write table to disk and exit\n" // " x extra functionality (experts only)\n" ); } /* Prototype: void main_menu(void) * Purpose : display main menu & process user selections */ static void main_menu(void) { int quit = 0; part_t *new_part; const char *s; static char *scheme; show_main_menu(); do { putchar('\n'); switch (tolower(read_char("Command (m for help): "))) { case 'd': if (part) delete_partition(); else goto unavailable; break; case 'e': if (part) list_table(LIST_EXTENDED_NORMAL); else goto unavailable; break; // case 'l': // if (part) // list_types(); // else // goto unavailable; // break; case 'm': default: show_main_menu(); break; case 'n': if (part) new_partition(); else goto unavailable; break; case 'p': if (part) list_table(LIST_NORMAL); else goto unavailable; break; case 'q': quit = 1; break; case 'r': s = read_line("Partitioning scheme: "); new_part = part_open(device, s); if (new_part) { if (scheme) free(scheme); part_close(part); part = new_part; dev_part_type = scheme = strdup(s); fprintf(stderr, "%s successfully reopened using %s scheme\n", device, dev_part_type); } else if (part) fprintf(stderr, "%s: %s: unable to reopen partition as %s,\n" "using %s instead.\n", progname, device, s, dev_part_type); else fprintf(stderr, "%s; %s: unable to reopen partition as %s\n", progname, device, s); break; case 't': if (part) change_type(); else goto unavailable; break; case 'u': change_units(part); break; case 'w': if (part) { write_tables(); break; } unavailable: fprintf(stderr, "%s: %s: option ignored - please re-open the device\n", progname, device); break; } } while (!quit); } /* Prototype: u_int edit_device(const char *dev_nam) * Purpose : Edit partition tables on a device * Params : dev_nam - special device name to edit * Returns : 0 if success */ static u_int edit_device(const char *dev_nam) { u_int use_default = dev_nam == NULL; if (use_default) { device = DEFAULT_DEVICE; part = part_open(device, dev_part_type); if (!part) { device = ALTERNATE_DEVICE; part = part_open(ALTERNATE_DEVICE, dev_part_type); } } else { device = dev_nam; part = part_open(device, dev_part_type); } if (use_default) printf("\nUsing %s as default device\n", device); if (!part) printf("Unable to open device %s: %s\n\n" " Please use 'r' to open the partition as a specific type\n\n", device, get_error()); else printf("\nDevice %s is partitioned using %s scheme\n", device, part_getscheme(part)); main_menu(); return 0; } int main(int argc, char *argv[]) { prog_mode_t mode; u_int ret = 1; progname = argv[0]; mode = parse_args(argc, argv); switch(mode) { case mode_version: printf("arm-fdisk v"VERSION"\n"); break; case mode_help: printf("Usage: %s [OPTION] [DEVICE]...\n", progname); printf("Display or edit partition tables on block devices.\n\n"); printf(" --type SCHEME specify the partitioning scheme to use on the device\n"); printf(" -l, --list DEVICE... list partition information on devices\n"); printf(" or all devices\n"); printf(" -s, --size DEVICE display size of partition\n"); printf(" --help display this help and exit\n"); printf(" --version output version information and exit\n\n"); printf("With no DEVICE, partition /dev/hda or /dev/sda\n"); break; case mode_size: switch(print_part_size(device)) { case pps_ret_ok: ret = 0; break; case pps_ret_open_error: fprintf(stderr, "Cannot open %s: %s\n", device, get_error()); break; case pps_ret_not_found: ret = 1; break; } break; case mode_list: if (optind < argc) ret = print_part_tables(argc - optind, argv + optind); else ret = print_part_tables(NR_DEVICES, part_devs); break; case mode_partition: if (optind < argc - 1) { fprintf(stderr, "Partitioning is only allowed on a single device\n"); goto bad; } if (optind == argc) ret = edit_device(NULL); else ret = edit_device(argv[optind]); break; bad: case mode_illegal: fprintf(stderr, "Try `%s --help` for more information.\n", progname); ret = 1; break; } return ret; } #else #include "partitions.h" #define LINE_LENGTH 80 #define NR_DEF_DEVS 2 static const char *default_devs[NR_DEF_DEVS] = { DEFAULT_DEVICE, ALTERNATE_DEVICE }; static const char *usage = "Usage: fdisk [-l [device...]] [-v] [-s /dev/hdxn] [/dev/hdx]\n"; static char *prog_name; static bool errorjump_set; static jmp_buf errorjump; unsigned int sector_offset = 1; bool dos_compatible_flag = TRUE; /* * Sundry functions... */ #ifdef __GNUC__ static volatile void fatal (const char *message, ...) __attribute__((noreturn)); #endif static volatile void fatal (const char *message, ...) { va_list ap; if (errorjump_set) longjmp (errorjump, 1); va_start (ap, message); fprintf (stderr, "%s: ", prog_name); vfprintf (stderr, message, ap); va_end (ap); exit (1); } static char line_buffer[LINE_LENGTH]; static char *line_ptr; /* interactive input */ char read_line (void) { if (!fgets (line_buffer, LINE_LENGTH, stdin)) return 0; line_ptr = line_buffer; while (*line_ptr && !isgraph (*line_ptr)) line_ptr ++; return *line_ptr; } char read_char (char *mesg) { do fputs (mesg, stdout); while (!read_line ()); return *line_ptr; } #define hex_val(c) ({ char _c = (c); isdigit(_c) ? _c - '0' : tolower(_c) + 10 - 'a'; }) int read_hex (struct systypes *sys, int size) { int hex; while (1) { read_char ("Hex code (type L to list codes): "); if (tolower (*line_ptr) == 'l') part_list_types (sys, size); else if (isxdigit (*line_ptr)) { hex = 0; do hex = hex << 4 | hex_val (*line_ptr++); while (isxdigit (*line_ptr)); return hex; } } } enum offset { BASE_IGNORE, BASE_LOWER, BASE_UPPER, BASE_DEFAULT }; int read_int (Partition_t *part, unsigned int low, unsigned int dflt, unsigned int high, enum offset base, char *mesg) { unsigned int i, use_default = 1; char ms[70]; switch (base) { case BASE_LOWER: sprintf (ms, "%s ([%d]-%d): ", mesg, low, high); break; case BASE_UPPER: sprintf (ms, "%s (%d-[%d]): ", mesg, low, high); break; case BASE_DEFAULT: sprintf (ms, "%s: (%d-[%d]-%d): ", mesg, low, dflt, high); break; default: sprintf (ms, "%s: (%d-%d): ", mesg, low, high); break; } while (1) { while (!isdigit (read_char (ms)) && (*line_ptr != '-' && *line_ptr != '+')) continue; if (*line_ptr == '+' || *line_ptr == '-') { if (*line_ptr == '+') line_ptr ++; i = atoi (line_ptr); while (isdigit (*line_ptr)) { line_ptr ++; use_default = 0; } switch (*line_ptr) { case 'c': case 'C': if (!unit_flag) i *= part->geo.heads * part->geo.sectors; break; case 'k': case 'K': i = (i << 1) / display_factor; break; case 'm': case 'M': i = (i << 11) / display_factor; break; default: break; } switch (base) { case BASE_LOWER: i += low; break; case BASE_UPPER: i += high; break; case BASE_DEFAULT: i += dflt; default: break; } } else { i = atoi (line_ptr); while (isdigit (*line_ptr)) { line_ptr ++; use_default = 0; } } if (use_default) printf ("Using default value %d\n", i = dflt); if (i >= low && i <= high) break; else printf ("Value out of range.\n"); } return i; } int select_partition (Partition_t *partitions, bool warn, int min, int max) { int i; if (!max) { min = 1; for (i = 0; i < partitions->nr_parts; i++) if (max < partitions->parts[i].dev_index) max = partitions->parts[i].dev_index; } max = read_int (partitions, min, max, max, BASE_IGNORE, "Partition number"); if (warn) { for (i = 0; i < partitions->nr_parts; i++) if (max == partitions->parts[i].dev_index) break; if (i >= partitions->nr_parts) printf ("Warning: partition %d has empty type\n", max); } return max; } void log2chs (Partition_t *part, unsigned long ls, unsigned int *c, unsigned int *h, unsigned int *s) { int spc = part->geo.heads * part->geo.sectors; *c = ls / spc; ls = ls % spc; *h = ls / part->geo.sectors; *s = ls % part->geo.sectors + 1; } void check_bounds (Partition_t *part, unsigned long *first, unsigned long *last) { int i; assert (part != NULL); assert (first != NULL); assert (last != NULL); for (i = 0; i < part->nr_parts; i++) { Part_t *p = &part->parts[i]; first[i] = calculate (part, p->begin.heads, p->begin.sectors, p->begin.cylinders); last[i] = p->start + p->size - 1; } } static void check_consistency (Partition_t *part, Part_t *p) { unsigned int pbc, pbh, pbs; unsigned int pec, peh, pes; unsigned int lbc, lbh, lbs; unsigned int lec, leh, les; /* physical beginning CHS */ pbc = p->begin.cylinders; pbh = p->begin.heads; pbs = p->begin.sectors; /* physical end CHS */ pec = p->end.cylinders; peh = p->end.heads; pes = p->end.sectors; /* logical beginning CHS */ log2chs (part, p->start, &lbc, &lbh, &lbs); /* logical end CHS */ log2chs (part, p->start + p->size - 1, &lec, &leh, &les); if (part->geo.cylinders <= 1024) { if (pbc != lbc || pbh != lbh || pbs != lbs) { printf ("Partition %d has different physical/logical " "beginnings (non-Linux?):\n", p->dev_index); printf (" phys=(%d, %d, %d) ", pbc, pbh, pbs); printf (" logi=(%d, %d, %d)\n", lbc, lbh, lbs); } if (pec != lec || peh != leh || pes != les) { printf ("Partition %d has different physical/logical " "endings:\n", p->dev_index); printf (" phys=(%d, %d, %d) ", pec, peh, pes); printf (" logi=(%d, %d, %d)\n", lec, leh, les); } } if (p->must_start_cyl && (pbh != 0/*!pbc*/ || pbs != 1)) { printf ("Partition %d does not start on a cylinder boundary:\n", p->dev_index); printf (" phys=(%d, %d, %d) ", pbc, pbh, pbs); printf ("should be (%d, %d, 1)\n", pbc, 0/*!pbc*/); } if (p->must_end_cyl && (peh != part->geo.heads - 1 || pes != part->geo.sectors)) { printf ("Partition %d does not end on a cylinder boundary:\n", p->dev_index); printf (" phys=(%d, %d, %d) ", pec, peh, pes); printf ("should be (%d, %d, %d)\n", pec, part->geo.heads - 1, part->geo.sectors); } if (p->must_1mb && p->size % 1048576) printf ("Partition %d does not contain a whole number of MB\n", p->dev_index); } void check (Partition_t *part, Part_t *p, unsigned long start) { /* if (!total) printf ("Warning: partition %d contains sector 0\n", p->dev_index); */ if (p->end.heads >= part->geo.heads) printf ("Partition %d: head %d is greater than maximum %d\n", p->dev_index, p->end.heads, part->geo.heads - 1); if (p->end.sectors > part->geo.sectors) printf ("Partition %d; sector %d is greater than maximum %d\n", p->dev_index, p->end.sectors, part->geo.sectors); if (p->end.cylinders >= part->geo.cylinders) printf ("Partition %d: cylinder %d is greater than maximum %d\n", p->dev_index, p->end.cylinders, part->geo.cylinders - 1); } Part_t *get_part (Partition_t *part, int dev_index) { int i; assert (part != NULL); for (i = 0; i < part->nr_parts; i++) if (part->parts[i].dev_index == dev_index) break; if (i >= part->nr_parts) return NULL; return &part->parts[i]; } /* * Other functions... */ static void move_begin (Partition_t *part, int dev_index) { Part_t *p = get_part (part, dev_index); unsigned long first, new_first; if (!p) return; if (!p->sysid || !p->size || p->sysid == SYSID_EXTENDED) { printf ("Partition %d has no data area\n", dev_index); return; } first = calculate (part, p->begin.heads, p->begin.sectors, p->begin.cylinders); new_first = read_int (part, first, first, p->start + p->size - 1, BASE_LOWER, "New beginning of data"); if (new_first != p->size) { first = p->size + p->start - new_first; p->size = first; p->start = new_first; p->changed = TRUE; } } static void print_raw (Partition_t *part) { printf ("Device: %s\n", part->device); part_dump (part); } static void toggle_active (Partition_t *part, int dev_index) { Part_t *p = get_part (part, dev_index); if (!p) return; if (p->boot_flags) p->boot_flags = 0; else p->boot_flags = ACTIVE_FLAG; p->changed = TRUE; } static void toggle_dos (Partition_t *part) { if ((dos_compatible_flag = !dos_compatible_flag)) sector_offset = part->geo.sectors; else sector_offset = 1; printf ("DOS compatibility flag is %sset", dos_compatible_flag ? "" : "not "); } static int delete_partition (Partition_t *part, int dev_index) { int i, j; assert (part != NULL); for (j = 0; j < part->nr_parts; j++) if (part->parts[j].dev_index == dev_index) break; if (j >= part->nr_parts) return 0; if (part->parts[j].dev_index_owner == part->parts[j].dev_index) { printf ("Cannot delete partition %d\n", dev_index); return 1; } for (i = 0; i < part->nr_parts; i++) if (part->parts[i].dev_index_owner == dev_index && delete_partition (part, part->parts[i].dev_index)) return 1; part->parts[j].changed = TRUE; part->parts[j].boot_flags = 0; part->parts[j].begin.sectors = 0; part->parts[j].begin.heads = 0; part->parts[j].begin.cylinders = 0; part->parts[j].end.sectors = 0; part->parts[j].end.heads = 0; part->parts[j].end.cylinders = 0; part->parts[j].start = 0; part->parts[j].size = 0; part->parts[j].sysid = SYSID_EMPTY; return 0; } static int add_partition (Partition_t *part, int dev_index, int dev_index_owner, PType_t type) { Part_t *p = get_part (part, dev_index); unsigned long *first, *last, start, stop = 0, limit; unsigned long temp; char mesg[48]; int read, i; if (p && p->sysid) { printf ("Partition %d is already defined. Delete " "it before adding it.\n", dev_index); return 0; } first = malloc (sizeof (unsigned long) * part->nr_parts); if (!first) return -1; last = malloc (sizeof (unsigned long) * part->nr_parts); if (!last) return -1; check_bounds (part, first, last); if (unit_flag) for (i = 0; i < part->nr_parts; i++) first[i] = (cround (first[i]) - 1) * display_factor; start = sector_offset; limit = part->geo.heads * part->geo.sectors * part->geo.cylinders - 1; if (type == PT_LOGICAL) { for (i = 0; i < part->nr_parts; i++) if (part->parts[i].dev_index == dev_index_owner) { start = part->parts[i].start + 1; limit = part->parts[i].start + part->parts[i].size - 1; } } sprintf (mesg, "First %s", unit_flag ? "cylinder" : "sector"); read = 0; do { temp = start; for (i = 0; i < part->nr_parts; i++) if (start >= first[i] && start <= last[i] && (part->parts[i].sysid != SYSID_EXTENDED || type != PT_LOGICAL)) start = last[i] + 1; if (start > limit) break; if (start != temp && read) { printf ("Sector %ld is already allocated\n", temp); temp = start = stop; read = 0; } if (!read && start == temp) { unsigned long i; i = stop = start; start = read_int (part, cround (i), cround (i), cround (limit), BASE_IGNORE, mesg); if (unit_flag) { start = (start - 1) * display_factor; if (start < i) start = i; } read = 1; } } while (start != temp || !read); for (i = 0; i < part->nr_parts; i++) { if (start < first[i] && limit >= first[i] && (part->parts[i].sysid != SYSID_EXTENDED || type != PT_LOGICAL)) limit = first[i] - 1; } if (start > limit) { printf ("No free sectors available\n"); return 0; } if (cround (start) == cround (limit)) stop = start; else { sprintf (mesg, "Last %s or +size or +sizeM or +sizeK", unit_flag ? "cylinder" : "sector"); stop = read_int (part, cround (start), cround (limit), cround (limit), BASE_LOWER, mesg); if (unit_flag) { stop = stop * display_factor - 1; if (stop > limit) stop = limit; } } if (!p) { p = realloc (part->parts, sizeof (Part_t) * (part->nr_parts + 1)); if (!p) return -1; part->parts = p; p = &part->parts[part->nr_parts++]; } p->dev_index = dev_index; p->dev_index_owner = dev_index_owner; p->boot_flags = 0; p->sysid = type == PT_EXTENDED ? SYSID_EXTENDED : SYSID_LINUXNAT; p->start = start; p->size = stop - start + 1; p->begin.sectors = start % part->geo.sectors + 1; start /= part->geo.sectors; p->begin.heads = start % part->geo.heads; p->begin.cylinders = start / part->geo.heads; p->end.sectors = stop % part->geo.sectors + 1; stop /= part->geo.sectors; p->end.heads = stop % part->geo.heads; p->end.cylinders = stop / part->geo.heads; p->changed = TRUE; return 0; } static void new_partition (Partition_t *part) { int partition_types, i; PType_t types[3]; partition_types = part_getavailabletypes (part); if (!partition_types) printf ("All partitions are used. Please delete some partitions " "first\n"); else { int lower, upper; i = 0; if (partition_types & 1) types[i++] = PT_PRIMARY; if (partition_types & 2) types[i++] = PT_EXTENDED; if (partition_types & 4) types[i++] = PT_LOGICAL; if (i != 1) { int j; printf ("Command action\n"); for (j = 0; j < i; j++) switch (types[j]) { case PT_PRIMARY: printf (" p primary\n"); break; case PT_EXTENDED: printf (" e extended\n"); break; case PT_LOGICAL: printf (" l logical\n"); break; } i = 0; do { char c; c = tolower (read_char ("\nPartition type: ")); switch (c) { case 'p': if (partition_types & 1) types[i++] = PT_PRIMARY; break; case 'e': if (partition_types & 2) types[i++] = PT_EXTENDED; break; case 'l': if (partition_types & 4) types[i++] = PT_LOGICAL; } } while (!i); } part_getpartrange (part, types[0], &lower, &upper); add_partition (part, select_partition (part, FALSE, lower, upper), 2, types[0]); } } static void change_sysid (Partition_t *part, int dev_index) { Part_t *p = get_part (part, dev_index); int sys; if (!p) return; if (p->sysid == SYSID_EXTENDED) printf ("Partition %d is extended. Delete it\n", dev_index); else while (1) { sys = read_hex (NULL, 0); if (!sys) { delete_partition (part, dev_index); break; } else if (sys == SYSID_EXTENDED) { printf ("You may not change a partition " "to be an extended partition\n"); break; } else if (sys != p->sysid) { p->sysid = sys; printf ("Changed system type of partition %d to %x (%s)\n", dev_index, sys, part_type (p->sysid)); p->changed = TRUE; part->changed = 1; break; } } } static void change_units (Partition_t *part) { if ((unit_flag = !unit_flag)) display_factor = 1; else display_factor = part->geo.heads * part->geo.sectors; update_units (part); printf ("Changing display/entry units to %ss\n", unit_flag ? "cylinder" : "sector"); } static int verify (Partition_t *part) { unsigned int total = 1; unsigned long *first, *last; int i, j; first = malloc (sizeof (unsigned long) * part->nr_parts); if (!first) return -1; last = malloc (sizeof (unsigned long) * part->nr_parts); if (!last) return -1; check_bounds (part, first, last); for (i = 0; i < part->nr_parts; i++) { Part_t *p = &part->parts[i]; if (p->sysid != SYSID_EMPTY) { if (p->sysid != SYSID_EXTENDED) { check_consistency (part, p); if (p->start < first[i]) printf ("Warning: bad start-of-data in partition %d.\n", p->dev_index); check (part, p, last[i]); total += last[i] + 1 - first[i]; if (p->dev_index_owner != p->dev_index) { for (j = 0; j < part->nr_parts; j++) if (p->dev_index_owner == part->parts[j].dev_index) { if (first[i] <= first[j] + 1 || last[i] > last[j]) printf ("Logical partition %d not " "entirely in partition %d\n", p->dev_index, p->dev_index_owner); break; } if (j >= part->nr_parts) printf ("Logical partition %d does not have a valid " "parent\n", p->dev_index); } for (j = 0; j < i; j++) { if (part->parts[j].sysid == SYSID_EXTENDED) continue; if ((first[i] >= first[j] && first[i] <= last[j]) || (last[i] <= last[j] && last[i] >= first[j])) { printf ("Warning: partition %d overlaps partition %d.\n", part->parts[i].dev_index, part->parts[j].dev_index); total += first[i] >= first[j] ? first[i] : first[j]; total -= last[i] <= last[j] ? last[i] : last[j]; } } } else { total += 1; } } } if (total > part->geo.heads * part->geo.sectors * part->geo.cylinders) printf ("Total allocated sectors %d greater than the maximum %d\n", total, part->geo.heads * part->geo.sectors * part->geo.cylinders); else if ((total = part->geo.heads * part->geo.sectors * part->geo.cylinders - total)) printf ("%d unallocated sectors\n", total); return 0; } static bool write_table (Partition_t *part) { return part_write (part) >= 0; } #define REPORT_ERRORS 0 #define IGNORE_ERRORS 1 static void print_part_table (const char *dev, int errorstatus) { static Partition_t *partitions; assert (dev != NULL); if (!errorjump_set && errorstatus == IGNORE_ERRORS) { errorjump_set = TRUE; if (setjmp (errorjump)) { part_close (partitions); partitions = NULL; return; } } partitions = part_open (dev, READ_ONLY); if (!partitions) fatal ("Cannot open %s: %s\n", dev, get_error()); list_table (partitions, LIST_NORMAL); part_close (partitions); partitions = NULL; } static int print_part_size (const char *dev) { Partition_t *partitions; char device[9]; int part_no, i; assert (dev != NULL); if (strlen (dev) <= 8 || (!(part_no = atoi (dev + 8)))) fatal (usage); strncpy (device, dev, 8); device[8] = '\0'; partitions = part_open (device, READ_ONLY); if (!partitions) fatal ("Cannot open %s: %s\n", device, get_error()); for (i = 0; i < partitions->nr_parts; i++) if (partitions->parts[i].dev_index == part_no) { printf ("%ld\n", partitions->parts[i].size / 2); break; } i = i < partitions->nr_parts ? 0 : 1; part_close (partitions); return i; } static void show_extra_menu (void) { puts ("\nCommand action\n" " b move beginning of data in a partition\n" " c change number of cylinders\n" " d print the raw data in the partition table\n" " e list extended partitions\n" " h change number of heads\n" " m print this menu\n" " p print the partition table\n" " q quit without saving changes\n" " r return to main menu\n" " s change number of sectors\n" " v verify the partition table\n" " w write table to disk and exit"); } static bool extra_menu (Partition_t *partitions) { bool quit = FALSE; static bool first = TRUE; if (first) show_extra_menu (); first = FALSE; do { putchar ('\n'); switch (tolower (read_char ("Expert command (m for help): "))) { case 'b': move_begin (partitions, select_partition (partitions, TRUE, 0, 0)); break; case 'c': partitions->geo.cylinders = read_int (partitions, 1, partitions->geo.cylinders, 65535, BASE_DEFAULT, "Number of cylinders"); break; case 'd': print_raw (partitions); break; case 'e': list_table (partitions, LIST_EXTENDED_EXTENDED); break; case 'h': partitions->geo.heads = read_int (partitions, 1, partitions->geo.heads, 256, BASE_DEFAULT, "Number of heads"); update_units (partitions); break; case 'm': default: show_extra_menu (); break; case 'p': list_table (partitions, LIST_EXTENDED_NORMAL); break; case 'q': quit = TRUE; break; case 'r': return FALSE; case 's': partitions->geo.sectors = read_int (partitions, 1, partitions->geo.sectors, 63, BASE_DEFAULT, "Number of sectors"); if (dos_compatible_flag) { sector_offset = partitions->geo.sectors; printf ("Warning: setting sector offset for DOS " "compatability\n"); } update_units (partitions); break; case 'v': verify (partitions); break; case 'w': quit = write_table (partitions); break; } } while (!quit); return TRUE; } static void show_main_menu (void) { puts ("\nCommand action\n" " a toggle a bootable flag\n" " b edit bsd disklabel\n" /* bf */ " c toggle the dos compatiblity flag\n" " d delete a partition\n" " l list known partition types\n" " m print this menu\n" " n add a new partition\n" " p print the partition table\n" " q quit without saving changes\n" " t change a partition's system id\n" " u change display/entry units\n" " v verify the partition table\n" " w write table to disk and exit\n" " x extra functionality (experts only)"); } static void main_menu (const char *dev, part_open_mode_t open_mode) { Partition_t *partitions; bool quit = FALSE; assert (dev != NULL); partitions = part_open (dev, open_mode); if (!partitions) fatal ("Cannot open %s: %s\n", dev, get_error()); if (dos_compatible_flag) sector_offset = partitions->geo.sectors; update_units (partitions); show_main_menu (); do { putchar ('\n'); switch (tolower (read_char ("Command (m for help): "))) { case 'a': toggle_active (partitions, select_partition (partitions, TRUE, 0, 0)); break; case 'b': break; case 'c': toggle_dos (partitions); break; case 'd': delete_partition (partitions, select_partition (partitions, FALSE, 0, 0)); break; case 'l': part_list_types (NULL, 0); break; case 'm': default: show_main_menu (); break; case 'n': new_partition (partitions); break; case 'p': list_table (partitions, LIST_NORMAL); break; case 'q': quit = TRUE; break; case 't': change_sysid (partitions, select_partition (partitions, TRUE, 0, 0)); break; case 'u': change_units (partitions); break; case 'v': verify (partitions); break; case 'w': quit = write_table (partitions); break; case 'x': quit = extra_menu (partitions); break; } } while (!quit); part_close (partitions); } int main (int argc, char *argv[]) { const char *device = NULL; part_open_mode_t open_mode = READ_WRITE; int i; prog_name = strrchr (argv[0], '/'); if (prog_name) prog_name ++; else prog_name = argv[0]; if (argc > 1 && *argv[1] == '-') { switch (argv[1][1]) { case 'v': printf ("fdisk v" VERSION "\n"); exit (0); case 'l': if (argc > 2) { for (i = 2; i < argc; i++) print_part_table (argv[i], REPORT_ERRORS); } else { for (i = 0; i < NR_DEVICES; i++) print_part_table (part_devs[i], IGNORE_ERRORS); } return 0; case 's': if (argc < 3) fatal (usage); return print_part_size (argv[2]); default: fprintf (stderr, "Option -%c not recognised\n", argv[1][1]); exit (1); } } if (argc > 3) fatal (usage); if (argc > 1) { int fd; device = argv[argc - 1]; fd = open (device, O_RDWR); if (fd < 0) { open_mode = READ_ONLY; fd = open (device, O_RDONLY); if (fd < 0) fatal ("can't open device '%s': %s\n", device, strerror (errno)); } close (fd); } else { int fd, mode; for (mode = 0; mode < 2; mode++) { for (i = 0; i < NR_DEF_DEVS; i++) { fd = open (default_devs[i], open_mode == READ_WRITE ? O_RDWR : O_RDONLY); if (fd >= 0) break; } if (fd >= 0) { device = default_devs[i]; close (fd); break; } open_mode = READ_ONLY; } if (!device) fatal ("can't open any device: %s\n", strerror (errno)); printf ("Using %s as default device\n", device); } if (open_mode == READ_ONLY) printf ("Warning: can't get write permission on device '%s'\n", device); main_menu (device, open_mode); exit (0); } #endif acorn-fdisk-3.0.6.orig/lib/0042755000000000000000000000000007101375523014134 5ustar rootrootacorn-fdisk-3.0.6.orig/lib/blkio/0042755000000000000000000000000007101375524015235 5ustar rootrootacorn-fdisk-3.0.6.orig/lib/blkio/close.c0100644000000000000000000000130406503055361016476 0ustar rootroot/* * blkio/close.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Close a device on UNIX architecture */ #include #include #include "util/debug.h" #include "blkio.h" /* Function: blkio_t *blkio_close (blkio_t *blkio) * Purpose : close a device previously opened with blkio_open * Params : blkio - structure returned by blkio_open * Returns : NULL */ blkio_t * blkio_close(blkio_t *blkio) { dbg_printf("blkio_close()"); if (blkio) { #if defined(RISCOS) free(blkio->disc_record); #elif defined(UNIX) close(blkio->fd); #endif free(blkio); } dbg_printf("ret=NULL"); return NULL; } acorn-fdisk-3.0.6.orig/lib/blkio/getgeo.c0100644000000000000000000000156406473506562016665 0ustar rootroot/* * blkio/getgeometry.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Close a device on RiscOS architecture */ #include #include #include "util/debug.h" #include "blkio.h" #include "filecore.h" /* Function: u_int blkio_getgeometry (blkio_t *blkio, geometry_t *geo) * Purpose : Return the geometry for the device opened with blkio_open * Params : blkio - structure returned by blkio_open * : geo - pointer to geometry structure */ u_int blkio_getgeometry (blkio_t *blkio, geometry_t *geo) { assert (blkio != NULL); assert (geo != NULL); dbg_printf ("blkio_getgeometry()"); *geo = blkio->geometry; dbg_printf ("ret=[sector_size=%d, sectors=%d, heads=%d, cylinders=%d]", geo->sector_size, geo->sectors, geo->heads, geo->cylinders); return !0; } acorn-fdisk-3.0.6.orig/lib/blkio/open.c0100644000000000000000000002575706776470157016374 0ustar rootroot/* * blkio/open.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Open a device on RiscOS architecture */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "util/zmalloc.h" #include "blkio.h" #include "filecore.h" #define MAX_FS_NAME 10 #define MAX_DRIVE_NAME 20 #ifdef RISCOS #include "!Swi.h" #include "util/swi_num.h" struct ide_identify_request { unsigned long unused; unsigned char unused1; unsigned char length; unsigned char cmd; unsigned char unused2; }; struct ide_identify_result { unsigned short config; unsigned short cyls; unsigned short reserved2; unsigned short heads; unsigned short track_bytes; unsigned short sector_bytes; unsigned short sectors; unsigned short vendor0; unsigned short vendor1; unsigned short vendor2; unsigned char serial_no[20]; unsigned short buf_type; unsigned short buf_size; unsigned short ecc_bytes; unsigned char fw_rev[8]; unsigned char model[40]; unsigned char max_multsect; unsigned char vendor3; unsigned short dword_io; unsigned char vendor4; unsigned char capability; /* 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup */ unsigned short reserved50; unsigned char vendor5; unsigned char tPIO; /* 0 slow 1 medium 2 fast */ unsigned char vendor6; unsigned char tDMA; /* 0 slow 1 medium 2 fast */ unsigned short field_valid; /* 0:cur_ok 1:eideok */ unsigned short cur_cyls; unsigned short cur_heads; unsigned short cur_sectors; unsigned short cur_capacity0; unsigned char multsect; unsigned char multsect_valid; unsigned int lba_capacity; unsigned short dma_1word; unsigned short dma_mword; unsigned short eide_pio_modes;/* 0:mode3 1:mode4 */ unsigned short eide_dma_min; /* min mword dma cycle time */ unsigned short eide_dma_time; /* recommended */ unsigned short eide_pio; /* min cycle time */ unsigned short eide_pio_iordy;/* min cycle time with IORDY (ns) */ unsigned short reserved69; unsigned short reserved70; unsigned short reservedxx[256-71]; }; #define TYPE_NOTPRESENT 0 #define TYPE_FD1772 1 #define TYPE_8271x 2 #define TYPE_ST506 3 #define TYPE_IDE 4 #define TYPE_SCSI (256+4) /* Function: int split_fs_name (const char *dev_name, char *fs_name, char *drive_name) * Purpose : Split a device name into fs name and drive name * Params : dev_name - device name to split * : fs_name - pointer to filesystem name * : drive_name - pointer to drive name * Returns : TRUE if successful, fs_name & drive_name containing strings */ static int split_fs_name (const char *dev_name, char *fs_name, char *drive_name) { const char *p; int error = 1; enum { s_in_fs, s_drv, s_in_drv, s_finished } state; state = s_in_fs; for (p = dev_name; state != s_finished; p ++) { switch (state) { case s_in_fs: if (*p != ':' && *p != '\0') *fs_name++ = *p; else { *fs_name = '\0'; if (*p == '\0') state = s_finished; else state = s_drv; } break; case s_drv: if (*p == ':') state = s_in_drv; else state = s_finished; break; case s_in_drv: if (*p != '.' && *p != '\0') *drive_name++ = *p; else { *drive_name = '\0'; state = s_finished; error = 0; } break; } } *fs_name = '\0'; *drive_name = '\0'; return !error; } static void set_disc_geometry (blkio_t *blkio, geometry_t *geo) { u_int log2secsize, sectors, update_disc_record = 0; log2secsize = blkio->disc_record->d.log2secsize; sectors = (blkio->disc_record->d.disc_size_high << (32 - log2secsize)) | (blkio->disc_record->d.disc_size >> log2secsize); geo->sector_size = 1 << log2secsize; geo->log2secsize = log2secsize; geo->sectors = blkio->disc_record->d.secspertrack; geo->heads = blkio->disc_record->d.heads + (blkio->disc_record->d.lowsector & 0x40 ? 1 : 0); geo->cylinders = sectors / (geo->heads * geo->sectors); if (blkio->swi_ideuserop) { struct ide_identify_request ide_id_req; struct ide_identify_result ide_id_res; int slave = 0, type; if (blkio->swi_controllertype) { if (!swix (blkio->swi_controllertype, rin(r0)|rout(r0), blkio->drive, &type) && type == TYPE_IDE && !swix(blkio->swi_controllertype, rin(r0)|rout(r0), blkio->drive - 1, &type) && type == TYPE_IDE) slave = 1; } dbg_printf ("-IDE drive is a %s", slave ? "slave" : "master"); memset (&ide_id_req, 0, sizeof (ide_id_req)); ide_id_req.length = 160 | (slave ? 1 << 4 : 0); ide_id_req.cmd = 236; if (!swix (blkio->swi_ideuserop, rin(r0|r2|r3|r4), 1 << 24, &ide_id_req, &ide_id_res, 512)) { geo->log2secsize = 9; geo->sector_size = 1 << 9; geo->sectors = ide_id_res.sectors; geo->heads = ide_id_res.heads; geo->cylinders = ide_id_res.cyls; update_disc_record = 1; } } else if (geo->sectors == 1) { geo->log2secsize = 9; geo->sector_size = 1 << 9; geo->sectors = 17; geo->heads = 1; geo->cylinders = 0; update_disc_record = 1; } if (update_disc_record #if 0 && (geo->sector_size == 1 << log2secsize) && (geo->sectors == blkio->disc_record->d.secspertrack) && (geo->heads == blkio->disc_record->d.heads + (blkio->disc_record->d.lowsector & 0x40 ? 1 : 0)) #endif ) { sectors = geo->cylinders * geo->heads * geo->sectors; if (sectors >= (512 * 1024 * 1024 >> log2secsize)) blkio->disc_record->d.big_flag = 1; blkio->disc_record->d.log2secsize = geo->log2secsize; blkio->disc_record->d.secspertrack = geo->sectors; blkio->disc_record->d.heads = geo->heads - (blkio->disc_record->d.lowsector & 0x40 ? 1 : 0); blkio->disc_record->d.disc_size_high = sectors >> (32 - log2secsize); blkio->disc_record->d.disc_size = sectors << log2secsize; } dbg_printf("-geometry: [secsz=%d, sec/tk=%d, hds=%d, cyls=%d]", geo->sector_size, geo->sectors, geo->heads, geo->cylinders); } /* Function: blkio_t *blkio_open (const char *dev_name) * Purpose : Open a device, specified in dev_name and return a structure * Params : dev_name - device name (eg, ADFS::4, /dev/hda etc) * Returns : pointer to above structure (to be used by all other calls) */ blkio_t *blkio_open (const char *dev_name) { /* On RiscOS, dev_name is something like 'ADFS::4....' */ blkio_t *blkio = NULL; char fs_name[MAX_FS_NAME], drive_name[MAX_DRIVE_NAME]; assert (dev_name != NULL); assert (sizeof (union disc_record) >= 64); dbg_printf ("blkio_open(%s)", dev_name); dbg_level_up (); do { if (!split_fs_name (dev_name, fs_name, drive_name)) { set_error ("Invalid filesystem name `%s'", dev_name); break; } dbg_printf ("-filesystem '%s' drive '%s'", fs_name, drive_name); blkio = zmalloc (sizeof (blkio_t)); if (blkio == NULL) break; blkio->swi_describedisc = swi_number (fs_name, "DescribeDisc"); blkio->swi_discop = swi_number (fs_name, "DiscOp"); blkio->swi_sectorop = swi_number (fs_name, "SectorOp"); if (blkio->swi_sectorop == 0) blkio->swi_sectorop = swi_number (fs_name, "SectorDiscOp"); blkio->swi_controllertype = swi_number (fs_name, "ControllerType"); blkio->swi_ideuserop = swi_number (fs_name, "IDEUserOp"); dbg_printf ("-swis: DescribeDisc 0x%05X, DiscOp 0x%05X, SectorOp 0x%05X", blkio->swi_describedisc, blkio->swi_discop, blkio->swi_sectorop); dbg_printf ("-swis: ControllerType 0x%05X, IDEUserOp 0x%05X", blkio->swi_controllertype, blkio->swi_ideuserop); if (blkio->swi_describedisc == 0) { set_error ("Bad filesystem type name `%s'", fs_name); free (blkio); blkio = NULL; break; } blkio->disc_record = zmalloc (sizeof (union disc_record)); if (!blkio->disc_record) { free (blkio); blkio = NULL; break; } if (swix (blkio->swi_describedisc, rin(r0|r1), drive_name, blkio->disc_record)) { set_error ("Invalid filesystem drive name `%s'", drive_name); free (blkio->disc_record); free (blkio); blkio = NULL; break; } blkio->drive = (blkio->disc_record->d.root >> 29) & 7; blkio->blocksize = 1 << blkio->disc_record->d.log2secsize; dbg_printf ("-disc_record: [secsz=%d, sec/tk=%d, hds=%d, ds=0x%08X%08X%s drv=%d]", blkio->blocksize, blkio->disc_record->d.secspertrack, blkio->disc_record->d.heads, blkio->disc_record->d.disc_size_high, blkio->disc_record->d.disc_size, blkio->disc_record->d.big_flag ? " big" : "", blkio->drive); set_disc_geometry (blkio, &blkio->geometry); dbg_printf ("-new disc record: [secsz=%d, sec/tk=%d, hds=%d, ds=0x%08X%08X%s drv=%d]", blkio->blocksize, blkio->disc_record->d.secspertrack, blkio->disc_record->d.heads, blkio->disc_record->d.disc_size_high, blkio->disc_record->d.disc_size, blkio->disc_record->d.big_flag ? " big" : "", blkio->drive); } while (0); dbg_level_down(); dbg_printf ("ret=%p", blkio); return blkio; } #endif #ifdef UNIX #include #include #include #ifdef linux #include #endif /* Function: blkio_t *blkio_open (const char *dev_name) * Purpose : Open a device, specified in dev_name and return a structure * Params : dev_name - device name (eg, ADFS::4, /dev/hda etc) * Returns : pointer to above structure (to be used by all other calls) */ blkio_t *blkio_open (const char *dev_name) { /* On RiscOS, dev_name is something like 'ADFS::4....' */ blkio_t *blkio = NULL; assert (dev_name != NULL); assert (sizeof (union disc_record) >= 64); dbg_printf ("blkio_open(%s)", dev_name); dbg_level_up (); do { struct hd_geometry geometry; blkio = zmalloc (sizeof (blkio_t)); if (blkio == NULL) break; blkio->fd = open(dev_name, O_RDWR); if (blkio->fd == (u_int)-1) blkio->fd = open(dev_name, O_RDONLY); if (blkio->fd == (u_int)-1) { set_error ("%s", strerror(errno)); free(blkio); blkio = NULL; break; } if (!ioctl(blkio->fd, HDIO_GETGEO, &geometry)) { blkio->geometry.cylinders = geometry.cylinders; blkio->geometry.heads = geometry.heads; blkio->geometry.sectors = geometry.sectors; blkio->geometry.sector_size = 512; blkio->geometry.log2secsize = 9; } else { blkio->geometry.cylinders = 1024; blkio->geometry.heads = 16; blkio->geometry.sectors = 63; blkio->geometry.sector_size = 512; blkio->geometry.log2secsize = 9; } blkio->blocksize = 512; dbg_printf("-geometry: [secsz=%d, sec/tk=%d, hds=%d, cyls=%d]", blkio->geometry.sector_size, blkio->geometry.sectors, blkio->geometry.heads, blkio->geometry.cylinders); } while (0); dbg_level_down(); dbg_printf ("ret=%p", blkio); return blkio; } #endif acorn-fdisk-3.0.6.orig/lib/blkio/read.c0100644000000000000000000000626707003311404016306 0ustar rootroot/* * blkio/read.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Read data from device on RiscOS architecture */ #include "util/debug.h" #include "util/error.h" #include "blkio.h" #include "filecore.h" #ifdef RISCOS #include "!Swi.h" static u_int read_block(blkio_t *blkio, void *data, blk_t block, u_int nr_blocks) { _kernel_oserror *ret; u_int swino, sector, nr, limit, res = 0; const char *what, *swiname; if (blkio->swi_sectorop) { swino = blkio->swi_sectorop; sector = block * (blkio->blocksize >> blkio->disc_record->d.log2secsize); nr = nr_blocks * blkio->blocksize; limit = 0x20000000; what = "sectoraddr"; swiname = "sectorop"; } else { swino = blkio->swi_discop; sector = block * blkio->blocksize; nr = nr_blocks * blkio->blocksize; limit = 0x20000000 / blkio->blocksize; what = "discaddr"; swiname = "discop"; } do { if (block + nr >= limit) { set_error("Unable to access block 0x%X above limit 0x%X", what, block, limit); break; } dbg_printf("-%s: [r1=0x%X r2=0x%X r3=%p r4=0x%X]", swiname, (((unsigned int)blkio->disc_record) << 6)|1, (blkio->drive << 29) | (sector & 0x1fffffff), data, nr); ret = swix(swino, rin(r1|r2|r3|r4), (((unsigned int)blkio->disc_record) << 6)|1, (blkio->drive << 29) | (sector & 0x1fffffff), data, nr); if (ret) { set_error("%s", ret->errmess); break; } res = nr_blocks; } while (0); return res; } #endif #ifdef UNIX #include #include #undef SYS__llseek #define SYS__llseek (__NR__llseek - __NR_SYSCALL_BASE) static inline _syscall5(int,_llseek,int,fd,u_int,off_high,u_int,off_low,loff_t *,loff,int,whence); static loff_t my_llseek(int fd, loff_t off, int whence) { u_int off_high, off_low; off_high = off >> 32; off_low = off & 0xffffffff; _llseek(fd, off_high, off_low, &off, whence); return off; } static u_int read_block(blkio_t *blkio, void *data, blk_t block, u_int nr_blocks) { u_int len, res = 0; loff_t loff; loff = (loff_t)block * blkio->blocksize; len = nr_blocks * blkio->blocksize; do { if (my_llseek(blkio->fd, loff, SEEK_SET) != loff) break; if (read(blkio->fd, data, len) != len) break; res = nr_blocks; } while (0); return res; } #endif /* Function: u_int blkio_read (blkio_t *blkio, void *data, blk_t block, u_int nr_blocks) * Purpose : Read `nr_blocks' blocks starting at `block' from the device previously opened * with blkio_open into memory area `data' * Params : blkio - structure returned by blkio_open * : data - memory area to read into * : block - block number to read * : nr_blocks - number of blocks to read * Returns : number of blocks actually read */ u_int blkio_read (blkio_t *blkio, void *data, blk_t block, u_int nr_blocks) { u_int res; dbg_printf("blkio_read(%p 0x%X +0x%X)", data, block, nr_blocks); dbg_level_up(); dbg_printf("-blocksize=0x%X", blkio->blocksize); res = read_block(blkio, data, block, nr_blocks); dbg_level_down(); dbg_printf("ret=%d", res); return res; } acorn-fdisk-3.0.6.orig/lib/blkio/setblocksz.c0100644000000000000000000000170506503056053017560 0ustar rootroot/* * blkio/setblocksz.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Close a device on RiscOS architecture */ #include #include #include "util/debug.h" #include "blkio.h" #include "filecore.h" /* Function: u_int blkio_setblocksize (blkio_t *blkio, u_int blocksize) * Purpose : Set the block size for all subsequent block IO routines * Params : blkio - structure returned by blkio_open * : blocksize - new block size to use * Returns : block size that will be used */ u_int blkio_setblocksize (blkio_t *blkio, u_int blocksize) { assert (blkio != NULL); dbg_printf ("blkio_setblocksize(%d)", blocksize); #ifdef RISCOS if (blocksize < (1 << blkio->disc_record->d.log2secsize)) blocksize = (1 << blkio->disc_record->d.log2secsize); #endif blkio->blocksize = blocksize; dbg_printf ("ret=%d", blocksize); return blocksize; } acorn-fdisk-3.0.6.orig/lib/blkio/setgeo.c0100644000000000000000000000314006503055513016656 0ustar rootroot/* * blkio/setgeometry.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Close a device on RiscOS architecture */ #include #include #include "util/debug.h" #include "blkio.h" #include "filecore.h" /* Function: u_int blkio_setgeometry (blkio_t *blkio, geometry_t *geo) * Purpose : Return the geometry for the device opened with blkio_open * Params : blkio - structure returned by blkio_open * : geo - pointer to geometry structure */ u_int blkio_setgeometry (blkio_t *blkio, const geometry_t *geo) { u_int log2secsize, sectors, ret = 0; assert (blkio != NULL); assert (geo != NULL); dbg_printf ("blkio_setgeometry([sector_size=%d, sectors=%d, heads=%d, cylinders=%d])", geo->sector_size, geo->sectors, geo->heads, geo->cylinders); dbg_level_up (); blkio->geometry = *geo; #if defined(RISCOS) log2secsize = blkio->disc_record->d.log2secsize; if (geo->sector_size == 1 << log2secsize) { sectors = geo->cylinders * geo->heads * geo->sectors; blkio->disc_record->d.secspertrack = geo->sectors; blkio->disc_record->d.heads = geo->heads - (blkio->disc_record->d.lowsector & 0x40 ? 1 : 0); blkio->disc_record->d.disc_size_high = sectors >> (32 - log2secsize); blkio->disc_record->d.disc_size = sectors << log2secsize; dbg_printf ("-disc_record: ds=0x%08X%08X", blkio->disc_record->d.disc_size_high, blkio->disc_record->d.disc_size); ret = !0; } #endif #ifdef UNIX ret = !0; #endif dbg_level_down (); dbg_printf ("ret=%d", ret); return ret; } acorn-fdisk-3.0.6.orig/lib/blkio/write.c0100644000000000000000000000625107003311576016530 0ustar rootroot/* * blkio/read.c * * Copyright (C) 1998 Russell King * * The block I/O interface allows an OS-independent method to access devices * * Write data to device on RiscOS architecture */ #include "util/debug.h" #include "util/error.h" #include "blkio.h" #include "filecore.h" #ifdef RISCOS #include "!Swi.h" static u_int write_block(blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks) { _kernel_oserror *ret; u_int swino, sector, nr, limit, res = 0; const char *what, *swiname; if (blkio->swi_sectorop) { swino = blkio->swi_sectorop; sector = block * (blkio->blocksize >> blkio->disc_record->d.log2secsize); nr = nr_blocks * blkio->blocksize; limit = 0x20000000; what = "sector"; swiname = "sectorop"; } else { swino = blkio->swi_discop; sector = block * blkio->blocksize; nr = nr_blocks * blkio->blocksize; limit = 0x20000000 / blkio->blocksize; what = "discaddr"; swiname = "discop"; } do { if (block >= limit) { set_error ("Unable to write %s 0x%X above limit 0x%X", what, block, limit); break; } dbg_printf ("-%s: [r1=0x%X r2=0x%X r3=%p r4=0x%X]", swiname, (((unsigned int)blkio->disc_record) << 6)|2, (blkio->drive << 29) | (sector & 0x1fffffff), data, nr); ret = swix (swino, rin(r1|r2|r3|r4), (((unsigned int)blkio->disc_record) << 6)|2, (blkio->drive << 29) | (sector & 0x1fffffff), data, nr); if (ret) { set_error ("%s", ret->errmess); break; } res = nr_blocks; } while (0); return res; } #endif #ifdef UNIX #include #include #undef SYS__llseek #define SYS__llseek (__NR__llseek - __NR_SYSCALL_BASE) static inline _syscall5(int,_llseek,int,fd,u_int,off_high,u_int,off_low,loff_t *,loff,int,whence); static loff_t my_llseek(int fd, loff_t off, int whence) { u_int off_high, off_low; off_high = off >> 32; off_low = off & 0xffffffff; _llseek(fd, off_high, off_low, &off, whence); return off; } static u_int write_block(blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks) { u_int len, res = 0; loff_t loff; loff = (loff_t)block * blkio->blocksize; len = nr_blocks * blkio->blocksize; do { if (my_llseek(blkio->fd, loff, SEEK_SET) != loff) break; if (write(blkio->fd, data, len) != len) break; res = nr_blocks; } while (0); return res; } #endif /* Function: u_int blkio_write (blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks) * Purpose : Write `nr_blocks' blocks starting at `block' from the device previously opened * with blkio_open into memory area `data' * Params : blkio - structure returned by blkio_open * : data - memory area to write data from * : block - block number to write * : nr_blocks - number of blocks to write * Returns : number of blocks actually written */ u_int blkio_write (blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks) { u_int res; dbg_printf ("blkio_write(%p 0x%X +0x%X)", data, block, nr_blocks); dbg_level_up (); res = write_block(blkio, data, block, nr_blocks); dbg_level_down (); dbg_printf ("ret=%d", res); return res; } acorn-fdisk-3.0.6.orig/lib/blkio/blkio.h0100644000000000000000000000735106473631254016515 0ustar rootroot/* * blkio/blkio.h * * Copyright (C) 1998 Russell King * * The block I/O interface allows a OS-independent method to access devices * * Public structures for block I/O based routines */ #ifndef BLKIO_BLKIO_H #define BLKIO_BLKIO_H #include "util/types.h" typedef u_int blk_t; typedef struct { u_int cylinders; u_int heads; u_int sectors; u_int sector_size; /* read-only! */ u_int log2secsize; /* read-only! */ } geometry_t; typedef struct { #ifdef UNIX /* Unix specific I/O data */ int fd; /* File descriptor */ #endif #ifdef RISCOS /* RiscOS specific I/O data */ u_int swi_describedisc; /* SWI number for xxx_DescribeDisc */ u_int swi_discop; /* SWI number for xxx_DiscOp */ u_int swi_sectorop; /* SWI number for xxx_SectorOp */ u_int swi_controllertype; /* SWI number for xxx_ControllerType */ u_int swi_ideuserop; /* SWI number for xxx_IDEUserOp */ union disc_record *disc_record; /* Disc Record to pass with DiscOp/SectorOp */ u_int drive; #endif geometry_t geometry; int blocksize; /* Size of a block */ } blkio_t; /* Function: blkio_t *blkio_close (blkio_t *blkio) * Purpose : close a device previously opened with blkio_open * Params : blkio - structure returned by blkio_open * Returns : NULL */ extern blkio_t *blkio_close (blkio_t *blkio); /* Function: u_int blkio_getgeometry (blkio_t *blkio, geometry_t *geo) * Purpose : Return the geometry for the device opened with blkio_open * Params : blkio - structure returned by blkio_open * : geo - pointer to geometry structure */ extern u_int blkio_getgeometry (blkio_t *blkio, geometry_t *geo); /* Function: blkio_t *blkio_open (const char *dev_name) * Purpose : Open a device, specified in dev_name and return a structure * Params : dev_name - device name (eg, ADFS::4, /dev/hda etc) * Returns : pointer to above structure (to be used by all other calls) */ extern blkio_t *blkio_open (const char *dev_name); /* Function: u_int blkio_setblocksize (blkio_t *blkio, u_int blocksize) * Purpose : Set the block size for all subsequent block IO routines * Params : blkio - structure returned by blkio_open * : blocksize - new block size to use * Returns : block size that will be used */ extern u_int blkio_setblocksize (blkio_t *blkio, u_int blocksize); /* Function: u_int blkio_setgeometry (blkio_t *blkio, geometry_t *geo) * Purpose : Set the geometry for the device opened with blkio_open * Params : blkio - structure returned by blkio_open * : geo - pointer to geometry structure */ extern u_int blkio_setgeometry (blkio_t *blkio, const geometry_t *geo); /* Function: u_int blkio_read (blkio_t *blkio, void *data, blk_t block, u_int nr_blocks) * Purpose : Read `nr_blocks' blocks starting at `block' from the device previously opened * with blkio_open into memory area `data' * Params : blkio - structure returned by blkio_open * : data - memory area to read into * : block - block number to read * : nr_blocks - number of blocks to read * Returns : number of blocks actually read */ extern u_int blkio_read (blkio_t *blkio, void *data, blk_t block, u_int nr_blocks); /* Function: u_int blkio_write (blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks) * Purpose : Write `nr_blocks' blocks starting at `block' from the device previously opened * with blkio_open into memory area `data' * Params : blkio - structure returned by blkio_open * : data - memory area to write data from * : block - block number to write * : nr_blocks - number of blocks to write * Returns : number of blocks actually written */ extern u_int blkio_write (blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks); #endif acorn-fdisk-3.0.6.orig/lib/blkio/Makefile0100644000000000000000000000043106722736175016701 0ustar rootrootAR = ar CC = cc ARFLAGS = rc CFLAGS = -DUNIX -O2 -Wall -I.. -g OBJS = close.o getgeo.o open.o read.o setblocksz.o setgeo.o write.o LIB = ../blkio.a all: $(LIB) clean:; $(RM) $(LIB) *.o $(LIB): $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) .c.o:; $(CC) $(CFLAGS) -o $@ -c $< acorn-fdisk-3.0.6.orig/lib/blkio/filecore.h0100644000000000000000000000206206473631204017172 0ustar rootroot/* * Structure of a filecore disc record */ #ifndef BLKIO_FILECORE_H #define BLKIO_FILECORE_H #include "util/types.h" #define FILECORE_BOOT_SECTOR 6 #define FILECORE_SECTOR_SIZE 512 typedef union disc_record { struct { u8 log2secsize; /* sector size */ u8 secspertrack; /* sectors per track */ u8 heads; /* number of heads */ u8 density; /* density of disk */ u8 idlen; u8 log2bpmb; /* bits per map bit */ u8 skew; u8 bootoption; /* boot option */ u8 lowsector; /* lowest numbered sector on track */ u8 nzones; /* number of map zones */ u16 zone_spare; u32 root; /* address of root directory */ u32 disc_size; /* disc size low word */ u16 disc_id; /* disc cycle id */ u8 disc_name[10]; /* disc name */ u32 disctype; /* disc type */ u32 disc_size_high; /* disc size high word */ unsigned int share_size : 4, /* granularity of directory sharing */ unused : 4, big_flag : 1, /* 1: use LBA mode */ unused2 : 23; } d; u8 packing[64]; } disc_record_t; #endif acorn-fdisk-3.0.6.orig/lib/part/0042755000000000000000000000000007101375523015102 5ustar rootrootacorn-fdisk-3.0.6.orig/lib/part/allocate.c0100644000000000000000000000353206475777540017052 0ustar rootroot/* * lib/part/create.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" /* Prototype: u_int part_create(part_t *part, partinfo_t *pinfo) * Function : Allocate a new partition slot `parn' and kernel partition number. * Params : part - partitionable device * : parn - partition number, or PARN_ALLOCATE to use first slot * : pinfo - partition info structure to set new partition as * Returns : FALSE on error * Notes : Do not alter any structures on disk. */ u_int part_allocate(part_t *part, partinfo_t *pinfo) { u_int parn; assert(part != NULL); assert(part->scheme != NULL); assert(pinfo != NULL); dbg_printf("part_allocate(pinfo=[bs=0x%X, be=0x%X, type=0x%X])", pinfo->blk_start, pinfo->blk_end, pinfo->type); dbg_level_up(); clear_error(); do { parn = part->scheme->allocate(part, pinfo); if (parn == PARN_ERROR) { if (!is_error_set()) set_error("unable to allocate slot for partition"); break; } if (part->scheme->validate_partno(part, parn)) { if (part->nr_partitions == 0 || parn >= part->nr_partitions) { partinfo_i_t **p; u_int new_nr = parn + 1; p = malloc(new_nr * sizeof(*p)); if (p) { memset(p, 0, new_nr * sizeof(*p)); memcpy(p, part->partinfo, part->nr_partitions * sizeof(*p)); free(part->partinfo); part->partinfo = p; part->nr_partitions = new_nr; } else { set_error("out of memory"); break; } } } else if (!is_error_set()) set_error("invalid partition number %d", parn); } while (0); dbg_level_down(); dbg_printf("ret=%d (kern_part_no=%d)", parn, pinfo->kern_part_no); return parn; } acorn-fdisk-3.0.6.orig/lib/part/close.c0100644000000000000000000000124406453223276016355 0ustar rootroot/* * lib/part/close.c * * Copyright (C) 1997,1998 Russell King */ #include #include "util/debug.h" #include "part/part.h" /* Prototype: part_t *part_close (part_t *part) * Function : Close and free all memory associated with this partition device. * Params : part - partitionable device to close * Returns : NULL * Notes : If changes are outstanding, discard the changes. */ part_t *part_close (part_t *part) { dbg_printf ("part_close()"); dbg_level_up (); if (part) { blkio_close (part->blkio); if (part->partinfo) free (part->partinfo); free (part); } dbg_level_down (); dbg_printf ("ret=NULL"); return NULL; } acorn-fdisk-3.0.6.orig/lib/part/create.c0100644000000000000000000000456306476050072016517 0ustar rootroot/* * lib/part/create.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" /* Prototype: u_int part_create(part_t *part, u_int parn, const partinfo_t *pinfo) * Function : Create a new partition in slot `parn' described by pinfo. * Params : part - partitionable device * : parn - partition number, or PARN_ALLOCATE to use first slot * : pinfo - partition info structure to set new partition as * Returns : FALSE on error * Notes : If it already exists, complain. Do not alter any structures on disk. */ u_int part_create(part_t *part, u_int parn, const partinfo_t *pinfo) { partinfo_t pnew; u_int ret = 0; assert(part != NULL); assert(part->scheme != NULL); assert(pinfo != NULL); pnew = *pinfo; dbg_printf("part_create(parn=%d, pinfo=[bs=0x%X, be=0x%X, type=0x%X])", parn, pnew.blk_start, pnew.blk_end, pnew.type); dbg_level_up(); clear_error(); do { if (!part_updatechs(part, &pnew)) break; if (parn == PARN_ALLOCATE) parn = part->scheme->allocate(part, &pnew); if (parn == PARN_ERROR) { if (!is_error_set()) set_error("unable to allocate slot for partition"); break; } if (part->scheme->validate_partno(part, parn)) { if (part->nr_partitions == 0 || parn >= part->nr_partitions) { partinfo_i_t **p; u_int new_nr = parn + 1; p = malloc(new_nr * sizeof(*p)); if (p) { memset(p, 0, new_nr * sizeof(*p)); memcpy(p, part->partinfo, part->nr_partitions * sizeof(*p)); free(part->partinfo); part->partinfo = p; part->nr_partitions = new_nr; } else { set_error("out of memory"); break; } } if (part->scheme->validate_creation(part, parn, part->partinfo[parn] ? &part->partinfo[parn]->info : NULL, &pnew)) { if (!part->partinfo[parn]) part->partinfo[parn] = malloc(sizeof(partinfo_i_t)); if (part->partinfo[parn]) { part->partinfo[parn]->changed = 1; part->partinfo[parn]->info = pnew; ret = 1; } } } else if (!is_error_set()) set_error("invalid partition number %d", parn); } while (0); dbg_level_down(); dbg_printf("ret=%d", ret); return ret; } acorn-fdisk-3.0.6.orig/lib/part/delete.c0100644000000000000000000000201006473604276016507 0ustar rootroot/* * lib/part/delete.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" /* Prototype: u_int part_delete (part_t *part, u_int parn) * Function : Delete partition `parn'. * Params : part - partitionable device * : parn - partition number * Returns : FALSE on error * Notes : Do not alter any structures on disk. */ u_int part_delete(part_t *part, u_int parn) { u_int ret = 0; assert(part != NULL); assert(part->nr_partitions && parn < part->nr_partitions); dbg_printf("part_delete(%d)", parn); dbg_level_up(); clear_error(); if (part->partinfo[parn] && part->scheme->validate_deletion(part, parn, &part->partinfo[parn]->info)) { free (part->partinfo[parn]); part->partinfo[parn] = NULL; ret = 1; } if (ret == 0 && !is_error_set()) set_error("partition cannot be deleted"); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } acorn-fdisk-3.0.6.orig/lib/part/getgeo.c0100644000000000000000000000134306453420340016511 0ustar rootroot/* * lib/part/getgeo.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "part/part.h" /* Prototype: u_int part_getgeometry (part_t *part, geometry_t *geo) * Function : Get the geometry of the drive. * Params : part - partitionable device * : geo - geometry structure * Returns : FALSE on error * Notes : Returns blkio's idea of geometry */ u_int part_getgeometry (part_t *part, geometry_t *geo) { u_int ret; assert(part != NULL); assert(geo != NULL); dbg_printf("part_getgeometry()"); dbg_level_up(); ret = blkio_getgeometry(part->blkio, geo); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } acorn-fdisk-3.0.6.orig/lib/part/getpinfo.c0100644000000000000000000000224706473650704017071 0ustar rootroot/* * lib/part/getpinfo.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" /* Prototype: u_int part_getpartinfo (part_t *part, u_int parn, partinfo_t *pinfo) * Function : Get the partition details for partition `parn'. * Params : part - partitionable device * : parn - partition number * : pinfo - partition info structure to fill out * Returns : FALSE on error */ u_int part_getpartinfo(part_t *part, u_int parn, partinfo_t *pinfo) { u_int ret = 0; assert(part != NULL); assert(pinfo != NULL); dbg_printf("part_getpartinfo(parn=%d)", parn); dbg_level_up(); if (part->nr_partitions && parn < part->nr_partitions) { if (part->partinfo[parn]) *pinfo = part->partinfo[parn]->info; else memset (pinfo, 0, sizeof (*pinfo)); ret = 1; } else set_error("invalid partition number %d", parn); dbg_level_down(); if (ret) dbg_printf("ret ok, pinfo=[bs=0x%X, be=0x%X, type=0x%X]", pinfo->blk_start, pinfo->blk_end, pinfo->type); else dbg_printf("ret error"); return ret; } acorn-fdisk-3.0.6.orig/lib/part/getscheme.c0100644000000000000000000000073006453277072017216 0ustar rootroot/* * lib/part/getscheme.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "part/part.h" /* Prototype: const char *part_getscheme (part_t *part) * Function : Get the partitioning scheme name. * Params : part - partitionable device * Returns : pointer to a string describing scheme, or NULL */ const char *part_getscheme(part_t *part) { assert(part != NULL); return part->scheme ? part->scheme->name : NULL; } acorn-fdisk-3.0.6.orig/lib/part/open.c0100644000000000000000000000474006562261172016213 0ustar rootroot/* * lib/part/open.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" static scheme_t *schemes[] = { &eesox_scheme, &icside_scheme, &powertec_scheme, &filecore_linux_scheme, &filecore_riscix_scheme, &pcbios_scheme, NULL }; /* Prototype: part_t *part_open (const char *dev_name, const char *part_scheme) * Function : Open a device. * Params : dev_name - OS specific device name * : part_scheme - partitioning scheme * Returns : pointer to part_t structure * Notes : Reads all partitioning data on the drive */ part_t *part_open(const char *dev_name, const char *part_scheme) { part_t *part = NULL; assert(dev_name != NULL); dbg_printf("part_open(dev_name=%s, part_scheme=%s)", dev_name, part_scheme ? part_scheme : ""); dbg_level_up(); do { scheme_t *scheme; part = malloc(sizeof (part_t)); if (!part) { set_error("out of memory"); break; } memset(part, 0, sizeof (part_t)); /* * open the device */ part->blkio = blkio_open(dev_name); if (!part->blkio) { free(part); part = NULL; break; } /* * Detect partitioning scheme */ if (!part_scheme) { scheme_t **sp; /* detect scheme */ for (sp = schemes; (scheme = *sp) != NULL; sp++) if (scheme->detect(part)) break; } else { scheme_t **sp; u_int scheme_len = strlen (part_scheme); u_int matches = 0; /* find named scheme */ for (sp = schemes; (scheme = *sp) != NULL; sp++) if (strncasecmp(scheme->name, part_scheme, scheme_len) == 0) { matches ++; if (scheme->detect(part)) break; } if (!scheme && matches == 1) { for (sp = schemes; (scheme = *sp) != NULL; sp++) if (strncasecmp(scheme->name, part_scheme, scheme_len) == 0) break; } } if (!scheme) { blkio_close(part->blkio); free(part); part = NULL; set_error("partitioning scheme not recognised"); break; } /* * read partition data */ if (!scheme->readinfo(part)) { blkio_close (part->blkio); free(part); part = NULL; set_error("unable to read partition tables"); break; } part->scheme = scheme; } while(0); dbg_level_down(); dbg_printf("ret=%p", part); return part; } acorn-fdisk-3.0.6.orig/lib/part/read.c0100644000000000000000000000231706473651006016163 0ustar rootroot/* * lib/part/read.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "part/part.h" /* Prototype: u_int part_read (part_t *part, u_int parn, void *data, blk_t blk, u_int nr_blks) * Function : Read blocks from a partition * Params : part - partitionable device * : parn - partition number * : data - data area to read into * : blk - starting block * : nr_blks - number of blocks to read * Returns : actual number of blocks read */ u_int part_read(part_t *part, u_int parn, void *data, blk_t blk, u_int nr_blks) { partinfo_i_t *pinfo; u_int ret = 0; assert(part != NULL); assert(part->nr_partitions && parn < part->nr_partitions); assert(data != NULL); dbg_printf("part_read(parn=%d, data=%p, blk=0x%X, nr=0x%X)", parn, data, blk, nr_blks); dbg_level_up(); pinfo = part->partinfo[parn]; if (pinfo) { blk += pinfo->info.blk_start; if (nr_blks <= (pinfo->info.blk_end - pinfo->info.blk_start) && blk < (pinfo->info.blk_end - nr_blks)) ret = blkio_read(part->blkio, data, blk, nr_blks); } dbg_level_down(); dbg_printf("ret=%d", ret); return ret; } acorn-fdisk-3.0.6.orig/lib/part/setgeo.c0100644000000000000000000000202106476046766016544 0ustar rootroot/* * lib/part/setgeo.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "part/part.h" /* Prototype: u_int part_setgeometry (part_t *part, const geometry_t *geo) * Function : Set the geometry of the drive * Params : part - partitionable device * : geo - geometry * Returns : FALSE on error * Notes : This does not set the geometry that the OS' idea of the geometry. * : This recalculates the CHS values for all partitions. */ u_int part_setgeometry(part_t *part, const geometry_t *geo) { u_int ret; assert(part != NULL); assert(geo != NULL); dbg_printf("part_setgeometry()"); dbg_level_up(); ret = blkio_setgeometry(part->blkio, geo); if (ret) { u_int i; for (i = 0; i < part->nr_partitions; i++) if (part->partinfo[i]) { part->partinfo[i]->info.chs_valid = 0; part_updatechs(part, &part->partinfo[i]->info); } } dbg_level_down(); dbg_printf("ret=%d", ret); return ret; } acorn-fdisk-3.0.6.orig/lib/part/setpinfo.c0100644000000000000000000000257206476115430017101 0ustar rootroot/* * lib/part/setpinfo.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" /* Prototype: u_int part_setpartinfo (part_t *part, u_int parn, const partinfo_t *pinfo) * Function : Set partition details for partition * Params : part - partitionable device * : parn - partition number * : pinfo - partition info structure to set partition * Returns : FALSE on error */ u_int part_setpartinfo(part_t *part, u_int parn, const partinfo_t *pinfo) { partinfo_t pnew; u_int ret = 0; assert(part != NULL); assert(part->nr_partitions && parn < part->nr_partitions); assert(pinfo != NULL); assert(part->scheme); pnew = *pinfo; dbg_printf("part_setpartinfo(parn=%d, pinfo=[bs=0x%X, be=0x%X, type=0x%X])", parn, pinfo->blk_start, pinfo->blk_end, pinfo->type); dbg_level_up(); do { if (!part_updatechs(part, &pnew)) break; if (part->partinfo[parn]) { ret = part->scheme->validate_change(part, parn, &part->partinfo[parn]->info, &pnew); if (ret) { part->partinfo[parn]->info = pnew; part->partinfo[parn]->changed = 1; } } else set_error("no partition defined for partition %d", parn); } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } acorn-fdisk-3.0.6.orig/lib/part/sync.c0100644000000000000000000000140606503056240016213 0ustar rootroot/* * lib/part/sync.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" /* Prototype: u_int part_sync (part_t *part) * Function : Synchronise (write) partition information with disk. * Params : part - partitionable device * Returns : FALSE on error */ u_int part_sync (part_t *part) { u_int ret = 0; assert (part != NULL); assert (part->scheme != NULL); dbg_printf ("part_sync()"); dbg_level_up(); if (part->scheme->writeinfo) ret = part->scheme->writeinfo(part); else set_error("partition style does not support writing of partition information"); dbg_level_down(); dbg_printf ("ret %sok", ret ? "" : "not "); return ret; } acorn-fdisk-3.0.6.orig/lib/part/types.c0100644000000000000000000000702006500324066016402 0ustar rootroot/* * lib/part/types.c * * Copyright (C) 1998 Russell King */ #include #include #include #include #include "util/debug.h" #include "part/part.h" static const struct { ptyp_t type; const char *name; } part_types[] = { /* * If a partition type is not listed in this * table, then the following function will * assert. Keep this table up to date! */ { ptyp_none, "None" }, { ptyp_dos12, "DOS-12" }, { ptyp_xenixroot, "XENIX root" }, { ptyp_xenixusr, "XENIX /usr" }, { ptyp_dos16l32, "DOS-16 < 32MB" }, { ptyp_dos_extended, "DOS Extended" }, { ptyp_dos16g32, "DOS-16 >= 32MB" }, { ptyp_hpfs, "HPFS" }, { ptyp_aix, "AIX" }, { ptyp_aixboot, "AIX Boot" }, { ptyp_os2, "OS/2" }, { ptyp_win98_extended,"Win98 Extended" }, { ptyp_venix, "VENIX" }, { ptyp_novell, "Novel" }, { ptyp_dm6_aux1, "DM6 Aux1" }, { ptyp_microport, "MicroPort" }, { ptyp_dm6_aux3, "DM6 Aux3" }, { ptyp_dm6, "Disk Manager 6" }, { ptyp_ezdrive, "EZ-Drive" }, { ptyp_gnuhurd, "GNU Hurd" }, { ptyp_novelnet286, "NovelNet 286" }, { ptyp_novelnet386, "NovelNet 386" }, { ptyp_pcix, "PCiX" }, { ptyp_old_minix, "Old MINIX" }, { ptyp_minix, "Minix" }, { ptyp_linux_swap, "Linux Swap" }, { ptyp_linux_native, "Linux Native" }, { ptyp_linux_extended,"Linux Extended" }, { ptyp_amoeba, "AMOEBA" }, { ptyp_amoebabbt, "AMOEBA BBT" }, { ptyp_bsd386, "BSD 386" }, { ptyp_bsdifs, "BSDi FS" }, { ptyp_bsdiswap, "BSDi Swap" }, { ptyp_syrinx, "Syrinx" }, { ptyp_cpm, "CP/M" }, { ptyp_dosaccess, "DOS Access" }, { ptyp_dosro, "DOS R/O" }, { ptyp_dosscc, "DOS SCC" }, { ptyp_bbt, "Bad Block Table" }, { ptyp_filecore, "Filecore" }, { ptyp_linux_table, "Linux Table" }, { ptyp_pc_table, "BIOS Table" }, { ptyp_pt_oldmap, "Filecore OldMap" }, { ptyp_pt_backup, "PowerTec Backup" }, { ptyp_pt_empty, "Empty" }, { ptyp_unknown, "Unknown" }, { ptyp_none, NULL } }; /* Prototype: const char *part_typename(part_t *part, ptyp_t type) * Purpose : Return the name of the partition type 'type' * Params : part - partitionable device * : type - partition type * Returns : const pointer to NUL terminated string */ const char *part_typename(part_t *part, ptyp_t type) { static char buf[32]; const char *name; u_int i; for (i = 0; part_types[i].name; i++) if (part_types[i].type == type) break; if (part_types[i].name) name = part_types[i].name; else { sprintf(buf, "Unknown type %d", type); name = buf; } return name; } /* Prototype: ptyp_t part_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : Return the next partition type * Params : part - partiionable device * : parn - partition number * : current - current partition type * : dir - increment (+1), or decrement (-1) * Returns : next partition type */ ptyp_t part_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { static ptyp_t types[] = { ptyp_linux_swap, ptyp_linux_native, ptyp_filecore }; ptyp_t ptype; int i; #define NR_TYPES (sizeof(types)/sizeof(ptyp_t)) if (part->scheme->nexttype) ptype = part->scheme->nexttype(part, parn, current, dir); else { for(i = 0; i < NR_TYPES; i++) if (types[i] == current) break; if (types[i] == current) { i += dir; if (i < 0) i = 0; if (i >= NR_TYPES) i = NR_TYPES - 1; } ptype = types[i]; } return ptype; } acorn-fdisk-3.0.6.orig/lib/part/validops.c0100644000000000000000000000211106473603750017064 0ustar rootroot/* * lib/part/validops.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "part/part.h" /* Prototype: u_int part_validops (part_t *part, u_int parn, const partinfo_t *pinfo) * Function : Returns a bitmask containing the valid operations that can be performed * on the specified partition * Params : part - partitionable device * : parn - partition number * Returns : bitmask of valid operations */ u_int part_validops(part_t *part, u_int parn, const partinfo_t *pinfo) { u_int ret = 0; assert(part != NULL); assert(part->nr_partitions && parn < part->nr_partitions); assert(part->scheme); dbg_printf("part_validops(parn=%d)", parn); dbg_level_up(); if (part->partinfo[parn]) { if (part->scheme->validate_change(part, parn, &part->partinfo[parn]->info, pinfo)) ret |= VALIDOPS_UPDATE; if (part->scheme->validate_deletion(part, parn, &part->partinfo[parn]->info)) ret |= VALIDOPS_DELETE; } dbg_level_down(); dbg_printf("ret %X", ret); return ret; } acorn-fdisk-3.0.6.orig/lib/part/write.c0100644000000000000000000000231606473651146016406 0ustar rootroot/* * lib/part/write.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/debug.h" #include "part/part.h" /* Prototype: u_int part_write (part_t *part, u_int parn, const void *data, blk_t blk, u_int nr_blks) * Function : Write blocks to a partition * Params : part - partitionable device * : parn - parititon number * : data - data to write * : blk - starting block * : nr_blks - number of blocks * Returns : actual number of blocks read */ u_int part_write(part_t *part, u_int parn, const void *data, blk_t blk, u_int nr_blks) { partinfo_i_t *pinfo; u_int ret = 0; assert(part != NULL); assert(part->nr_partitions && parn < part->nr_partitions); assert(data != NULL); dbg_printf("part_write(parn=%d, data=%p, blk=0x%X, nr=0x%X)", parn, data, blk, nr_blks); dbg_level_up(); pinfo = part->partinfo[parn]; if (pinfo) { blk += pinfo->info.blk_start; if (nr_blks <= (pinfo->info.blk_end - pinfo->info.blk_start) && blk < (pinfo->info.blk_end - nr_blks)) ret = blkio_write(part->blkio, data, blk, nr_blks); } dbg_level_down(); dbg_printf("ret=%d", ret); return ret; } acorn-fdisk-3.0.6.orig/lib/part/part.h0100644000000000000000000002401106677130073016220 0ustar rootroot/* * lib/part/part.h * * Copyright (C) 1997,1998 Russell King */ #ifndef PART_PART_H #define PART_PART_H #include "util/types.h" #include "blkio/blkio.h" typedef struct { u_int cylinder; u_int head; u_int sector; } chs_t; typedef enum { /* PC compatible partition numbers */ ptyp_none = 0x00, /* No defined partition */ ptyp_dos12 = 0x01, /* DOS 12-bit FAT */ ptyp_xenixroot = 0x02, /* XENIX root */ ptyp_xenixusr = 0x03, /* XENIX /usr */ ptyp_dos16l32 = 0x04, /* DOS 16-bit FAT < 32MB */ ptyp_dos_extended = 0x05, /* DOS Extended partition */ ptyp_dos16g32 = 0x06, /* DOS 16-bit FAT >= 32MB */ ptyp_hpfs = 0x07, /* HPFS */ ptyp_aix = 0x08, /* AIX */ ptyp_aixboot = 0x09, /* AIX boot */ ptyp_os2 = 0x0a, /* OS/2 */ ptyp_win98_extended = 0x0f, /* Win98 extended partition */ ptyp_venix = 0x40, /* VENIX */ ptyp_novell = 0x51, /* Novell */ ptyp_dm6_aux1 = 0x51, /* Disk Manager */ ptyp_microport = 0x52, /* MicroPort */ ptyp_dm6_aux3 = 0x53, /* Disk Manager */ ptyp_dm6 = 0x54, /* Disk Manager */ ptyp_ezdrive = 0x55, /* EZ-Drive */ ptyp_gnuhurd = 0x63, /* GNU HURD */ ptyp_novelnet286 = 0x64, /* Novel Net 286 */ ptyp_novelnet386 = 0x65, /* Novel Net 386 */ ptyp_pcix = 0x75, /* PCIX */ ptyp_old_minix = 0x80, /* Old MINIX partition */ ptyp_linux_parttion = 0x80, /* Old Linux partition */ ptyp_minix = 0x81, /* MINIX partition */ ptyp_linux_swap = 0x82, /* Linux swap */ ptyp_linux_native = 0x83, /* Linux native */ ptyp_linux_extended = 0x85, /* Linux Extended */ ptyp_amoeba = 0x93, /* AMOEBA */ ptyp_amoebabbt = 0x94, /* AMOEBA bad block table */ ptyp_bsd386 = 0xa5, /* BSD 386 */ ptyp_bsdifs = 0xb7, /* BSDi FS */ ptyp_bsdiswap = 0xb8, /* BSDi Swap */ ptyp_syrinx = 0xc7, /* Syrinx */ ptyp_cpm = 0xdb, /* CP/M */ ptyp_dosaccess = 0xe1, /* DOS Access */ ptyp_dosro = 0xe3, /* DOS Read/Only */ ptyp_dosscc = 0xf2, /* DOS SCC */ ptyp_bbt = 0xff, /* Bad block table */ /* Other partition types */ ptyp_filecore = 0x100, /* RiscOS filecore partition */ ptyp_linux_table = 0x101, /* RiscOS filecore Linux partition tbl */ ptyp_pc_table = 0x102, /* PC partition table */ ptyp_pt_oldmap = 0x103, /* for PowerTec OLDMAP partitions */ ptyp_pt_backup = 0x104, /* for PowerTec BACKUP partitions */ ptyp_pt_empty = 0x105, /* for PowerTec EMPTY partitions */ ptyp_reserved = 0xfffe,/* Space used/reserved */ ptyp_unknown = 0xffff /* unrecognised partition */ } ptyp_t; /* External data structure */ typedef struct { bool_t chs_valid; /* CHS address is valid */ chs_t chs_start; /* For PC BIOS-type schemes */ chs_t chs_end; blk_t blk_start; /* For LBA block addresses */ blk_t blk_end; ptyp_t type; /* Partition type */ u_int kern_part_no; /* Kernel partition number */ } partinfo_t; #include "part/schemedata.h" typedef struct { bool_t changed; /* change flag */ partinfo_t info; /* partition information */ scheme_part_t data; /* scheme-specific data */ } partinfo_i_t; /* Internal data structure: No data should be used from this structure * in the application layer. */ typedef struct { blkio_t *blkio; /* Device */ struct scheme *scheme; /* Scheme */ scheme_data_t data; /* Scheme-specific data */ u_int nr_partitions; /* Number of partitions */ partinfo_i_t **partinfo; /* Partition info */ } part_t; #include "part/scheme.h" /* * Use this parn to tell part_create to allocate a partition number */ #define PARN_ALLOCATE (-1U) #define PARN_ERROR (-2U) #define VALIDOPS_UPDATE (1 << 0) #define VALIDOPS_DELETE (1 << 1) /* Prototype: u_int part_create(part_t *part, partinfo_t *pinfo) * Function : Allocate a new partition slot `parn' and kernel partition number. * Params : part - partitionable device * : parn - partition number, or PARN_ALLOCATE to use first slot * : pinfo - partition info structure to set new partition as * Returns : FALSE on error * Notes : Do not alter any structures on disk. */ u_int part_allocate(part_t *part, partinfo_t *pinfo); /* Prototype: part_t *part_close (part_t *part) * Function : Close and free all memory associated with this partition device. * Params : part - partitionable device to close * Returns : NULL * Notes : If changes are outstanding, discard the changes. */ extern part_t *part_close(part_t *part); /* Prototype: u_int part_create (part_t *part, u_int parn, const partinfo_t *pinfo) * Function : Create a new partition in slot `parn' described by pinfo. * Params : part - partitionable device * : parn - partition number * : pinfo - partition info structure to set new partition as * Returns : FALSE on error * Notes : If it already exists, complain. Do not alter any structures on disk. */ extern u_int part_create(part_t *part, u_int parn, const partinfo_t *pinfo); /* Prototype: u_int part_delete (part_t *part, u_int parn) * Function : Delete partition `parn'. * Params : part - partitionable device * : parn - partition number * Returns : FALSE on error * Notes : Do not alter any structures on disk. */ extern u_int part_delete(part_t *part, u_int parn); /* Prototype: u_int part_getgeometry (part_t *part, geometry_t *geo) * Function : Get the geometry of the drive. * Params : part - partitionable device * : geo - geometry structure * Returns : FALSE on error * Notes : Returns blkio's idea of geometry */ extern u_int part_getgeometry(part_t *part, geometry_t *geo); /* Prototype: u_int part_getpartinfo (part_t *part, u_int parn, partinfo_t *pinfo) * Function : Get the partition details for partition `parn'. * Params : part - partitionable device * : parn - partition number * : pinfo - partition info structure to fill out * Returns : FALSE on error */ extern u_int part_getpartinfo(part_t *part, u_int parn, partinfo_t *pinfo); /* Prototype: const char *part_getscheme (part_t *part) * Function : Get the partitioning scheme name. * Params : part - partitionable device * Returns : pointer to a string describing scheme, or NULL */ extern const char *part_getscheme(part_t *part); /* Prototype: ptyp_t part_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : Return the next partition type * Params : part - partiionable device * : parn - partition number * : current - current partition type * : dir - increment (+1), or decrement (-1) * Returns : next partition type */ extern ptyp_t part_nexttype(part_t *part, u_int parn, ptyp_t current, int dir); /* Prototype: part_t *part_open (const char *dev_name, const char *part_scheme) * Function : Open a device. * Params : dev_name - OS specific device name * : part_scheme - partitioning scheme * Returns : pointer to part_t structure * Notes : Reads all partitioning data on the drive */ extern part_t *part_open(const char *dev_name, const char *part_scheme); /* Prototype: u_int part_read (part_t *part, u_int parn, void *data, blk_t blk, u_int nr_blks) * Function : Read blocks from a partition * Params : part - partitionable device * : parn - partition number * : data - data area to read into * : blk - starting block * : nr_blks - number of blocks to read * Returns : actual number of blocks read */ extern u_int part_read(part_t *part, u_int parn, void *data, blk_t blk, u_int nr_blks); /* Prototype: u_int part_setgeometry (part_t *part, const geometry_t *geo) * Function : Set the geometry of the drive * Params : part - partitionable device * : geo - geometry * Returns : FALSE on error * Notes : This does not set the geometry that the OS' idea of the geometry. */ extern u_int part_setgeometry(part_t *part, const geometry_t *geo); /* Prototype: u_int part_setpartinfo(part_t *part, u_int parn, const partinfo_t *pinfo) * Function : Set partition details for partition * Params : part - partitionable device * : parn - partition number * : pinfo - partition info structure to set partition * Returns : FALSE on error */ extern u_int part_setpartinfo(part_t *part, u_int parn, const partinfo_t *pinfo); /* Prototype: u_int part_sync (part_t *part) * Function : Synchronise (write) partition information with disk. * Params : part - partitionable device * Returns : FALSE on error */ extern u_int part_sync(part_t *part); /* Prototype: const char *part_typename(part_t *part, ptyp_t type) * Purpose : Return the name of the partition type 'type' * Params : part - partitionable device * : type - partition type * Returns : const pointer to NUL terminated string */ extern const char *part_typename(part_t *part, ptyp_t type); /* Prototype: u_int part_updatechs(part_t *part, partinfo_t *pinfo) * Purpose : Update CHS values if they have become invalid * Params : part - partitionable device * : pinfo - partition to update * Returns : FALSE on error */ u_int part_updatechs(part_t *part, partinfo_t *pinfo); /* Prototype: u_int part_validops (part_t *part, u_int parn, const partinfo_t *pinfo) * Function : Returns a bitmask containing the valid operations that can be performed * on the specified partition * Params : part - partitionable device * : parn - partition number * Returns : bitmask of valid operations */ extern u_int part_validops(part_t *part, u_int parn, const partinfo_t *pinfo); /* Prototype: u_int part_write (part_t *part, u_int parn, const void *data, blk_t blk, u_int nr_blks) * Function : Write blocks to a partition * Params : part - partitionable device * : parn - parititon number * : data - data to write * : blk - starting block * : nr_blks - number of blocks * Returns : FALSE on error */ extern u_int part_write(part_t *part, u_int parn, const void *data, blk_t blk, u_int nr_blks); #endif acorn-fdisk-3.0.6.orig/lib/part/scheme.h0100644000000000000000000000212306476244456016526 0ustar rootroot/* * lib/part/scheme.h * * Copyright (C) 1997,1998 Russell King */ #ifndef PART_SCHEME_H #define PART_SCHEME_H #include "util/types.h" typedef struct scheme { /* scheme name */ const char *name; /* Detect partitioning scheme */ u_int (*detect)(part_t *); /* Read partition information */ u_int (*readinfo)(part_t *); /* Write partition information */ u_int (*writeinfo)(part_t *); /* allocate a partition number, and kernel partition number */ u_int (*allocate)(part_t *, partinfo_t *pnew); /* validate an alteration to a partition */ u_int (*validate_change)(part_t *, u_int, const partinfo_t *pold, const partinfo_t *pnew); /* validate creation of a partition */ u_int (*validate_creation)(part_t *, u_int, const partinfo_t *pold, const partinfo_t *pnew); /* validate deletion of a partition */ u_int (*validate_deletion)(part_t *, u_int, const partinfo_t *pold); /* validate a partition number */ u_int (*validate_partno)(part_t *, u_int); /* return next valid partition type */ ptyp_t (*nexttype)(part_t *, u_int, ptyp_t, int); } scheme_t; #endif acorn-fdisk-3.0.6.orig/lib/part/schemedata.h0100644000000000000000000000234606677130176017363 0ustar rootroot/* * lib/part/schemedata.h * * Copyright (C) 1997,1998 Russell King */ #ifndef PART_SCHEMEDATA_H #define PART_SCHEMEDATA_H #include "scheme/icside.h" #include "scheme/linux.h" #include "scheme/pcbios.h" #include "scheme/powertec.h" #include "scheme/riscix.h" #include "scheme/eesox.h" typedef union { #ifdef SCHEME_FILECORE_LINUX filecore_linux_part_t filecore_linux; #endif #ifdef SCHEME_FILECORE_RISCiX filecore_riscix_part_t filecore_riscix; #endif #ifdef SCHEME_ICSIDE icside_part_t icside; #endif #ifdef SCHEME_PCBIOS pcbios_part_t pcbios; #endif #ifdef SCHEME_POWERTEC powertec_part_t powertec; #endif #ifdef SCHEME_EESOX eesox_part_t eesox; #endif #ifdef SCHEME_FILECORE_RISCiX filecore_riscix_part_t riscix; #endif } scheme_part_t; typedef union { #ifdef SCHEME_FILECORE_LINUX filecore_linux_data_t filecore_linux; #endif #ifdef SCHEME_FILECORE_RISCiX filecore_riscix_data_t filecore_riscix; #endif #ifdef SCHEME_ICSIDE icside_data_t icside; #endif #ifdef SCHEME_PCBIOS pcbios_data_t pcbios; #endif #ifdef SCHEME_POWERTEC powertec_data_t powertec; #endif #ifdef SCHEME_EESOX eesox_data_t eesox; #endif #ifdef SCHEME_FILECORE_RISCiX filecore_riscix_data_t riscix; #endif } scheme_data_t; #endif acorn-fdisk-3.0.6.orig/lib/part/utils.h0100644000000000000000000000212306475631562016417 0ustar rootroot/* * lib/part/utils.h * * Copyright (C) 1997,1998 Russell King */ #ifndef PART_UTILS_H #define PART_UTILS_H #include "part/part.h" /* Function: u_int part_add (part_t *part, u_int parn, partinfo_t *pinfo) * Purpose : add a new partition (as read from disk) to the partition structures * Params : part - partitionable device * : parn - partition number * : pinfo - partition info * Returns : FALSE on error */ extern u_int part_add (part_t *part, u_int parn, partinfo_i_t *pinfo); /* Function: u_int check_overlap(part_t *part, u_int exclude_parn, partinfo_t *pinfo) * Purpose : check that the new partition information `pinfo' for `exclude_parn' entry * does not overlap physically on the disk with the existing partitions. * Params : part - partitionable device * : exclude_parn - partition entry to exclude from check * : pinfo - new partition information to check against * Returns : TRUE if new information overlaps existing */ extern u_int check_overlap(part_t *part, u_int exclude_parn, const partinfo_t *pinfo); #endif acorn-fdisk-3.0.6.orig/lib/part/Makefile0100644000000000000000000000061106722736175016547 0ustar rootrootAR = ar CC = cc ARFLAGS = rc CFLAGS = -DUNIX -O2 -Wall -I.. -g SQUEEZE = squeeze OBJS = allocate.o close.o create.o delete.o \ getgeo.o getpinfo.o getscheme.o open.o read.o \ setgeo.o setpinfo.o sync.o types.o write.o \ validops.o LIB = ../part.a all: $(LIB) clean:; $(RM) $(LIB) *.o $(LIB): $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) .c.o:; $(CC) $(CFLAGS) -o $@ -c $< acorn-fdisk-3.0.6.orig/lib/scheme/0042755000000000000000000000000007101375523015400 5ustar rootrootacorn-fdisk-3.0.6.orig/lib/scheme/add.c0100644000000000000000000000302706476230602016273 0ustar rootroot/* * lib/scheme/utils.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "part/utils.h" /* Function: u_int part_add (part_t *part, u_int parn, partinfo_i_t *pinfo) * Purpose : add a new partition (as read from disk) to the partition structures * Params : part - partitionable device * : parn - partition number * : pinfo - internal partition info * Returns : FALSE on error */ u_int part_add(part_t *part, u_int parn, partinfo_i_t *pinfo) { u_int ret = 1; assert (part != NULL); assert (pinfo != NULL); dbg_printf("part_add(parn=%d, pinfo=[bs=0x%X, be=0x%X, type=0x%X])", parn, pinfo->info.blk_start, pinfo->info.blk_end, pinfo->info.type); dbg_level_up(); part_updatechs(part, &pinfo->info); if (part->nr_partitions == 0 || parn >= part->nr_partitions) { partinfo_i_t **p; p = malloc((parn + 1) * sizeof (*p)); if (p) { memset(p, 0, (parn + 1) * sizeof (*p)); if (part->partinfo) { memcpy(p, part->partinfo, part->nr_partitions * sizeof (*p)); free(part->partinfo); } part->nr_partitions = parn + 1; part->partinfo = p; } else ret = 0; } if (!part->partinfo[parn]) part->partinfo[parn] = malloc(sizeof (partinfo_i_t)); if (part->partinfo[parn]) { *part->partinfo[parn] = *pinfo; part->partinfo[parn]->changed = 0; } else ret = 0; dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "failed"); return ret; } acorn-fdisk-3.0.6.orig/lib/scheme/chs.c0100644000000000000000000000302306504057627016322 0ustar rootroot/* * lib/part/chs.c * * Update CHS values when they're not valid */ #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" static void part_calcchs(chs_t *chs, geometry_t *geo, blk_t blk) { chs->sector = blk % geo->sectors; chs->head = (blk /= geo->sectors) % geo->heads; chs->cylinder = blk /= geo->heads; } /* Prototype: u_int part_updatechs(part_t *part, partinfo_t *pinfo) * Purpose : Update CHS values if they have become invalid * Params : part - partitionable device * : pinfo - partition to update * Returns : FALSE on error */ u_int part_updatechs(part_t *part, partinfo_t *pinfo) { geometry_t geo; u_int ret = 0; assert(part != NULL); assert(pinfo != NULL); dbg_printf("part_updatechs([bs=0x%X, be=0x%X, type=0x%X])", pinfo->blk_start, pinfo->blk_end, pinfo->type); dbg_level_up(); if (pinfo->chs_valid == 0) { if (!blkio_getgeometry(part->blkio, &geo)) set_error("unable to get geometry"); else { part_calcchs(&pinfo->chs_start, &geo, pinfo->blk_start); part_calcchs(&pinfo->chs_end, &geo, pinfo->blk_end); pinfo->chs_valid = 1; ret = 1; } } else ret = 1; dbg_printf("start=[C=%d,H=%d,S=%d] end=[C=%d,H=%d,S=%d]", pinfo->chs_start.cylinder, pinfo->chs_start.head, pinfo->chs_start.sector, pinfo->chs_end.cylinder, pinfo->chs_end.head, pinfo->chs_end.sector); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } acorn-fdisk-3.0.6.orig/lib/scheme/filecore.c0100644000000000000000000000052106476251536017340 0ustar rootroot/* * lib/scheme/filecore.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "scheme/filecore.h" u_int filecore_checksum(u8 *sector) { u_int sum = 0; int i; assert(sector != NULL); for (i = 510; i >= 0; i--) sum = (sum & 255) + sector[i] + (sum >> 8); return sum & 255; } acorn-fdisk-3.0.6.orig/lib/scheme/icside.c0100644000000000000000000003165306562264106017013 0ustar rootroot/* * lib/scheme/icside.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "util/types.h" #include "part/part.h" #include "part/utils.h" #define ICSIDE_SECTOR_SIZE 512 #define ICSIDE_PART_SECTOR 0 #define ICSIDE_NR_PARTITIONS 16 #undef ICSIDE_DUMP #define ICSIDE_SAVE #define NR(x) (sizeof(x) / sizeof(x[0])) typedef union { struct part { u32 start; s32 size; } p[ICSIDE_SECTOR_SIZE / sizeof(struct part)]; u8 sector[ICSIDE_SECTOR_SIZE]; } icside_pe_t; static u_int icside_checksum(u8 *sector) { u_int sum = 0x50617274; int i; for (i = 0; i < 508; i++) sum += sector[i]; return sum; } /* Prototype: u_int icside_detect(part_t *part) * Purpose : detect a drive partitioned with an ICS IDE table * Params : part - partitionable device * Returns : FALSE if not detected */ static u_int icside_detect(part_t *part) { u_int ret = 0; dbg_printf("icside_detect()"); dbg_level_up(); assert(part != NULL); do { icside_pe_t sector; u32 calc_checksum, disc_checksum; if (blkio_setblocksize(part->blkio, ICSIDE_SECTOR_SIZE) != ICSIDE_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector.sector, ICSIDE_PART_SECTOR, 1) != 1) break; calc_checksum = icside_checksum(sector.sector); disc_checksum = *(u32 *)§or.sector[508]; dbg_printf("-icside disc checksum: %08X", disc_checksum); dbg_printf("-icside calc checksum: %08X", calc_checksum); if (calc_checksum != disc_checksum) { dbg_memdump(sector.sector, ICSIDE_SECTOR_SIZE); break; } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } /* Prototype: u_int icside_readinfo(part_t *part) * Purpose : read all partition information from the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int icside_readinfo(part_t *part) { u_int ret = 0; dbg_printf("icside_readinfo()"); dbg_level_up(); assert(part != NULL); do { icside_pe_t sector; partinfo_i_t pinfo; char temp_sector[512]; u_int idx, part_no; if (blkio_read(part->blkio, sector.sector, ICSIDE_PART_SECTOR, 1) != 1) break; ret = 1; pinfo.info.chs_valid = 0; /* Scan through all available partitions, detecting filecore, * Linux and non-Linux partitions */ for (idx = 0, part_no = 1; idx < ICSIDE_NR_PARTITIONS; idx ++, part_no ++) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.p[idx].start; pinfo.data.icside.idx = idx; if (sector.p[idx].size > 0) { /* If size > 0, then we have a filecore partition */ pinfo.info.blk_start = sector.p[idx].start; pinfo.info.blk_end = sector.p[idx].start + sector.p[idx].size - 1; pinfo.info.type = ptyp_filecore; pinfo.info.kern_part_no = part_no; pinfo.data.icside.idx = idx; if (!part_add(part, part_no, &pinfo)) { ret = 0; break; } /* should we check the filecore boot sector? */ } else if (sector.p[idx].size < 0) { /* Otherwise if size < 0, we have some other partition */ if (blkio_read(part->blkio, temp_sector, pinfo.info.blk_start, 1) == 1 && memcmp(temp_sector, "LinuxPart", 9) == 0) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.p[idx].start; pinfo.info.blk_end = sector.p[idx].start - sector.p[idx].size - 1; pinfo.info.kern_part_no = part_no; pinfo.data.icside.idx = idx; switch (temp_sector[9]) { case 'N': pinfo.info.type = ptyp_linux_native; break; case 'S': pinfo.info.type = ptyp_linux_swap; break; default: break; } if (!part_add(part, part_no, &pinfo)) { ret = 0; break; } } else { /* Mark other partitions as unknown */ pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.p[idx].start; pinfo.info.blk_end = (sector.p[idx].start - sector.p[idx].size) - 1; pinfo.info.type = ptyp_unknown; pinfo.info.kern_part_no = part_no; pinfo.data.icside.idx = idx; if (!part_add(part, part_no, &pinfo)) { ret = 0; break; } } } } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int icside_writeinfo(part_t *part) * Purpose : write all partition information back to the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int icside_writeinfo(part_t *part) { icside_pe_t sector; u_int part_no, ret = 0; dbg_printf("icside_writeinfo()"); dbg_level_up(); assert(part != NULL); assert(part->nr_partitions <= ICSIDE_NR_PARTITIONS); memset(sector.sector, 0, sizeof(sector)); for (part_no = 1; part_no < part->nr_partitions; part_no++) if (part->partinfo[part_no]) { partinfo_i_t *info = part->partinfo[part_no]; u_int idx = part_no - 1; /* * Linux table partitions are just placeholders - ignore them */ switch (info->info.type) { case ptyp_none: break; case ptyp_unknown: sector.p[idx].start = info->info.blk_start; sector.p[idx].size = -((info->info.blk_end - info->info.blk_start) + 1); break; case ptyp_linux_native: case ptyp_linux_swap: sector.p[idx].start = info->info.blk_start; sector.p[idx].size = -((info->info.blk_end - info->info.blk_start) + 1); break; case ptyp_filecore: sector.p[idx].start = info->info.blk_start; sector.p[idx].size = (info->info.blk_end - info->info.blk_start) + 1; break; default: assert(0); } } *(unsigned long *)§or.sector[508] = icside_checksum(sector.sector); #ifdef ICSIDE_DUMP dbg_memdump(sector.sector, ICSIDE_SECTOR_SIZE); #endif #ifdef ICSIDE_SAVE ret = 1; if (blkio_write(part->blkio, sector.sector, ICSIDE_PART_SECTOR, 1) != 1) ret = 0; #endif for (part_no = 1; part_no < part->nr_partitions; part_no++) if (part->partinfo[part_no]) { partinfo_i_t *info = part->partinfo[part_no]; char *id = NULL; switch (info->info.type) { case ptyp_linux_native: id = "LinuxPartN"; break; case ptyp_linux_swap: id = "LinuxPartS"; break; default: break; } if (id) { memset(sector.sector, 0, ICSIDE_SECTOR_SIZE); memcpy(sector.sector, id, strlen(id)); dbg_printf("write to 0x%lX", info->info.blk_start); #ifdef ICSIDE_DUMP dbg_memdump(sector.sector, ICSIDE_SECTOR_SIZE); #endif #ifdef ICSIDE_SAVE if (blkio_write(part->blkio, sector.sector, info->info.blk_start, 1) != 1) ret = 0; #endif } } #ifndef ICSIDE_SAVE set_error("ICS-style partition information cannot be saved with this build"); #endif dbg_level_down(); dbg_printf("ret=%d", ret); return ret; } /* Prototype: u_int icside_allocate(part_t *part, partinfo_t *pnew) * Purpose : allocate a partition entry number and a kernel partition * number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int icside_allocate(part_t *part, partinfo_t *pnew) { u_int parn; dbg_printf("icside_allcate()"); assert(part != NULL); assert(pnew != NULL); for (parn = 1; parn < part->nr_partitions; parn++) if (!part->partinfo[parn]) break; if (parn >= ICSIDE_NR_PARTITIONS) { set_error("too many partitions already created"); parn = PARN_ERROR; } else { pnew->kern_part_no = parn; pnew->type = ptyp_linux_native; } dbg_printf("ret %d", parn); return parn; } /* Prototype: u_int icside_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Purpose : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int icside_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("icside_validate_change(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(pold != NULL); assert(parn < part->nr_partitions); do { if (pold->type == ptyp_filecore) { set_error("you cannot edit a filecore partition"); break; } if (pnew) { if (pnew->type == ptyp_filecore) { set_error("you cannot create a filecore partition"); break; } if (check_overlap(part, parn, pnew)) { set_error("the modified partition overlaps an existing partition"); break; } } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int icside_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Purpose : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int icside_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("icside_validate_creation(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); do { if (pold != NULL) { set_error("unable to create partition in this slot"); break; } if (pnew) { if (pnew->type == ptyp_filecore) { set_error("you cannot create a filecore partition"); break; } if (check_overlap(part, parn, pnew)) { set_error("the new partition overlaps an existing partition"); break; } } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int icside_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Purpose : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int icside_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("icside_validate_deletion(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); ret = 1; dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int icside_validate_partno(part_t *part, u_int parn) * Purpose : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int icside_validate_partno(part_t *part, u_int parn) { u_int ret = 0; dbg_printf("icside_validate_partno(parn=%d)", parn); dbg_level_up(); assert(part != NULL); if (parn > 0 && parn < 1 + ICSIDE_NR_PARTITIONS) ret = 1; else set_error("the requested partition is invalid"); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: ptyp_t icside_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : return next valid partition type for an entry * Params : part - partitionable device * : parn - partition number * : current - currently selected partition type * : dir - next/previous flag * Returns : next valid partition type */ static ptyp_t icside_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { ptyp_t types[] = { ptyp_filecore, ptyp_linux_native, ptyp_linux_swap, ptyp_unknown }; ptyp_t ptype; dbg_printf("icside_nexttype(parn=%d, current=0x%X, %s)", parn, current, dir > 0 ? "next" : "previous"); dbg_level_up(); assert(parn < part->nr_partitions); if (parn == 1) ptype = ptyp_filecore; else { int i; for (i = 0; i < NR(types); i++) if (types[i] == current) break; i += dir; if (i < 0) i = 0; else if (i >= NR(types)) i = NR(types) - 1; ptype = types[i]; } dbg_level_down(); dbg_printf("ret 0x%X", ptype); return ptype; } scheme_t icside_scheme = { "ICSIDEFS", icside_detect, icside_readinfo, icside_writeinfo, icside_allocate, icside_validate_change, icside_validate_creation, icside_validate_deletion, icside_validate_partno, icside_nexttype }; acorn-fdisk-3.0.6.orig/lib/scheme/linux.c0100644000000000000000000004036606766721572016726 0ustar rootroot/* * lib/scheme/linux.c * * Partition backend for Linux on Filecore partitioning scheme. This * uses the non-ADFS descriptor to point to the start of the disc to * be partitioned. The first two sectors contain a partition table to * identify the Linux partitions contained within. * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" #include "part/utils.h" #include "blkio/filecore.h" #include "scheme/filecore.h" #define LINUX_SAVE #define LINUX_DEBUG #define FILECORE_MAX_PARTITIONS 16 #define FILECORE_LINUX_NATIVE 0xdeafa1de #define FILECORE_LINUX_SWAP 0xdeafab1e #define FILECORE_DOSDISC 0x0d05d15c #define FILECORE_FILECORE 0xf11ec05e union partition_sector_u { struct { u32 magic; u32 offset_start; u32 size; } p[FILECORE_MAX_PARTITIONS]; u8 sector[FILECORE_SECTOR_SIZE]; }; static void fcl_internalcheck(part_t *part) { u_int i; assert(part != NULL); assert(part->nr_partitions <= FILECORE_MAX_PARTITIONS + 3); for (i = 0; i < part->nr_partitions; i++) if (part->partinfo[i]) assert(part->partinfo[i]->info.kern_part_no == i); } /* Prototype: u_int fcl_detect(part_t *part) * Function : detect a drive partitioned with a filecore-linux partition table * Params : part - partitionable device * Returns : FALSE if not detected */ static u_int fcl_detect(part_t *part) { u_char sector[FILECORE_SECTOR_SIZE]; disc_record_t *disc_record; u_int ret = 0; dbg_printf("fcl_detect()"); dbg_level_up(); assert(part != NULL); do { u_int disc_csum, calc_csum; if (blkio_setblocksize(part->blkio, FILECORE_SECTOR_SIZE) != FILECORE_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector, FILECORE_BOOT_SECTOR, 1) != 1) break; disc_csum = sector[511]; calc_csum = filecore_checksum(sector); dbg_printf("-fcl disc checksum: %02X", disc_csum); dbg_printf("-fcl calc checksum: %02X", calc_csum); if (calc_csum != disc_csum) break; /* * Check that we do not have a sector filled with zero */ disc_record = (disc_record_t *)(sector + 0x1c0); if (disc_record->d.disc_size == 0 && disc_record->d.disc_size_high == 0) break; part->data.filecore_linux.disc_record = *disc_record; part->data.filecore_linux.boot_checksum = sector[511]; /* * Check that a Linux partition table exists, or no non-ADFS partition */ if ((sector[508] & 15) != 9 && sector[508] != 0) break; ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } /* Prototype: u_int fcl_readinfo(part_t *part) * Function : read all partition information from the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int fcl_readinfo(part_t *part) { u_int ret = 0; dbg_printf("fcl_readinfo()"); dbg_level_up(); assert(part != NULL); do { disc_record_t *disc_record = &part->data.filecore_linux.disc_record; union partition_sector_u sector; partinfo_i_t pinfo; blk_t parttable_start; u_int i; /* * First partition is the filecore image */ pinfo.info.chs_valid = 0; pinfo.info.blk_start = 0; pinfo.info.blk_end = (disc_record->d.disc_size_high << (32 - 9) | disc_record->d.disc_size >> 9) - 1; pinfo.info.type = ptyp_filecore; pinfo.info.kern_part_no = 1; if (!part_add(part, 1, &pinfo)) break; /* * If we don't have a non-filecore image, then we don't have a Linux * partition table, and therefore no Linux partitions. */ if (disc_record->packing[508 - 0x1c0] == 0) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = pinfo.info.blk_end + 1; pinfo.info.blk_end = pinfo.info.blk_start + 1; pinfo.info.type = ptyp_reserved; pinfo.info.kern_part_no = 2; if (!part_add(part, 2, &pinfo)) break; ret = 1; } else { /* * Locate the start of the non-filecore image, and add that as * partition 2. (It is always partition 2). */ parttable_start = (disc_record->packing[509 - 0x1c0] | disc_record->packing[510 - 0x1c0] << 8) * disc_record->d.heads * disc_record->d.secspertrack; pinfo.info.chs_valid = 0; pinfo.info.blk_start = parttable_start; pinfo.info.blk_end = pinfo.info.blk_start + 1; pinfo.info.type = ptyp_linux_table; pinfo.info.kern_part_no = 2; if (!part_add(part, 2, &pinfo)) break; /* * Now read the Linux partition table - one sector, but in fact * two sectors are set aside for it. */ if (blkio_read(part->blkio, §or, pinfo.info.blk_start, 1) != 1) break; ret = 1; /* * And add the partitions found within... We only recognise * two different magic numbers representing Linux native and * Linux swap partition types. */ for (i = 0; i < FILECORE_MAX_PARTITIONS; i++) { if (sector.p[i].magic == FILECORE_LINUX_NATIVE || sector.p[i].magic == FILECORE_LINUX_SWAP) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = parttable_start + sector.p[i].offset_start; pinfo.info.blk_end = parttable_start + sector.p[i].offset_start + sector.p[i].size - 1; pinfo.info.type = sector.p[i].magic == FILECORE_LINUX_NATIVE ? ptyp_linux_native : ptyp_linux_swap; pinfo.info.kern_part_no = 3 + i; if (!part_add(part, 3 + i, &pinfo)) { ret = 0; break; } } } } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int fcl_writeinfo(part_t *part) * Function : write all partition information back to the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int fcl_writeinfo(part_t *part) { u_int ret = 0; dbg_printf("fcl_writeinfo()"); dbg_level_up(); fcl_internalcheck(part); do { disc_record_t *disc_record = &part->data.filecore_linux.disc_record; union partition_sector_u sector; if (blkio_read(part->blkio, sector.sector, FILECORE_BOOT_SECTOR, 1) != 1) break; /* * Ensure that the information we read was a valid boot sector. * Ok, I'm being paranoid... but then partitioning is dangerous. */ if (filecore_checksum(sector.sector) != sector.sector[511]) { set_error("filecore boot sector is corrupt"); break; } /* * We check to make sure that the checksum we have here is * identical to that when we read the sector in fcl_readinfo. * If it's different, we're in trouble! */ if (sector.sector[511] != part->data.filecore_linux.boot_checksum) { set_error("filecore boot sector has been changed by another program"); break; } /* * If we have partitions > 2, then we have a non-ADFS descriptor. * Otherwise, we remove the non-ADFS descriptor (If it wasn't a * Linux descriptor, we shouldn't be here). */ if (part->nr_partitions > 2 && part->partinfo[2]) { u_int start_cyl; start_cyl = part->partinfo[2]->info.blk_start / (disc_record->d.heads * disc_record->d.secspertrack); /* * This should always be true. If it's incorrect, then you've * been playing, and I'm confused. */ assert(start_cyl == part->partinfo[2]->info.chs_start.cylinder); sector.sector[508] = 9; sector.sector[509] = start_cyl & 255; sector.sector[510] = start_cyl >> 8; } else { sector.sector[508] = 0; sector.sector[509] = 0; sector.sector[510] = 0; } /* * We have made our changes to the boot sector. Recalculate * the checksum, and don't forget to update our own copy. */ sector.sector[511] = filecore_checksum(sector.sector); part->data.filecore_linux.boot_checksum = sector.sector[511]; #ifdef LINUX_DEBUG dbg_printf("Filecore boot sector (0xc00):"); dbg_memdump(sector.sector, FILECORE_SECTOR_SIZE); #endif #ifdef LINUX_SAVE if (blkio_write(part->blkio, sector.sector, FILECORE_BOOT_SECTOR, 1) != 1) { set_error("unable to write filecore boot sector"); break; } #endif if (part->nr_partitions > 2 && part->partinfo[2]) { blk_t parttable_start = part->partinfo[2]->info.blk_start; u_int i; /* * Now, write the partition information to the Linux * partition sectors. */ memset(sector.sector, 0, sizeof(sector.sector)); for (i = 0; i < part->nr_partitions - 3; i++) { partinfo_i_t *info = part->partinfo[i + 3]; if (info && info->info.type != ptyp_none) { sector.p[i].offset_start = info->info.blk_start - parttable_start; sector.p[i].size = info->info.blk_end - info->info.blk_start + 1; switch(info->info.type) { case ptyp_linux_native: sector.p[i].magic = FILECORE_LINUX_NATIVE; break; case ptyp_linux_swap: sector.p[i].magic = FILECORE_LINUX_SWAP; break; default: assert(0); } } } #ifdef LINUX_DEBUG dbg_printf("Linux partition sector (0x%X):", parttable_start); dbg_memdump(sector.sector, FILECORE_SECTOR_SIZE); #endif #ifdef LINUX_SAVE if (blkio_write(part->blkio, sector.sector, parttable_start, 1) != 1) { set_error("unable to write linux partition sector"); break; } ret = 1; #endif } } while (0); #ifndef LINUX_SAVE set_error("filecore-linux partition information cannot be saved with this build"); #endif dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int fcl_allocate(part_t *part, partinfo_t *pnew) * Function : allocate a partition entry number and a kernel * partition number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int fcl_allocate(part_t *part, partinfo_t *pnew) { u_int parn; dbg_printf("fcl_allocate()"); dbg_level_up(); fcl_internalcheck(part); assert(pnew != NULL); if (part->nr_partitions < 2) { set_error("partition table missing"); parn = PARN_ERROR; } else { for (parn = 3; parn < part->nr_partitions; parn++) if (part->partinfo[parn] == NULL) break; if (parn >= FILECORE_MAX_PARTITIONS) { set_error("partition table is full"); parn = PARN_ERROR; } else { pnew->kern_part_no = parn; pnew->type = ptyp_linux_native; } } dbg_level_down(); dbg_printf("ret %d", parn); return parn; } /* Prototype: u_int fcl_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int fcl_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("fcl_validate_change(parn=%d)", parn); dbg_level_up(); fcl_internalcheck(part); assert(parn < part->nr_partitions); do { if (pnew) { if (pnew->type != ptyp_linux_native && pnew->type != ptyp_linux_swap) { set_error("invalid partition type"); break; } if (check_overlap(part, parn, pnew)) { set_error("the modified partition overlaps an existing partition"); break; } } if (parn >= 3 && parn < part->nr_partitions) ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int fcl_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int fcl_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("fcl_validate_creation(parn=%d)", parn); dbg_level_up(); fcl_internalcheck(part); assert(parn < part->nr_partitions); do { if (pold != NULL) { set_error("unable to create partition in this slot"); break; } if (pnew) { if (pnew->type != ptyp_linux_native && pnew->type != ptyp_linux_swap) { set_error("invalid partition type"); break; } if (check_overlap(part, parn, pnew)) { set_error("the new partition overlaps an existing partition"); break; } } if (part->partinfo[2] && part->partinfo[2]->info.type == ptyp_reserved) part->partinfo[2]->info.type = ptyp_linux_table; ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int fcl_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Function : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int fcl_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("fcl_validate_deletion(parn=%d)", parn); dbg_level_up(); fcl_internalcheck(part); assert(pold != NULL); assert(parn < part->nr_partitions); switch (pold->kern_part_no) { case 0: case 1: /* filecore partition */ set_error("unable to delete filecore partition"); break; case 2: /* Linux table partition */ { int i; for (i = 3; i < part->nr_partitions; i++) if (part->partinfo[i]) break; if (i >= part->nr_partitions) ret = 1; else set_error("delete all partitions contained within first"); } break; default: ret = 1; break; } dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int fcl_validate_partno(part_t *part, u_int parn) * Function : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int fcl_validate_partno(part_t *part, u_int parn) { u_int ret = 0; dbg_printf("fcl_validate_partno(parn=%d)", parn); dbg_level_up(); fcl_internalcheck(part); if (parn < FILECORE_MAX_PARTITIONS) ret = 1; else set_error("the requested partition is invalid"); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: ptyp_t fcl_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : return next valid partition type for an entry * Params : part - partitionable device * : parn - partition number * : current - currently selected partition type * : dir - next/previous flag * Returns : next valid partition type */ static ptyp_t fcl_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { ptyp_t ptype = current; dbg_printf("fcl_nexttype(parn=%d, current=0x%X, %s)", parn, current, dir > 0 ? "next" : "previous"); dbg_level_up(); fcl_internalcheck(part); assert(parn < part->nr_partitions); switch(parn) { case 0: case 1: ptype = ptyp_filecore; break; case 2: ptype = ptyp_linux_table; break; default: switch(current) { case ptyp_linux_native: if (dir > 0) ptype = ptyp_linux_swap; break; case ptyp_linux_swap: if (dir < 0) ptype = ptyp_linux_native; break; default: ptype = ptyp_linux_native; break; } } dbg_level_down(); dbg_printf("ret 0x%X", ptype); return ptype; } scheme_t filecore_linux_scheme = { "Filecore/Linux", fcl_detect, fcl_readinfo, fcl_writeinfo, fcl_allocate, fcl_validate_change, fcl_validate_creation, fcl_validate_deletion, fcl_validate_partno, fcl_nexttype }; acorn-fdisk-3.0.6.orig/lib/scheme/overlap.c0100644000000000000000000000233706476055052017222 0ustar rootroot/* * lib/scheme/overlap.c * * Copyright (C) 1998 Russell King */ #include #include #include "util/debug.h" #include "part/utils.h" static u_int test_overlap(const partinfo_t *p1, const partinfo_t *p2) { dbg_printf("checking [0x%X-0x%X] with [0x%X-0x%X]", p2->blk_start, p2->blk_end, p1->blk_start, p1->blk_end); return !(p2->blk_end < p1->blk_start || p2->blk_start > p1->blk_end); } /* Function: u_int check_overlap(part_t *part, u_int exclude_parn, partinfo_t *pinfo) * Purpose : check that the new partition information `pinfo' for `exclude_parn' entry * does not overlap physically on the disk with the existing partitions. * Params : part - partitionable device * : exclude_parn - partition entry to exclude from check * : pinfo - new partition information to check against * Returns : TRUE if new information overlaps existing */ u_int check_overlap(part_t *part, u_int exclude_parn, const partinfo_t *pinfo) { u_int i, ret = 0; for (i = 1; i < part->nr_partitions; i++) if (i != exclude_parn && part->partinfo[i] && test_overlap(&part->partinfo[i]->info, pinfo)) { ret = 1; break; } return ret; } acorn-fdisk-3.0.6.orig/lib/scheme/pcbios.c0100644000000000000000000003757406722736613017047 0ustar rootroot/* * lib/scheme/pcbios.c * * Partition backend for PC/BIOS partitioning scheme. This consists * of a partition table in the first sector of the disk which contains * both CHS and LBA values for the partitions. There can be up to four * entries in the primary partition table. One of these can be an * extended partition containing up to four extra partitions. * * NOTE: We do not support extended partitions yet. * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "util/warning.h" #include "part/part.h" #include "part/utils.h" #include "scheme/pcbios.h" #define PCBIOS_SAVE #define PCBIOS_DEBUG #define PCBIOS_SECTOR_SIZE 512 #define PCBIOS_BOOT_SECTOR 0 #define PCBIOS_NR_PRIMARY 4 #define is_extended(x) ((x) == ptyp_dos_extended) /* Prototype: void pcbios_copychsin(chs_t *chs, u8 *p) * Purpose : Copy a CHS value from a PC partition table to a chs_t structure * Params : chs - destination for CHS values * : p - pointer to start of packed CHS values */ static void pcbios_copychsin(chs_t *chs, u8 *p) { chs->head = p[0]; chs->sector = (p[1] & 63) - 1; chs->cylinder = p[2] | (p[1] & 0xc0) << 2; } /* Prototype: void pcbios_copychsout(u8 *p, chs_t *chs) * Purpose : Copy a CHS value to a PC partition table from a chs_t structure * Params : p - pointer to start of packed CHS values * : chs - values to pack for CHS values */ static void pcbios_copychsout(u8 *p, chs_t *chs) { p[0] = chs->head; p[1] = ((chs->sector + 1) & 63) | ((chs->cylinder >> 2) & 0xc0); p[2] = chs->cylinder & 0xff; } /* Prototype: u32 pcbios_copylogin(u8 *p) * Purpose : Copy a logical start/end 32-bit value from a PC partition table * Params : p - pointer to start of 32-bit value * Returns : 32-bit unsigned integer */ static u32 pcbios_copylogin(u8 *p) { return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; } /* Prototype: u_int pcbios_copylogout(u8 *p, u32 l) * Purpose : Copy a logical start/end 32-bit value to a PC partition table * Params : p - pointer to start of 32-bit value * : l - value to place */ static void pcbios_copylogout(u8 *p, u32 l) { p[0] = l & 255; p[1] = (l >> 8) & 255; p[2] = (l >> 16) & 255; p[3] = (l >> 24) & 255; } /* Prototype: u_int pcbios_detect(part_t *part) * Purpose : detect a drive partitioned with a PC/BIOS partition table * Params : part - partitionable device * Returns : FALSE if not detected */ static u_int pcbios_detect(part_t *part) { u_char sector[PCBIOS_SECTOR_SIZE]; u_int ret = 0; dbg_printf("pcbios_detect()"); dbg_level_up(); assert(part != NULL); do { if (blkio_setblocksize(part->blkio, PCBIOS_SECTOR_SIZE) != PCBIOS_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector, PCBIOS_BOOT_SECTOR, 1) != 1) break; if (sector[510] != 0x55 || sector[511] != 0xaa) break; ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } static u_int pcbios_readextended(part_t *part, blk_t blkstart, u_int size) { static u_char sector[PCBIOS_SECTOR_SIZE]; u_int ret = 0; u_int extended_nr = 5; dbg_printf("pcbios_readextended(%d, %d)", blkstart, size); dbg_level_up(); assert(part != NULL); do { u_char *p = sector + 0x1be; partinfo_i_t pinfo; u_int parn; if (blkio_read(part->blkio, sector, blkstart, 1) != 1) break; if (sector[510] != 0x55 || sector[511] != 0xaa) { issue_warning("The extended partition table does not contain a valid signature." " This will be corrected when writing partition information " "to disk."); sector[510] = 0x55; sector[511] = 0xaa; } part->data.pcbios.extended_sector = sector; ret = 1; for (parn = 0; parn < PCBIOS_NR_PRIMARY; parn++, p += 16) if (p[4] && !is_extended(p[4])) { blk_t start; u32 size; pinfo.info.chs_valid = 1; pinfo.info.kern_part_no = extended_nr; pcbios_copychsin(&pinfo.info.chs_start, p + 1); pcbios_copychsin(&pinfo.info.chs_end, p + 5); pinfo.info.type = p[4]; start = pcbios_copylogin(p + 8) + blkstart; size = pcbios_copylogin(p + 12); pinfo.info.blk_start = start; pinfo.info.blk_end = start + size - 1; if (!part_add (part, extended_nr, &pinfo)) { ret = 0; break; } extended_nr += 1; } p = sector + 0x1be; for (parn = 0; parn < PCBIOS_NR_PRIMARY; parn++, p += 16) if (is_extended(p[4])) { blkstart += pcbios_copylogin(p + 8); size = pcbios_copylogin(p + 12); } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int pcbios_readinfo(part_t *part) * Purpose : read all partition information from the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int pcbios_readinfo(part_t *part) { static u_char sector[PCBIOS_SECTOR_SIZE]; u_int ret = 0; dbg_printf("pcbios_readinfo()"); dbg_level_up(); assert(part != NULL); do { partinfo_i_t pinfo; chs_t chs; blk_t start; u_int parn, valid; u_char *p; part->data.pcbios.pcboot_sector = sector; if (blkio_read(part->blkio, sector, PCBIOS_BOOT_SECTOR, 1) != 1) break; valid = sector[510] == 0x55 && sector[511] == 0xaa; if (!valid) { issue_warning("The master boot sector does not contain a valid signature." " This will be corrected when writing partition information " " to disk."); sector[510] = 0x55; sector[511] = 0xaa; } p = part->data.pcbios.pcboot_sector + 0x1be; if (valid && chs.cylinder == 0) { /* * Attempt to calculate the size of one track * track_size = (start_log / (cyl * head) - sector */ start = pcbios_copylogin(p + 8); pcbios_copychsin(&chs, p + 1); start /= chs.head ? chs.head : 1; start -= chs.sector; } else { geometry_t geo; blkio_getgeometry(part->blkio, &geo); start = geo.sectors * geo.heads; } memset (&pinfo, 0, sizeof(pinfo)); pinfo.info.chs_valid = 1; pinfo.info.chs_start.sector = 0; pinfo.info.chs_end.sector = start - 1; pinfo.info.blk_end = start - 1; pinfo.info.type = ptyp_pc_table; if (!part_add(part, 0, &pinfo)) break; /* * Look for all possible primary partitions * - feature - if the drive is already partitioned, * with non-Linux partitions, we will assert! */ ret = 1; for (parn = 0; parn < PCBIOS_NR_PRIMARY; parn++, p += 16) if (p[4]) { blk_t start; u32 size; pinfo.info.chs_valid = 1; pinfo.info.kern_part_no = parn + 1; pcbios_copychsin(&pinfo.info.chs_start, p + 1); pcbios_copychsin(&pinfo.info.chs_end, p + 5); pinfo.info.type = p[4]; start = pcbios_copylogin(p + 8); size = pcbios_copylogin(p + 12); pinfo.info.blk_start = start; pinfo.info.blk_end = start + size - 1; if (!part_add (part, parn + 1, &pinfo)) { ret = 0; break; } if (is_extended(p[4]) && !pcbios_readextended(part, start, size)) { ret = 0; break; } } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int pcbios_writeinfo(part_t *part) * Purpose : write all partition information back to the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int pcbios_writeinfo(part_t *part) { u_int parn; u_int ret = 0; u_char *p; dbg_printf("pcbios_writeinfo()"); dbg_level_up(); assert(part != NULL); assert(part->nr_partitions <= PCBIOS_NR_PRIMARY + 1); assert(part->data.pcbios.pcboot_sector != NULL); /* * We use the mbr sector that we loaded when we started * the partition process, so keeping any PC code */ p = part->data.pcbios.pcboot_sector + 0x1be; /* * Write the magic number */ part->data.pcbios.pcboot_sector[510] = 0x55; part->data.pcbios.pcboot_sector[511] = 0xaa; /* * Loop through *all* possible partitions - we zero the * undefined partition entries. */ for (parn = 1; parn < PCBIOS_NR_PRIMARY + 1; parn++, p += 16) { partinfo_i_t *info; memset(p, 0, 16); if (parn < part->nr_partitions) { info = part->partinfo[parn]; if (info && info->info.type != ptyp_none) { /* * We should always have 'type' as an 8-bit value */ assert(info->info.type <= 0xff); /* * p[0] = boot flag... (we don't set yet) */ p[4] = info->info.type; pcbios_copychsout(p + 1, &info->info.chs_start); pcbios_copychsout(p + 5, &info->info.chs_end); pcbios_copylogout(p + 8, info->info.blk_start); pcbios_copylogout(p + 12, info->info.blk_end - info->info.blk_start + 1); } } } #ifdef PCBIOS_DEBUG dbg_printf("Boot sector:"); dbg_memdump(part->data.pcbios.pcboot_sector, 512); #endif #ifdef PCBIOS_SAVE if (blkio_write(part->blkio, part->data.pcbios.pcboot_sector, PCBIOS_BOOT_SECTOR, 1) != 1) set_error("unable to save partition information"); else ret = 1; #else set_error("PC/BIOS partition information cannot be saved with this build"); #endif dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int pcbios_allocate(part_t *part, partinfo_t *pnew) * Purpose : allocate a partition entry number and a kernel partition * number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int pcbios_allocate(part_t *part, partinfo_t *pnew) { u_int parn; dbg_printf("pcbios_allocate()"); assert(part != NULL); assert(pnew != NULL); /* * Look for a free primary partition */ for (parn = 1; parn < 1 + PCBIOS_NR_PRIMARY && parn < part->nr_partitions; parn++) if (!part->partinfo[parn] || part->partinfo[parn]->info.type == ptyp_none) break; if (parn >= 1 + PCBIOS_NR_PRIMARY) { set_error("primary bios partition table is full"); parn = PARN_ERROR; } else { pnew->kern_part_no = parn; pnew->type = ptyp_linux_native; } dbg_printf("ret %d", parn); assert(parn < 1 + PCBIOS_NR_PRIMARY || parn == PARN_ERROR); return parn; } /* Prototype: u_int pcbios_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Purpose : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int pcbios_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("pcbios_validate_change(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(pold != NULL); assert(parn < part->nr_partitions); do { if (parn == 0) { set_error("unable to modify the BIOS partition table partition"); break; } if (pnew && check_overlap(part, parn, pnew)) { set_error("the modified partition overlaps an existing partition"); break; } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int pcbios_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Purpose : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int pcbios_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("pcbios_validate_creation(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); do { if (pold != NULL) { set_error("unable to create partition in this slot"); break; } if (pnew && check_overlap(part, parn, pnew)) { set_error("the new partition overlaps an existing partition"); break; } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int pcbios_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Purpose : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int pcbios_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("pcbios_validate_deletion(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(pold != NULL); assert(parn < part->nr_partitions); if (parn > 0) ret = 1; else set_error("unable to delete partition"); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int icside_validate_partno(part_t *part, u_int parn) * Purpose : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int pcbios_validate_partno(part_t *part, u_int parn) { u_int ret = 0; dbg_printf("pcbios_validate_partno(parn=%d)", parn); dbg_level_up(); assert(part != NULL); if (parn > 0 && parn < 1 + PCBIOS_NR_PRIMARY) ret = 1; else set_error("the requested partition is invalid"); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: ptyp_t pcbios_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : return next valid partition type for an entry * Params : part - partitionable device * : parn - partition number * : current - currently selected partition type * : dir - next/previous flag * Returns : next valid partition type */ static ptyp_t pcbios_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { static ptyp_t types[] = { ptyp_dos12, ptyp_xenixroot, ptyp_xenixusr, ptyp_dos16l32, ptyp_dos_extended, ptyp_dos16g32, ptyp_hpfs, ptyp_aix, ptyp_aixboot, ptyp_os2, ptyp_win98_extended, ptyp_venix, ptyp_novell, ptyp_microport, ptyp_dm6_aux3, ptyp_dm6, ptyp_ezdrive, ptyp_gnuhurd, ptyp_novelnet286, ptyp_novelnet386, ptyp_pcix, ptyp_old_minix, ptyp_minix, ptyp_linux_swap, ptyp_linux_native, ptyp_linux_extended, ptyp_amoeba, ptyp_amoebabbt, ptyp_bsd386, ptyp_bsdifs, ptyp_bsdiswap, ptyp_syrinx, ptyp_cpm, ptyp_dosaccess, ptyp_dosro, ptyp_dosscc, ptyp_bbt }; #define NR_TYPES (sizeof(types) / sizeof(ptyp_t)) ptyp_t ptype = current; dbg_printf("pcbios_nexttype(parn=%d, current=0x%X, %s)", parn, current, dir > 0 ? "next" : "previous"); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); if (parn == 0) ptype = ptyp_pc_table; else { s_int i; for (i = 0; i < NR_TYPES; i++) if (types[i] == current) break; if (types[i] == current) { i += dir; if (i < 0) i = 0; if (i >= NR_TYPES) i = NR_TYPES - 1; ptype = types[i]; } else ptype = ptyp_linux_native; } dbg_level_down(); dbg_printf("ret 0x%X", ptype); return ptype; } scheme_t pcbios_scheme = { "PC/BIOS", pcbios_detect, pcbios_readinfo, pcbios_writeinfo, pcbios_allocate, pcbios_validate_change, pcbios_validate_creation, pcbios_validate_deletion, pcbios_validate_partno, pcbios_nexttype }; acorn-fdisk-3.0.6.orig/lib/scheme/powertec.c0100644000000000000000000003444506562264652017413 0ustar rootroot/* * lib/scheme/powertec.c * * Partition backend for PowerTec SCSI partitioning scheme on the * Acorn machines. * * Copyright (C) 1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "util/types.h" #include "part/part.h" #include "part/utils.h" #define POWERTEC_SECTOR_SIZE 512 #define POWERTEC_PART_SECTOR 0 #define POWERTEC_NR_PARTITIONS 16 #undef POWERTEC_DUMP #define POWERTEC_SAVE /* 24 -> 6 words * - start- - size - ----- name ------ * 00000000 00000000 00000000 00080000 00000000 63736952 003a734f * 00000000 00000000 00080070 00000000 00000000 63736952 003a734f * 00000000 00000000 00080070 00000000 00000000 63736952 003a734f * ... etc ... * 00000000 00000000 00000000 00053000 00000000 63736952 003a734f * 00000000 00000000 00053020 0002cfe0 00000000 63736952 003a734f * 00000000 00000000 00080070 00000000 00000000 63736952 003a734f * ... etc ... */ typedef struct { u32 unused1; u32 unused2; u32 start; u32 size; u32 unused5; char type[8]; } pe_t; typedef union { pe_t pe[POWERTEC_SECTOR_SIZE / sizeof(pe_t)]; u8 sector[POWERTEC_SECTOR_SIZE]; } powertec_psect_t; typedef struct { const ptyp_t type; const u_int len; const char name[9]; } powertec_ptyp_t; /* * This is the list of partition types that we recognise - * we use this table to convert ptyp_ to name and vice versa */ static powertec_ptyp_t powertec_ptypes[] = { { ptyp_linux_swap, 8, "LinuxS:" }, { ptyp_linux_native, 8, "LinuxN:" }, { ptyp_filecore, 8, "RiscOs:" }, { ptyp_pt_oldmap, 8, "OldMap:" }, { ptyp_pt_backup, 8, "Backup:" }, { ptyp_pt_empty, 7, "Empty:" }, { ptyp_dos16g32, 8, "DOSDisc:" }, { ptyp_unknown, 0, "" } }; #define NR_TYPES (sizeof(powertec_ptypes) / sizeof(powertec_ptyp_t)) /* Prototype: char *powertec_getstr(pe_t *pe) * Purpose : Read the type string from the partition table * Params : pe - pointer to powertec partition entty * Returns : pointer to NUL terminated string */ static char * powertec_getstr(pe_t *pe) { u_int len; char *str = NULL; for (len = 0; len < sizeof(pe->type); len++) if (pe->type[len] == '\0') break; if (len) { str = malloc(len + 1); if (str) { memcpy(str, pe->type, len); str[len] = '\0'; } } return str; } /* Prototype: void powertec_putstr(pe_t *pe, char *str) * Purpose : Write the type string to the partition table * Params : pe - pointer to powertec partition entty * : str - pointer to string */ static void powertec_putstr(pe_t *pe, char *str) { memcpy(pe->type, str, strlen(str)); } /* Prototype: ptyp_t powertec_gettype(pe_t *pe) * Purpose : Convert a powertec partition type to our internal * partition type numbers * Params : pe - pointer to powertec partition entry * Returns : our internal ptyp_ number, or ptyp_unknown if not recognised */ static ptyp_t powertec_gettype(pe_t *pe) { u_int i; /* * If we don't recognise the type, we will be set at the final entry */ for (i = 0; i < NR_TYPES - 1; i++) if (memcmp(pe->type, powertec_ptypes[i].name, powertec_ptypes[i].len) == 0) break; return powertec_ptypes[i].type; } /* Prototype: void powertec_puttype(pe_t *pe, ptyp_t type) * Purpose : Convert our internal partition numbers to a * powertec partition type name * Params : pe - pointer to powertec partition entry * : type - our internal partition type number * Notes : if we are unable to store our partition type number, * we will assert. This should never happen. */ static void powertec_puttype(pe_t *pe, ptyp_t type) { u_int i; for (i = 0; i < NR_TYPES - 1; i++) if (powertec_ptypes[i].type == type) break; if (i >= NR_TYPES) assert(0); memset(pe->type, 0, sizeof (pe->type)); memcpy(pe->type, powertec_ptypes[i].name, powertec_ptypes[i].len); } /* Prototype: u_int powertec_checksum(u_char *sector) * Purpose : generate a PowerTec SCSI checksum * Params : sector - sector comtaining partition information * Returns : calculated checksum */ static u_int powertec_checksum(u_char *sector) { u_int sum = 0x2a; int i; for (i = 0; i < 511; i++) sum += sector[i]; return sum & 255; } /* Prototype: u_int powertec_detect(part_t *part) * Function : detect a drive partitioned with an ICS IDE table * Params : part - partitionable device * Returns : FALSE if not detected */ static u_int powertec_detect(part_t *part) { powertec_psect_t sector; u_int ret = 0; dbg_printf("powertec_detect()"); dbg_level_up(); assert(part != NULL); do { u_int disc_csum, calc_csum; if (blkio_setblocksize(part->blkio, POWERTEC_SECTOR_SIZE) != POWERTEC_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector.sector, POWERTEC_PART_SECTOR, 1) != 1) break; disc_csum = sector.sector[511]; calc_csum = powertec_checksum(sector.sector); dbg_printf("-powertec disc checksum: %02X", disc_csum); dbg_printf("-powertec calc checksum: %02X", calc_csum); if (calc_csum != disc_csum) break; ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } /* Prototype: u_int powertec_readinfo(part_t *part) * Function : read all partition information from the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int powertec_readinfo(part_t *part) { u_int ret = 0; dbg_printf("powertec_readinfo()"); dbg_level_up(); assert(part != NULL); do { powertec_psect_t sector; partinfo_i_t pinfo; u_int part_no; if (blkio_read(part->blkio, sector.sector, POWERTEC_PART_SECTOR, 1) != 1) break; ret = 1; for (part_no = 0; part_no < POWERTEC_NR_PARTITIONS; part_no++) if (sector.pe[part_no].size != 0) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.pe[part_no].start; pinfo.info.blk_end = sector.pe[part_no].start + sector.pe[part_no].size - 1; pinfo.info.kern_part_no = part_no + 1; pinfo.data.powertec.idx = part_no; pinfo.data.powertec.type = powertec_getstr(§or.pe[part_no]); pinfo.info.type = powertec_gettype(§or.pe[part_no]); if (!part_add(part, part_no + 1, &pinfo)) { ret = 0; break; } /* should we check the filecore boot sector? */ } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int powertec_writeinfo(part_t *part) * Function : write all partition information back to the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int powertec_writeinfo(part_t *part) { powertec_psect_t sector; u_int part_no, ret = 0; dbg_printf("powertec_writeinfo()"); dbg_level_up(); assert(part != NULL); assert(part->nr_partitions <= POWERTEC_NR_PARTITIONS); memset(sector.sector, 0, sizeof(sector.sector)); for (part_no = 0; part_no < part->nr_partitions; part_no++) if (part->partinfo[part_no] && part->partinfo[part_no]->info.type != ptyp_none) { partinfo_i_t *info = part->partinfo[part_no]; u_int idx = info->data.powertec.idx; char *str = info->data.powertec.type; sector.pe[idx].start = info->info.blk_start; sector.pe[idx].size = info->info.blk_end - info->info.blk_start + 1; if (info->info.type != ptyp_unknown) powertec_puttype(§or.pe[idx], info->info.type); else powertec_putstr(§or.pe[idx], str); } sector.sector[254] = 1; /* what does this do? */ sector.sector[511] = powertec_checksum(sector.sector); #ifdef POWERTEC_DUMP dbg_memdump(sector.sector, POWERTEC_SECTOR_SIZE); #endif #ifdef POWERTEC_SAVE if (blkio_write(part->blkio, sector.sector, POWERTEC_PART_SECTOR, 1) != 1) set_error("unable to write partition sector"); else ret = 1; #else set_error("PowerTec partition information cannot be saved with this build"); #endif dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int powertec_allocate(part_t *part, partinfo_t *pnew) * Function : allocate a partition entry number and a kernel * partition number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int powertec_allocate(part_t *part, partinfo_t *pnew) { u_int parn, test; assert(part != NULL); dbg_printf("powertec_allocate()"); dbg_level_up(); /* * Find a free slot in the partition table */ for (test = 1, parn = 1; parn < part->nr_partitions; parn++) if (part->partinfo[parn] && part->partinfo[parn]->data.powertec.idx == test) { test += 1; parn = 1; } /* * Look for a free entry in our structures */ for (parn = 1; parn < part->nr_partitions; parn++) if (!part->partinfo[parn]) break; if (parn > POWERTEC_NR_PARTITIONS || test > POWERTEC_NR_PARTITIONS) { set_error("partition table is full"); parn = PARN_ERROR; } else { pnew->kern_part_no = test; pnew->type = ptyp_linux_native; } dbg_level_down(); dbg_printf("ret %d", parn); return PARN_ERROR; } /* Prototype: u_int powertec_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int powertec_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("powertec_validate_change(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(pold != NULL); assert(parn < part->nr_partitions); do { if (pold->type == ptyp_filecore) { set_error("you cannot edit a filecore partition"); break; } if (pnew) { if (pnew->type == ptyp_filecore) { set_error("you cannot create a filecore partition"); break; } if (check_overlap(part, parn, pnew)) { set_error("the modified partition overlaps an existing partition"); break; } } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int powertec_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int powertec_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("powertec_validate_creation(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); do { if (pold != NULL) { set_error("unable to create partition in this slot"); break; } if (pnew) { if (pnew->type == ptyp_filecore) { set_error("you cannot create a filecore partition"); break; } if (check_overlap(part, parn, pnew)) { set_error("the new partition overlaps an existing partition"); break; } } ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int powertec_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Function : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int powertec_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("powertec_validate_deletion(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); if (parn < 2) set_error("the first Filecore partition cannot be deleted"); else ret = 1; dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int powertec_validate_partno(part_t *part, u_int parn) * Function : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int powertec_validate_partno(part_t *part, u_int parn) { u_int ret = 0; assert(part != NULL); dbg_printf("powertec_validate_partno(parn=%d)", parn); dbg_level_up(); if (parn < POWERTEC_NR_PARTITIONS) ret = 1; else set_error("the requested partition is invalid"); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: ptyp_t powertec_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : return next valid partition type for an entry * Params : part - partitionable device * : parn - partition number * : current - currently selected partition type * : dir - next/previous flag * Returns : next valid partition type */ static ptyp_t powertec_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { ptyp_t ptype; s_int i; dbg_printf("powertec_nexttype(parn=%d, current=0x%X, %s)", parn, current, dir > 0 ? "next" : dir < 0 ? "previous" : "???"); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); for (i = 0; i < NR_TYPES - 1; i++) if (powertec_ptypes[i].type == current) break; if (powertec_ptypes[i].type == current) { i += dir; if (i < 0) i = 0; if (i > NR_TYPES - 1) i = NR_TYPES - 1; ptype = powertec_ptypes[i].type; } else ptype = ptyp_pt_empty; dbg_level_down(); dbg_printf("ret 0x%X", ptype); return ptype; } scheme_t powertec_scheme = { "PowerTec", powertec_detect, powertec_readinfo, powertec_writeinfo, powertec_allocate, powertec_validate_change, powertec_validate_creation, powertec_validate_deletion, powertec_validate_partno, powertec_nexttype }; acorn-fdisk-3.0.6.orig/lib/scheme/riscix.c0100644000000000000000000003416406766721615017065 0ustar rootroot/* * lib/scheme/riscix.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include #include "util/debug.h" #include "util/error.h" #include "part/part.h" #include "part/utils.h" #include "blkio/filecore.h" #include "scheme/filecore.h" #define RISCIX_DEBUG #define RISCIX_SAVE #define RISCIX_MAX_PARTITIONS 10 #define MAX_RISCIX_NAME_LEN 16 union partition_sector_u { struct { u32 magic; u32 date; struct { u32 start; u32 length; u32 one; char name[MAX_RISCIX_NAME_LEN]; } p[RISCIX_MAX_PARTITIONS]; } p; u8 sector[FILECORE_SECTOR_SIZE]; }; static u_int riscix_detect(part_t *part) { u_char sector[FILECORE_SECTOR_SIZE]; disc_record_t *disc_record; u_int ret = 0; dbg_printf("riscix_detect()"); dbg_level_up(); assert(part != NULL); do { u_int disc_csum, calc_csum; if (blkio_setblocksize(part->blkio, FILECORE_SECTOR_SIZE) != FILECORE_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector, FILECORE_BOOT_SECTOR, 1) != 1) break; disc_csum = sector[511]; calc_csum = filecore_checksum(sector); dbg_printf("-riscix disc checksum: %02X", disc_csum); dbg_printf("-riscix calc checksum: %02X", calc_csum); if (calc_csum != disc_csum) break; part->data.riscix.disc_record = *disc_record; part->data.riscix.boot_checksum = sector[511]; /* * Check that we do not have a sector filled with zero */ disc_record = (disc_record_t *)(sector + 0x1c0); if (disc_record->d.disc_size == 0 && disc_record->d.disc_size_high == 0) break; ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } static u_int riscix_readinfo(part_t *part) { u_int ret = 0; dbg_printf("riscix_readinfo()"); dbg_level_up(); assert(part != NULL); do { disc_record_t *disc_record = &part->data.filecore_linux.disc_record; union partition_sector_u sector; partinfo_i_t pinfo; blk_t parttable_start; u_int pnr; /* * First partition is the filecore image */ pinfo.info.chs_valid = 0; pinfo.info.blk_start = 0; pinfo.info.blk_end = (disc_record->d.disc_size_high << (32 - 9) | disc_record->d.disc_size >> 9) - 1; pinfo.info.type = ptyp_filecore; pinfo.info.kern_part_no = 1; /* * Locate the start of the non-filecore image, and add that as * partition 2. (It is always partition 2). */ parttable_start = (disc_record->packing[509 - 0x1c0] | disc_record->packing[510 - 0x1c0] << 8) * disc_record->d.heads * disc_record->d.secspertrack; /* * If we don't have a non-filecore image, then we don't have a Linux * partition table, and therefore no Linux partitions. */ switch (disc_record->packing[508 - 0x1c0]) { case 0: if (!part_add(part, 1, &pinfo)) break; pinfo.info.chs_valid = 0; pinfo.info.blk_start = pinfo.info.blk_end + 1; pinfo.info.blk_end = pinfo.info.blk_start; pinfo.info.type = ptyp_reserved; pinfo.info.kern_part_no = 2; if (!part_add(part, 2, &pinfo)) goto quit; ret = 1; goto quit; case 2: pinfo.info.blk_end = parttable_start - 1; case 1: if (!part_add(part, 1, &pinfo)) break; pinfo.info.chs_valid = 0; pinfo.info.blk_start = parttable_start; pinfo.info.blk_end = pinfo.info.blk_start; pinfo.info.type = ptyp_linux_table; pinfo.info.kern_part_no = 2; if (blkio_read(part->blkio, §or, parttable_start, 1) != 1) break; if (sector.p.magic != 0x4a657320) break; if (!part_add(part, 2, &pinfo)) break; for (pnr = 0; pnr < RISCIX_MAX_PARTITIONS - 2; pnr++) { if (sector.p.p[pnr].one == 0 || memcmp(sector.p.p[pnr].name, "All", 4) == 0) continue; pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.p.p[pnr].start; pinfo.info.blk_end = sector.p.p[pnr].start + sector.p.p[pnr].length - 1; if (memcmp(sector.p.p[pnr].name, "LSwap", 6) == 0) pinfo.info.type = ptyp_linux_swap; else if (memcmp(sector.p.p[pnr].name, "LNative", 8) == 0) pinfo.info.type = ptyp_linux_native; else pinfo.info.type = ptyp_reserved; pinfo.info.kern_part_no = 3 + pnr; if (!part_add(part, pnr + 3, &pinfo)) break; } ret = 1; } } while (0); quit: dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } static u_int riscix_writeinfo(part_t *part) { u_int ret = 0; dbg_printf("riscix_writeinfo()"); dbg_level_up(); do { disc_record_t *disc_record = &part->data.filecore_linux.disc_record; union partition_sector_u sector; if (blkio_read(part->blkio, sector.sector, FILECORE_BOOT_SECTOR, 1) != 1) break; /* * Ensure that the information we read was a valid boot sector. * Ok, I'm being paranoid... but then partitioning is dangerous. */ if (filecore_checksum(sector.sector) != sector.sector[511]) { set_error("filecore boot sector is corrupt"); break; } /* * We check to make sure that the checksum we have here is * identical to that when we read the sector in riscix_readinfo. * If it's different, we're in trouble! */ if (sector.sector[511] != part->data.filecore_linux.boot_checksum) { set_error("filecore boot sector has been changed by another program"); break; } /* * If we have partitions > 2, then we ave a non-ADFS descriptor. * Otherwise, we remove the non-ADFS descriptor (If it wasn't a * RiscIX descriptor, we shouldn't be here). */ if (part->nr_partitions > 2 && part->partinfo[2]) { u_int start_cyl; u_int type; start_cyl = part->partinfo[2]->info.blk_start / (disc_record->d.heads * disc_record->d.secspertrack); if (part->partinfo[1]->info.blk_end == (disc_record->d.disc_size_high << (32 - 9) | disc_record->d.disc_size >> 9) - 1) type = 1; else type = 2; /* * This should always be true. If it's incorrect, then you've * been playing, and I'm confused. */ assert(start_cyl == part->partinfo[2]->info.chs_start.cylinder); sector.sector[508] = type; sector.sector[509] = start_cyl & 255; sector.sector[510] = start_cyl >> 8; } else { sector.sector[508] = 0; sector.sector[509] = 0; sector.sector[510] = 0; } /* * We have made our changes to the boot sector. Recalculate * the checksum, and don't forget to update our own copy. */ sector.sector[511] = filecore_checksum(sector.sector); part->data.filecore_linux.boot_checksum = sector.sector[511]; #ifdef RISCIX_DEBUG dbg_printf("Filecore boot sector (0xc00):"); dbg_memdump(sector.sector, FILECORE_SECTOR_SIZE); #endif #ifdef RISCIX_SAVE if (blkio_write(part->blkio, sector.sector, FILECORE_BOOT_SECTOR, 1) != 1) { set_error("unable to write filecore boot sector"); break; } #endif if (part->nr_partitions > 2 && part->partinfo[2]) { blk_t parttable_start = part->partinfo[2]->info.blk_start; u_int i; if (blkio_read(part->blkio, sector.sector, parttable_start, 1) != 1) break; /* * Now, write the partition information to the * RiscIX partition sectors. */ if (sector.p.magic != 0x4a657320) { memset(sector.sector, 0, sizeof(sector.sector)); sector.p.magic = 0x4a657320; } sector.p.date = time(NULL); for (i = 0; i < part->nr_partitions - 3; i++) { partinfo_i_t *info = part->partinfo[i + 3]; if (info && info->info.type != ptyp_none) { sector.p.p[i].start = info->info.blk_start; sector.p.p[i].length = info->info.blk_end - info->info.blk_start + 1; sector.p.p[i].one = 1; switch(info->info.type) { case ptyp_linux_native: strcpy(sector.p.p[i].name, "LNative"); break; case ptyp_linux_swap: strcpy(sector.p.p[i].name, "LSwap"); break; case ptyp_reserved: break; default: assert(0); } } } #ifdef RISCIX_DEBUG dbg_printf("RiscIX partition sector (0x%X):", parttable_start); dbg_memdump(sector.sector, FILECORE_SECTOR_SIZE); #endif #ifdef RISCIX_SAVE if (blkio_write(part->blkio, sector.sector, parttable_start, 1) != 1) { set_error("unable to write linux partition sector"); break; } ret = 1; #endif } } while (0); #ifndef RISCIX_SAVE set_error("filecore-riscix partition information cannot be saved with this build"); #endif dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int riscix_allocate(part_t *part, partinfo_t *pnew) * Function : allocate a partition entry number and a kernel * partition number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int riscix_allocate(part_t *part, partinfo_t *pnew) { u_int parn; dbg_printf("riscix_allocate()"); dbg_level_up(); assert(pnew != NULL); if (part->nr_partitions < 2) { set_error("Partition table missing"); parn = PARN_ERROR; } else { for (parn = 3; parn < part->nr_partitions; parn++) if (part->partinfo[parn] == NULL) break; if (parn >= RISCIX_MAX_PARTITIONS) { set_error("partition table is full"); parn = PARN_ERROR; } else { pnew->kern_part_no = parn; pnew->type = ptyp_linux_native; } } dbg_level_down(); dbg_printf("ret %d", parn); return parn; } /* Prototype: u_int riscix_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int riscix_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("riscix_validate_change(parn=%d)", parn); dbg_level_up(); assert(parn < part->nr_partitions); do { if (pnew) { if (pnew->type != ptyp_linux_native && pnew->type != ptyp_linux_swap) { set_error("invalid partition type"); break; } if (check_overlap(part, parn, pnew)) { set_error("the modified partition overlaps an existing partition"); break; } } if (parn >= 3 && parn < part->nr_partitions) ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int riscix_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int riscix_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("riscix_validate_creation(parn=%d)", parn); dbg_level_up(); assert(parn < part->nr_partitions); do { if (pold != NULL) { set_error("unable to create partition in this slot"); break; } if (pnew) { if (pnew->type != ptyp_linux_native && pnew->type != ptyp_linux_swap) { set_error("invalid partition type"); break; } if (check_overlap(part, parn, pnew)) { set_error("the new partition overlaps an existing partition"); break; } } if (part->partinfo[2] && part->partinfo[2]->info.type == ptyp_reserved) part->partinfo[2]->info.type = ptyp_linux_table; ret = 1; } while (0); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int riscix_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Function : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int riscix_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("riscix_validate_deletion(parn=%d)", parn); dbg_level_up(); assert(pold != NULL); assert(parn < part->nr_partitions); switch (pold->kern_part_no) { case 0: case 1: /* filecore partition */ set_error("unable to delete filecore partition"); break; case 2: { int i; for (i = 3; i < part->nr_partitions; i++) if (part->partinfo[i]) break; if (i >= part->nr_partitions) ret = 1; else set_error("delete all partitions contained within first"); } break; default: ret = 1; break; } dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int riscix_validate_partno(part_t *part, u_int parn) * Function : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int riscix_validate_partno(part_t *part, u_int parn) { u_int ret = 0; dbg_printf("riscix_validate_partno(parn=%d)", parn); dbg_level_up(); if (parn < RISCIX_MAX_PARTITIONS) ret = 1; else set_error("the requested partition is invalid"); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } scheme_t filecore_riscix_scheme = { "Filecore/RISCiX", riscix_detect, riscix_readinfo, riscix_writeinfo, riscix_allocate, riscix_validate_change, riscix_validate_creation, riscix_validate_deletion, riscix_validate_partno }; acorn-fdisk-3.0.6.orig/lib/scheme/filecore.h0100644000000000000000000000061306476251432017342 0ustar rootroot/* * lib/scheme/filecore.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_FILECORE_H #define SCHEME_FILECORE_H #include "util/types.h" /* Function: u_int filecore_checksum (unsigned char *sector) * Purpose : Calculate a filecore checksum * Params : sector - filecore sector to checksum * Returns : filecore checksum */ extern u_int filecore_checksum (u8 *sector); #endif acorn-fdisk-3.0.6.orig/lib/scheme/icside.h0100644000000000000000000000050206475627774017026 0ustar rootroot/* * lib/scheme/icside.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_ICSIDE_H #define SCHEME_ICSIDE_H #define SCHEME_ICSIDE typedef struct { u_int unused; } icside_data_t; typedef struct { u_int idx; /* index into partition table */ } icside_part_t; extern struct scheme icside_scheme; #endif acorn-fdisk-3.0.6.orig/lib/scheme/linux.h0100644000000000000000000000073106476251462016715 0ustar rootroot/* * lib/scheme/linux.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_LINUX_H #define SCHEME_LINUX_H #include "blkio/filecore.h" #define SCHEME_FILECORE_LINUX typedef struct { disc_record_t disc_record; /* disc record */ u8 boot_checksum; /* checksum of boot sector */ } filecore_linux_data_t; typedef struct { u_int part_offset; /* offset into partition table */ } filecore_linux_part_t; extern struct scheme filecore_linux_scheme; #endif acorn-fdisk-3.0.6.orig/lib/scheme/pcbios.h0100644000000000000000000000054706503477611017037 0ustar rootroot/* * lib/scheme/pcbios.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_PCBIOS_H #define SCHEME_PCBIOS_H #define SCHEME_PCBIOS typedef struct { u8 *pcboot_sector; u8 *extended_sector; } pcbios_data_t; typedef struct { u_int part_offset; /* offset into partition table */ } pcbios_part_t; extern struct scheme pcbios_scheme; #endif acorn-fdisk-3.0.6.orig/lib/scheme/powertec.h0100644000000000000000000000062306562261544017404 0ustar rootroot/* * lib/scheme/powertec.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_POWERTEC_H #define SCHEME_POWERTEC_H #define SCHEME_POWERTEC typedef struct { u_int unused; } powertec_data_t; typedef struct { u_int idx; /* offset into partition table */ char *type; /* powertec type name (for unknown partitions) */ } powertec_part_t; extern struct scheme powertec_scheme; #endif acorn-fdisk-3.0.6.orig/lib/scheme/riscix.h0100644000000000000000000000070306677117070017055 0ustar rootroot/* * lib/scheme/riscix.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_RISCiX_H #define SCHEME_RISCiX_H #define SCHEME_FILECORE_RISCiX typedef struct { disc_record_t disc_record; /* disc record */ u8 boot_checksum; /* checksum of boot sector */ } filecore_riscix_data_t; typedef struct { u_int part_offset; /* offset into partition table */ } filecore_riscix_part_t; extern struct scheme filecore_riscix_scheme; #endif acorn-fdisk-3.0.6.orig/lib/scheme/Makefile0100644000000000000000000000047306722736175017053 0ustar rootrootAR = ar CC = cc ARFLAGS = rc CFLAGS = -DUNIX -O2 -Wall -I.. -g OBJS = add.o chs.o overlap.o filecore.o icside.o \ linux.o pcbios.o powertec.o riscix.o eesox.o LIB = ../scheme.a all: $(LIB) clean:; $(RM) $(LIB) *.o $(LIB): $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) .c.o:; $(CC) $(CFLAGS) -o $@ -c $< acorn-fdisk-3.0.6.orig/lib/scheme/eesox.c0100644000000000000000000001673406562261345016703 0ustar rootroot/* * lib/scheme/eesox.c * * Partition backend for Eesox SCSI partitioning scheme on the * Acorn machines. * * Copyright (C) 1998 Russell King */ #include #include #include #include "util/debug.h" #include "util/error.h" #include "util/types.h" #include "part/part.h" #include "part/utils.h" #define EESOX_SECTOR_SIZE 512 #define EESOX_PART_SECTOR 7 #define EESOX_NR_PARTITIONS 8 #define NOSAVE_POWERTEC typedef struct { char magic[6]; char discname[10]; u32 start; u32 unused6; u32 unused7; u32 unused8; } ep_t; typedef union { ep_t ep[EESOX_NR_PARTITIONS]; u8 sector[EESOX_SECTOR_SIZE]; } eesox_psect_t; static const char eesox_name[] = { 'N', 'e', 'i', 'l', ' ', 'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' ' }; /* Prototype: u_int eesox_detect(part_t *part) * Function : detect a drive partitioned with an ICS IDE table * Params : part - partitionable device * Returns : FALSE if not detected */ static u_int eesox_detect(part_t *part) { eesox_psect_t sector; u_int ret = 0; dbg_printf("eesox_detect()"); dbg_level_up(); assert(part != NULL); do { u_int i; if (blkio_setblocksize(part->blkio, EESOX_SECTOR_SIZE) != EESOX_SECTOR_SIZE) break; if (blkio_read(part->blkio, sector.sector, EESOX_PART_SECTOR, 1) != 1) break; for (i = 0; i < EESOX_SECTOR_SIZE; i++) sector.sector[i] ^= eesox_name[i & 15]; if (memcmp(sector.sector, "Eesox", 6) == 0) ret = 1; } while (0); dbg_level_down(); dbg_printf("ret%s detected", ret ? "" : " not"); return ret; } /* Prototype: u_int eesox_readinfo(part_t *part) * Function : read all partition information from the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int eesox_readinfo(part_t *part) { u_int ret = 0; dbg_printf("eesox_readinfo()"); dbg_level_up(); assert(part != NULL); do { eesox_psect_t sector; partinfo_i_t pinfo; u_int part_no, i; if (blkio_read(part->blkio, sector.sector, EESOX_PART_SECTOR, 1) != 1) break; for (i = 0; i < EESOX_SECTOR_SIZE; i++) sector.sector[i] ^= eesox_name[i & 15]; ret = 1; for (part_no = 0; part_no < EESOX_NR_PARTITIONS; part_no++) if (memcmp(sector.ep[part_no].magic, "Eesox", 6) == 0) { pinfo.info.chs_valid = 0; pinfo.info.blk_start = sector.ep[part_no].start; pinfo.info.blk_end = sector.ep[part_no].start + 1; pinfo.info.kern_part_no = part_no + 1; pinfo.info.type = ptyp_filecore; dbg_memdump(§or.ep[part_no], sizeof(sector.ep[part_no])); if (!part_add(part, part_no + 1, &pinfo)) { ret = 0; break; } /* should we check the filecore boot sector? */ } } while (0); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int eesox_writeinfo(part_t *part) * Function : write all partition information back to the drive * Params : part - partitionable device * Returns : FALSE on error */ static u_int eesox_writeinfo(part_t *part) { u_int ret = 0; dbg_printf("eesox_writeinfo()"); dbg_level_up(); assert(part != NULL); assert(part->nr_partitions <= EESOX_NR_PARTITIONS); set_error("EESOX partition information cannot be saved with this build"); dbg_level_down(); dbg_printf("ret %s", ret ? "ok" : "error"); return ret; } /* Prototype: u_int eesox_allocate(part_t *part, partinfo_t *pnew) * Function : allocate a partition entry number and a kernel * partition number for a new partition * Params : part - partitionable device * Returns : partition number, or PARN_ERROR on error */ static u_int eesox_allocate(part_t *part, partinfo_t *pnew) { u_int parn = PARN_ERROR; assert(part != NULL); dbg_printf("eesox_allocate()"); dbg_level_up(); dbg_level_down(); dbg_printf("ret %d", parn); return parn; } /* Prototype: u_int eesox_validate_change(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * : pnew - new partition information * Returns : FALSE if we reject the change */ static u_int eesox_validate_change(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("eesox_validate_change(parn=%d)", parn); dbg_level_up(); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int eesox_validate_creation(part_t *part, u_int parn, * const partinfo_t *pold, const partinfo_t *pnew) * Function : validate changes made to a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information (NULL if none) * : pnew - new partition information * Returns : FALSE if we reject the creation */ static u_int eesox_validate_creation(part_t *part, u_int parn, const partinfo_t *pold, const partinfo_t *pnew) { u_int ret = 0; dbg_printf("eesox_validate_creation(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int eesox_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) * Function : validate a deletion of a partition * Params : part - partitionable device * : parn - partition number * : pold - old partition information * Returns : FALSE if we reject the deletion */ static u_int eesox_validate_deletion(part_t *part, u_int parn, const partinfo_t *pold) { u_int ret = 0; dbg_printf("eesox_validate_deletion(parn=%d)", parn); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: u_int eesox_validate_partno(part_t *part, u_int parn) * Function : validate a partition number * Params : part - partitionable device * : parn - partition number * Returns : FALSE if we reject the partition number */ static u_int eesox_validate_partno(part_t *part, u_int parn) { u_int ret = 0; assert(part != NULL); dbg_printf("eesox_validate_partno(parn=%d)", parn); dbg_level_up(); dbg_level_down(); dbg_printf("ret %svalid", ret ? "" : "in"); return ret; } /* Prototype: ptyp_t eesox_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) * Purpose : return next valid partition type for an entry * Params : part - partitionable device * : parn - partition number * : current - currently selected partition type * : dir - next/previous flag * Returns : next valid partition type */ static ptyp_t eesox_nexttype(part_t *part, u_int parn, ptyp_t current, int dir) { ptyp_t ptype = current; dbg_printf("eesox_nexttype(parn=%d, current=0x%X, %s)", parn, current, dir > 0 ? "next" : dir < 0 ? "previous" : "???"); dbg_level_up(); assert(part != NULL); assert(parn < part->nr_partitions); dbg_level_down(); dbg_printf("ret 0x%X", ptype); return ptype; } scheme_t eesox_scheme = { "EESOX", eesox_detect, eesox_readinfo, eesox_writeinfo, eesox_allocate, eesox_validate_change, eesox_validate_creation, eesox_validate_deletion, eesox_validate_partno, eesox_nexttype }; acorn-fdisk-3.0.6.orig/lib/scheme/eesox.h0100644000000000000000000000047506562261345016703 0ustar rootroot/* * lib/scheme/eesox.h * * Copyright (C) 1997,1998 Russell King */ #ifndef SCHEME_EESOX_H #define SCHEME_EESOX_H #define SCHEME_EESOX typedef struct { u_int unused; } eesox_data_t; typedef struct { u_int idx; /* offset into partition table */ } eesox_part_t; extern struct scheme eesox_scheme; #endif acorn-fdisk-3.0.6.orig/lib/util/0042755000000000000000000000000007101375524015112 5ustar rootrootacorn-fdisk-3.0.6.orig/lib/util/debug.c0100644000000000000000000000314106505005006016326 0ustar rootroot/* * lib/util/debug.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include static int debug_level; static FILE *debug_file; /* Function: void dbg_level_up (void) * Purpose : increase the indentation level of debugs */ void dbg_level_up (void) { debug_level += 2; } /* Function: void dbg_level_up (void) * Purpose : decrease the indentation level of debugs */ void dbg_level_down (void) { if (debug_level > 0) debug_level -= 2; } /* Function: void dbg_printf (const char *fmt, ...) * Purpose : write some debugging information * Params : fmt - printf-like format string */ void dbg_printf (const char *fmt, ...) { static char buffer[2048]; va_list ap; va_start (ap, fmt); vsprintf (buffer, fmt, ap); va_end (ap); if (!debug_file) debug_file = fopen("/tmp/part.debug", "w+"); if (debug_file) fprintf (debug_file, "%*s%s\n", debug_level, "", buffer); } /* Function: void dbg_memdump (void *data, int length) * Purpose : dump out a block of memory * Params : data - start of memory to dump * : length - number of bytes to dump */ void dbg_memdump (void *data, int length) { const char *byte = (char *)data; int offset, i; for (offset = 0; offset < length; offset += 16) { fprintf(debug_file, "%04X : ", offset); for (i = offset; i < offset + 16; i++) fprintf(debug_file, "%02X ", byte[i]); fprintf(debug_file, ": "); for (i = offset; i < offset + 16; i++) if (isprint(byte[i])) fprintf(debug_file, "%c", byte[i]); else fprintf(debug_file, "."); fprintf(debug_file, "\n"); } } acorn-fdisk-3.0.6.orig/lib/util/error.c0100644000000000000000000000175506473604364016422 0ustar rootroot/* * lib/util/error.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "util/error.h" static char errmsg[2048]; static int error_set; /* Function: void set_error (const char *fmt, ...) * Purpose : Set error string * Params : fmt - printf-like format */ void set_error (const char *fmt, ...) { va_list ap; if (fmt) { va_start (ap, fmt); vsprintf (errmsg, fmt, ap); va_end (ap); error_set = 1; } else { errmsg[0] = '\0'; error_set = 0; } } /* Function: const char *get_error(void) * Purpose : Get error string * Returns : const pointer to error message buffer */ const char *get_error(void) { error_set = 0; return errmsg; } /* Function: u_int is_error_set(void) * Purpose : check to see if an error is set * Returns : FALSE if not set */ u_int is_error_set(void) { return error_set; } /* Function: void clear_error(void) * Purpose : clear error condition */ void clear_error(void) { error_set = 0; } acorn-fdisk-3.0.6.orig/lib/util/Makefile0100644000000000000000000000041206722736175016555 0ustar rootrootAR = ar CC = cc ARFLAGS = rc CFLAGS = -DUNIX -O2 -Wall -I.. -g OBJS = debug.o strcscmp.o zmalloc.o error.o warning.o LIB = ../util.a all: $(LIB) clean:; $(RM) $(LIB) *.o $(LIB): $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS) .c.o:; $(CC) $(CFLAGS) -o $@ -c $< acorn-fdisk-3.0.6.orig/lib/util/strcscmp.c0100644000000000000000000000037706124756252017123 0ustar rootroot#include #include int strcasecmp (const char *s1, const char *s2) { int diff; do { diff = tolower(*s1) - tolower(*s2); if (diff) return diff; if (!*s1) return 0; s1 ++; s2 ++; } while (1); } acorn-fdisk-3.0.6.orig/lib/util/strncscmp.c0100644000000000000000000000051406124756304017270 0ustar rootroot#include #include int strncasecmp (const char *s1, const char *s2, int len) { int diff; diff = 0; do { if (--len < 0) return diff; diff = tolower(*s1) - tolower(*s2); if (diff) return diff; if (!*s1) return 0; s1 ++; s2 ++; } while (len); return 0; } acorn-fdisk-3.0.6.orig/lib/util/zmalloc.c0100644000000000000000000000065606452773514016732 0ustar rootroot/* * lib/util/zmalloc.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include "zmalloc.h" /* Function: void *zmalloc (size_t size) * Purpose : malloc some memory (and clear it) * Params : size - number of bytes to malloc * Returns : pointer to allocated memory */ void *zmalloc (size_t size) { void *ptr = malloc (size); if (ptr) memset (ptr, 0, size); return ptr; } acorn-fdisk-3.0.6.orig/lib/util/debug.h0100644000000000000000000000145406503054471016350 0ustar rootroot/* * lib/debug.h * * Copyright (C) 1997,1998 Russell King */ #ifndef LIB_DEBUG_H #define LIB_DEBUG_H /* Function: void dbg_level_up (void) * Purpose : increase the indentation level of debugs */ extern void dbg_level_up (void); /* Function: void dbg_level_up (void) * Purpose : decrease the indentation level of debugs */ extern void dbg_level_down (void); /* Function: void dbg_printf (const char *fmt, ...) * Purpose : write some debugging information * Params : fmt - printf-like format string */ extern void dbg_printf (const char *fmt, ...); /* Function: void dbg_memdump (void *data, int length) * Purpose : dump out a block of memory * Params : data - start of memory to dump * : length - number of bytes to dump */ extern void dbg_memdump (void *data, int length); #endif acorn-fdisk-3.0.6.orig/lib/util/types.h0100644000000000000000000000104606503056350016421 0ustar rootroot/* * util/types.h * * Copyright (C) 1998 Russell King */ #ifndef UTIL_TYPES_H #define UTIL_TYPES_H #ifndef UNIX typedef unsigned int u_int; typedef unsigned int u_long; typedef unsigned char u_char; #else #include #endif typedef signed int s_int; typedef signed int s_long; typedef signed char s_char; typedef unsigned int bool_t; typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; typedef signed int s32; typedef signed short s16; typedef signed char s8; #endif acorn-fdisk-3.0.6.orig/lib/util/error.h0100644000000000000000000000126506473604150016414 0ustar rootroot/* * lib/error.h * * Copyright (C) 1997,1998 Russell King */ #ifndef ERROR_H #define ERROR_H #include "util/types.h" /* Function: void set_error (const char *fmt, ...) * Purpose : Set error string * Params : fmt - printf-like format */ void set_error (const char *fmt, ...); /* Function: const char *get_error(void) * Purpose : Get error string * Returns : const pointer to error message buffer */ const char *get_error(void); /* Function: u_int is_error_set(void) * Purpose : check to see if an error is set * Returns : FALSE if not set */ u_int is_error_set(void); /* Function: void clear_error(void) * Purpose : clear error condition */ void clear_error(void); #endif acorn-fdisk-3.0.6.orig/lib/util/zmalloc.h0100644000000000000000000000051506452745270016727 0ustar rootroot/* * lib/zmalloc.h * * Copyright (C) 1997,1998 Russell King */ #ifndef LIB_MALLOC_H #define LIB_MALLOC_H /* Function: void *zmalloc (size_t size) * Purpose : malloc some memory (and clear it) * Params : size - number of bytes to malloc * Returns : pointer to allocated memory */ extern void *zmalloc (size_t size); #endif acorn-fdisk-3.0.6.orig/lib/util/warning.c0100644000000000000000000000162106506311564016720 0ustar rootroot/* * lib/util/warning.c * * Copyright (C) 1997,1998 Russell King */ #include #include #include #include "util/warning.h" static char warning_message[2048]; /* Function: void issue_warning (const char *fmt, ...) * Purpose : Set warning string * Params : fmt - printf-like format */ void issue_warning (const char *fmt, ...) { va_list ap; if (fmt) { int characters = 0; char *p, *s, *e; va_start (ap, fmt); p = warning_message; p += sprintf(p, "Warning: "); vsprintf (p, fmt, ap); va_end (ap); for (p = s = e = warning_message;; p += 1) { if (!*p) { if (characters) printf("%s\n", s); break; } characters += 1; if (isspace(*p)) e = p; if (characters > 60) { *e = '\0'; printf("%s\n", s); s = (p = e) + 1; characters = 0; } } } } acorn-fdisk-3.0.6.orig/lib/util/warning.h0100644000000000000000000000047306506310430016720 0ustar rootroot/* * lib/warning.h * * Copyright (C) 1997,1998 Russell King */ #ifndef WARNING_H #define WARNING_H #include "util/types.h" /* Function: void issue_warning (const char *fmt, ...) * Purpose : Display a warning string * Params : fmt - printf-like format */ void issue_warning (const char *fmt, ...); #endif acorn-fdisk-3.0.6.orig/lib/partdmp0100755000000000000000000024110306503067464015534 0ustar rootrootg0 -W-8  /Z`/\ 4 Unable to open device: %s Drive: %d cylinders %d heads %d sectors Partitioning scheme is: %s Partition | Flgs | Start C /H /S | End C /H /S | Type ----------+------+---------------------+---------------------+----------------- %8s%-2d| %c%c | %08X %4d/%2d/%2d | %08X %4d/%2d/%2d | %03X %s  -LHMh -\OhP cOH //dK \0` dgO/ AaO/\O/LO/PKl l  sP, l  P, D@ @(`hp-,00-800-<00-@00-000-D00-H00-L  -4-E -0 jOt/,ЍOp/ [dev_name != NULLopen.c%s:%u: failed assertion `%s' part_open(dev_name=%s, part_scheme=%s)out of memorypartitioning scheme not recognisedunable to read partition tablesret=%p -LPP" OO0OOg/pcy/pO[q/pOSG/OY JO#T@/pP  /@@T Y P@T/ P*@T& z/`4Q@T  s/P`P@TVT Q@T  ]/P @TT PP @}O[part != NULLgetgeo.c%s:%u: failed assertion `%s' geo != NULLpart_getgeometry()okerrorret %s 0-L@PP0O OOTp0O OOxO@O0OTO0[part != NULLgetscheme.c%s:%u: failed assertion `%s' -PL<O\0O TOP[part != NULLgetpinfo.c%s:%u: failed assertion `%s' pinfo != NULLpart_getpartinfo(parn=%d)invalid partition number %dret ok, pinfo=[bs=0x%X, be=0x%X, type=0x%X]ret error -L@`pPP0O OOV0O OOO' L0S T*P0P , /pHOW $0 IOAO[part != NULLvalidops.c%s:%u: failed assertion `%s' part->nr_partitions && parn < part->nr_partitionspart->schemepart_validops(parn=%d)ret %X -L`pP@P0O OO'L0S V:0O OO0S0O BO@OOP0!R 0 PPP0! 00PPAO[|th\L<,$  @QQRԍSȍTUcdeuxldXH80$܌̌xUnknownEmptyPowerTec BackupFilecore OldMapBIOS TableLinux TableFilecoreBad Block TableDOS SCCDOS R/ODOS AccessCP/MSyrinxBSDi SwapBSDi FSBSD 386AMOEBA BBTAMOEBALinux ExtendedLinux NativeLinux SwapMinixOld MINIXPCiXNovelNet 386NovelNet 286GNU HurdEZ-DriveDisk Manager 6DM6 Aux3MicroPortDM6 Aux1NovelVENIXWin98 ExtendedOS/2AIX BootAIXHPFSDOS-16 >= 32MBDOS ExtendedDOS-16 < 32MBXENIX /usrXENIX rootDOS-12NoneUnknown type %d - 0SL 0S 0SX01P[h@ O/[0 -L0$\0 [ <1S P1SPP#[part_close()ret=NULL -L@4O`BT PP//AXOS[@H -L@$p`P  /P `P@T1[0powertec.c%s:%u: failed assertion `%s' @H p-LP ` 0S  PUUn |OtO0Ou @/0 0/p[ - L*0 R[powertec_detect()part != NULL-powertec disc checksum: %02X-powertec calc checksum: %02X notret%s detected -LMPpOU0O mOkO($P0 OKU`V P[@OOTpO0OWO[powertec_readinfo()okerrorret %s -LMHOvYe?O OO(0 KP!`$PKp1S 0T2 182 ~/E 00C42 @,B (b K0 /K P Pp`VLBOD?OXDOZ[powertec_writeinfo()part->nr_partitions <= POWERTEC_NR_PARTITIONSPowerTec partition information cannot be saved with a debug build -LMPO.U`?O DO@A@O@@L0S0O lO@AhO@@x/K/@L0V*P0\ (0S 0`p G 01$ 0C01?K(@L0T:OKK YOO?OVO[powertec_allocate()partition table is fullret %d p-L`PPC/ jO@AiO@@0O@>C'xO@ L0T *P1S 00S @@T:@LT*P1S @T:RTOY@( 0$0Op[powertec_validate_change(parn=%d)pold != NULLparn < part->nr_partitionsyou cannot edit a filecore partitionyou cannot create a filecore partitionthe modified partition overlaps an existing partitioninret %svalid -Lp`P@DOW9W?O@>CP/ O@AO@@UK?OP/ O@AO@@L0V:R?OQ/O@AO@@ROKODO$0@S T $0@S   P IO?O@>CXMO[powertec_validate_creation(parn=%d)unable to create partition in this slotthe new partition overlaps an existing partition -L`Pp@OV80O>C\/ UOATO@>L0U:?O\/ `OA_O@3OOO WT $0@S  c PO0O>CXO[powertec_validate_deletion(parn=%d)the first Filecore partition cannot be deleted p-LP@`tOxUc?O>Cg/ OAO@L0T:$0O@>Cg/ OAO@TO/`eOAk?O>CVO@pp[powertec_validate_partno(parn=%d)the requested partition is invalid 0-PLP@m/ OAO@?O>COI+U@O /O@A?O>CTO@@:0[previous???nextpowertec_nexttype(parn=%d, current=0x%X, %s)ret 0x%X@ -L`p@PSt O0OE  ! O0 O V?O>Cv/OAO@cL0W:?O@>Cv/ OAO@W 0S  R11S R R 1AAO@ JO [PowerTec - ~Lar tP0 R[icside_detect()part != NULLicside.c%s:%u: failed assertion `%s' -icside disc checksum: %08X-icside calc checksum: %08X notret%s detected -LM@O v T0O5 OO   X0 K `V (P@Or Oo TW O0OYOe [icside_readinfo()LinuxPartokerrorret %s -LCMMXOM / Xx?O` vOtO 0 K Pv0p `EKLL\ $PKTr 0T2 "8" (r 1S282 /E 00C42 @?02 `(r 0,2 /K6N0\ P4 MO\/@P.TB 282 @/42  0" ,B `(r /K P6 82TB 082 /E 0B0C42 0,2 (r O4[NS SS 0002 `/K P0T2 282 , E 0A0C42 0" (r 0,2 `/KPpW O?OYO [icside_writeinfo()part->nr_partitions <= ICSIDE_NR_PARTITIONS0ICS-style partition information cannot be saved with a debug buildret=%d 0-LM@O u TP0O@>C O@AO@@ L0S0O O@AO@@ /KE/L0UC*P0 P; ( R0R*R3 +@?0R. @R #<0R! B 02$ 0C01! B 00C2$ 0C00c1! B 02$ 0C01t?O O@AO@@ L0\:OKX D O  xO$ 0[Creation not supported -PLB/ O@@?O@>CO@Am XO [icside_validate_change(parn=%d)pold != NULLparn < part->nr_partitionsyou cannot edit a filecore partitionyou cannot create a filecore partitionthe modified partition overlaps an existing partitioninret %svalid -Lp`P@CO W?O@>CH/O@AO@@ UJ?OH/ OAO@ L0V:Q?OH/ HOADO@ ROY KOV DOS $0@S T $0@S  5 Pz IO`0O>CXMO [icside_validate_creation(parn=%d)unable to create partition in this slotthe new partition overlaps an existing partition -L`Pp@O[ = Vj?O>CS/ jOAiO@ L0U:?OT/tOAsO@ O O O WT $0@S  P Oy?O>CXO& [icside_validate_deletion(parn=%d) 0-L@P@O T?O>C_/OAO@h L0U:?O0C_/ OAO@\ OAO@ 0[ -PLO@?O>Cd/OAG O@@ [ -L[ICSIDEFSpart != NULLlinux.c%s:%u: failed assertion `%s' part->nr_partitions <= FILECORE_MAX_PARTITIONS + 3part->partinfo[i]->info.kern_part_no == i -PL0O( OO L0S0O) OO R[)P01S ,0S 0O- BOAO  L0R:[fcl_detect()-fcl disc checksum: %02X-fcl calc checksum: %02X notret%s detected -LM`Ol N Vr?O> pOoO  P.0 OK pW%!P[ @OO OL TP0S`K<0S $ [0 S R !0[H0 MOO?OXOO) [fcl_readinfo()okerrorret %s -LM`DO V ?O0Cs OAO@j \ZT 8 OK ,04;0C42 @0r P,R PG D0S E0F 4T 8 042 , 002  P0 08"Ko P)P^|!pGuG@yG$@KT, B%B@)B2SS0T2 1082 10!00C42 2S0002 , /KP @PU yO{?OY{O [fcl_writeinfo()filecore boot sector is corruptfilecore boot sector has been changed by another programstart_cyl == part->partinfo[2]->info.chs_start.cylinderfilecore-linux partition information cannot be saved with a debug buildFilecore boot sector (0xc00):0Linux partition sector (0x%X): p-LMPSOP 2 `OK0 Py0[PaOrH0P^OmL0SP0@T 0 0P a?O O@AO@@ 00KK 400K0K0KOKKHhOXO ' L0S?P00S; / @/L0S, KP0 1 Q (0S 00d1$ 0C01(0S S^CV_O@@p[fcl_allocate()pnew != NULLpartition table is fullret %d p-LP`\OVOAO@x0OW/@L T*P1S @T:TOA@(@0$0tOp[fcl_validate_change(parn=%d)parn < part->nr_partitionsinvalid partition typethe modified partition overlaps an existing partitioninret %svalid -L`@PpOS5L0T :`/ OAO@0OOOU $00CS PTL0Tp3OQ?O>CWO&[fcl_validate_creation(parn=%d)unable to create partition in this slotthe new partition overlaps an existing partition -L`Pp@ODL0U:k/OAO@?OMOOOWT $00CS |PO?O>CXO[fcl_validate_deletion(parn=%d)pold != NULLunable to delete filecore partitionUnable to delete table partition: delete all partitions contained within first -L@P`pO|V0Ov/ EOAEO@L0U:?O0Cv/ QOAQO@( RR GO- R*P1S R:L0RNO2;:pROAd0O>CWO@@][fcl_validate_partno(parn=%d)the requested partition is invalid p-LP@`dOB$T``O&O@AE?O>CVO@@1p[nextpreviousfcl_nexttype(parn=%d, current=0x%X, %s)ret 0x%X -L@`pPd OpOS00 xO UL0V:w?O@>C/ OAO@\VV @_ @_P W WXPHPP#PO[Filecore/Linuxriscix_detect() notret%s detected -<OL4O@O[ -L[ -L[ -L[ -L[ -L[ -L[ -L[Filecore/RISCiX -000?00C0L 00! [ -00  ? 0#10  L00[ -L0 4 8 [ -!40L!80![pcbios_detect()part != NULLpcbios.c%s:%u: failed assertion `%s' notret%s detected0./ p-LP`OD&U0OY OOP0 l@P1US1S`@O0OVO!p[pcbios_readinfo()okerrorret %s -LHMh HO h\{ ZOXO`?OcQh0o}@dKZdQb@`Q]@\0@c4 X`K/pTp @H 0D<0 0  40 h P P& l` p `0VS 0T0 P,P PK+DK(0V00 C@@8@ l @@D4@ hP p`WlOn?OYnO [pcbios_writeinfo()part->nr_partitions <= PCBIOS_NR_PRIMARY + 1info->info.type <= 0xffPC/BIOS partition information cannot be saved with a debug build -LOy[X?O0C OAO@L0S0O OAO@ o_PU01` p 01 P0A/L0TV*(0S SN?O hO@AdO@@0G $0 C`pPVEgOOA?O0CYO@ [pcbios_allocate()pnew != NULLprimary bios partition table is fullret %dparn < 1 + PCBIOS_NR_PRIMARY || parn == PARN_ERROR p-LP`OUt?O@>CA/ tO@AsO@@HV0OA/ ~O@A}O@@>@L T *P01S (0S @TTFO@(@0$0CO00T00S J?OF/ O@AO@@p[pcbios_validate_change(parn=%d)pold != NULLparn < part->nr_partitionsunable to modify the BIOS partition table partitionthe modified partition overlaps an existing partitioninret %svalid -L`@PpOz\V?O@>CL/O@AO@@XC?OL/ O@AO@@L0T :J?OL/ OAO@KO  AO  T U  Pp4BO@0O>CWFOA[pcbios_validate_creation(parn=%d)unable to create partition in this slotthe new partition overlaps an existing partition -L`P@pOVT?O>CV/ TOASO@hL0U :?OV/ _OA^O@]O O XT  PpOl?O>CWO[pcbios_validate_deletion(parn=%d)unable to delete partition -L`@pPdOV?O>C_/ OAO@W?O0C`/OAO@L0T:?O0C`/ OAO@TPOX OA?O>CUO@[pcbios_validate_partno(parn=%d)the requested partition is invalid p-L@P`dOaTOAO@?O>Cg/U U`O W|O@A?O>CVO@@bp[nextpreviouspcbios_nexttype(parn=%d, current=0x%X, %s)ret 0x%X -L`@Ph OtOpS00 |O<V0O>Cp/ OAO@L0T:?O@>Cq/OAO@T@O@ 1S $P1SP$P$#A@FO [PC/BIOSpart != NULLadd.c%s:%u: failed assertion `%s' pinfo != NULLpart_add(parn=%d, pinfo=[bs=0x%X, be=0x%X, type=0x%X])okfailedret %s -L`pPP0O OO2W0O OO+(00-O$0 ЍL0S V:p x/@P !{/PQ L !r/P/LP@P01S4_/ P0P0^ 00P0!00s_Oa?OYaO [checking [0x%X-0x%X] with [0x%X-0x%X] 0-LP 00-@LO0 g 0R0[9 0R0[ -LPp`@ T P0P P`@L0T:[sector != NULLfilecore.c%s:%u: failed assertion `%s' -PL@O`0O XO0  0,ăAQ [ p-L`P@z@sp[part != NULLchs.c%s:%u: failed assertion `%s' pinfo != NULLpart_updatechs([bs=0x%X, be=0x%X, type=0x%X])unable to get geometrystart=[C=%d,H=%d,S=%d] end=[C=%d,H=%d,S=%d]okerrorret %s -LMPp`P0O OO!U0O COBOOm$0 O0S0@KP   0pp00-00-00-IO 0 ~ ЍDOF?OWFO[blkio_close()ret=NULL -L@4O|Tr//@Ou[dev_name != NULLopen.c%s:%u: failed assertion `%s' blkio_open(%s)%s-geometry: [secsz=%d, sec/tk=%d, hds=%d, cyls=%d]ret=%p< 0-LMPP0OQ/OO80/O~/@)O5P@P! /p  K/P 08#800[00[ 0?0 00?000-KO0 ЍFO 0[blkio != NULLgetgeo.c%s:%u: failed assertion `%s' geo != NULLblkio_getgeometry()ret=[sector_size=%d, sectors=%d, heads=%d, cylinders=%d] 0-L@PP0O OO3T0O OO,O0000-O0 0[blkio != NULLsetblocksz.c%s:%u: failed assertion `%s' blkio_setblocksize(%d)ret=%d 0-L@PPpOdO0O XO@PO0[ -L`P0 ?/P /PP[blkio_read(%p 0x%X +0x%X)-blocksize=0x%Xret=%d -Lp`P@XO_ALO[0 @@dOQ[00  --LQ , /4 00H0 P0[0 0 - 0L0[0  -0L[0  - 0L0[4 - L000[4 - L0S0C0[w+/tmp/part.debug%*s%s 4 84 -0-L ,P/4@0SdOdO-/ P P-lO`0 |0O&/0[ -L[ 0-L@P/PP /0[T@-@0S0S0@- r 0S  1S@R TP@T`0@/@ 0S00@-0-@0 //n/0@-0 S :FS:P^ *P:BPE^:PUp0C S 0CP R0@ BBPUc^|a S",0S0S0S0S M0 J00S D0 A00S0S 80 500S /0 ,00S0S0S B 0 B00S B0 B00S0S B 0 B00S B0 B\S B000@-0 S :FS:P^ *P:BPE^:PUp0C S 0CP R0@ BBPUc^|a S",0S0S0S0S M0 J00S D0 A00S0S 80 500S /0 ,00S0S0S B 0 B00S B0 B00S0S B 0 B00S B0 B\S000` -L \0 0l0[ [` -L V\0 0l0[ [` -L@ \@ 0l0[ [` -L [\8 0l0[ [/lib/ld.so/usr/arm-linux/lib/ld.so: can't load dynamic linker '/lib/ld.so nor /usr/arm-linux/lib/ld.so' statically linked  p-0LTM`P@0S4 0^70 OP OP @G OdK/T 0S 0S aF dKe00-00-lKV 0 hlЍ  KOd@Kt/V jVp[D -LM[libc.so.4DLL Jump 4.6pl270XLinuxS:LinuxN:RiscOs:OldMap:Backup:Empty:DOSDisc:ܝԒpp̚ԛȩԞܢԤبpt̬Գ0и,@Th| @QRSTUcdeu$HX4(PXs?d|  # +DpHTaЁgmhq\ ~4 | ́ -59DGp5RH[54muL5H5T5\lL85(58PP P0X&5954585<=HD5DLW[P_Xe`i<5tv555zHPx4Ѕ(T45 9555Ȇ5555Ȇ555  9t5`5d5l 95l5t5x5555W $(,50<504D5<8PP P9$555W8L585@5D(l5X5`5d5p,܊5C KW|[th_\cLg<5,k$o sw |ԍȍxldXH80$܌̌ !&x+389Ď5=F0PULddh 5p5t @W(l9X0А5ܐ55p$D5 5 55 5l5x555Ԓ5+555 /[3H7;5ē5ȓ5ԓEp5Y5]5Ĕalei\m5555z$5$tLh55Ȗ5@5 5Lh5hȘt5t5Ę5̘5p5ș5ԙ5#P(5- 5 2L5T5h7̚5SXL5P]ԛw55,|5ܜ5554dpĝ5̝&ܝ Ԟ5,$555 45t55555055$5((tؠ/ȡ5[eH5,505<ܢ5(P54ipep$T(ģ,5T55-Ԥ 5 >5 VT[|5\̦5`5e5j5o5 5 t5ЧT5050<5<H5H55ب5( Ppȩ x9555555,̪(555t5555|55 8P5552̬5(@D/ Hv555L5Y5D5Xiа[5fܰ55kTo̱s5̱5x5[ز5̲55(Գ5H5(050`<5<jx5505P#5-555555ԶX5@Xd5Xx5545P и555  P# d( l- x2 7 < 53A йй йJ 555Y ,j @| T h |  c кк к к   L1 xD 0c O 5,$T5@5H5L,555^ 5<5$5(5,H4p555o H5Xv 5  x 855 X5l5ki55 d5D 45T 5 5 5f 5 5$58 5o d5,L5LX5Xe55 5Lt#5 (5@t 5$  . 5,505LX?  D 5$I 00 09555555 5 O $XW04 _ $5(5,58c PP Pm x50,$W(8{ @@ @9555$    ` <5(5054Wd5D5L5PdX5X(5p5555h   5L ,5h c < 9d5(50544<  5L 5h   ,5500 09555555558 `` `955555    Hh p555  W 0[ 0 DP Ddh_lc) g7 D  WL 4[Y 4 <_@c 8kD5x5|o <v 55y    W P   @ P[0 _8 < t d    @c  W' / 6 A PK HW g 0l dq Dv d l 8      0   8$ `Tx%.7@IR[,dl`A K W  g l q v          l `  %D. 7@8ItRh[w <)l 7 A JU`kv h        d  &.DYd@oTAH,H$p,7DEP<[frz `  `/usr/lib/crt0.o___crt_dummy____entry___load_shared_librariesL1___setfpucw___libc_init_main_exit.L1____brk_addr___environ___fpu_control___shared_dummy_____SHARED_LIBRARIES_____shared_dummy1____SHARABLE_CONFLICTS__/tmp/cca006491.ogcc2_compiled.___gnu_compiled_cLC2__IO_stderr____mainL0_part_openL2_get_error_fprintf_part_getgeometry_printf_part_getschemeL3_part_getpartinfoL4_part_validops_part_typename_part_closeopen.o_schemes_powertec_scheme_icside_scheme_filecore_linux_scheme_filecore_riscix_scheme_pcbios_schemeLC6L31___eprintfL65_set_errorL34L66_freeL67_blkio_closeL68_dbg_printf_dbg_level_up_malloc_memset_blkio_openL40L47L44_strlenL49L51_strncmpL50L59_dbg_level_downgetgeo.oL33_blkio_getgeometrygetscheme.ogetpinfo.oL35L36L37L38L39validops.otypes.o_part_typesLC0LC1LC3LC4LC5LC7LC8LC9LC10LC11LC12LC13LC14LC15LC16LC17LC18LC19LC20LC21LC22LC23LC24LC25LC26LC27LC28LC29LC30LC31LC32LC33LC34LC35LC36LC37LC38LC39LC40LC41LC42LC43LC44LC45_buf.24LC46LC48_sprintf_types.27LC50_part_nexttypeL42close.oL30powertec.o_powertec_ptypes_powertec_gettype_memcmp_powertec_puttypeL43_memcpy_powertec_checksumL48_powertec_detectL52_blkio_setblocksizeL54_blkio_read_powertec_readinfoL64L79L72L71_part_add_powertec_writeinfoL82L84L86L88L87_dbg_memdump_powertec_allocateL95L97L99L98L103L105_powertec_validate_changeL112L114L116L127L118L128L129L121_check_overlap_powertec_validate_creationL132L134L145L136L146L147L139_powertec_validate_deletionL150L152_powertec_validate_partnoL159_powertec_nexttypeL165L166L170L172L176L174L179L182icside.o_icside_checksum_icside_detect_icside_readinfoL58L57L63L80_icside_writeinfoL83L85L89L100L96L101_icside_allocate_icside_validate_changeL108L110L123L124L125L117_icside_validate_creationL130L141L142L143L135_icside_validate_deletionL148_icside_validate_partnoL153_icside_nexttypelinux.o_fcl_internalcheck_fcl_detectL46_filecore_checksum_fcl_readinfoL78L60L69_fcl_writeinfo___udivsi3L106L93L94L107_fcl_allocate_fcl_validate_changeL133_fcl_validate_creationL138L149_fcl_validate_deletionL154L157L158L167L155L160L162_fcl_validate_partno_fcl_nexttypeL180L183L184L185L181L189L191riscix.o_riscix_detect_riscix_readinfo_riscix_writeinfo_riscix_allocate_riscix_validate_change_riscix_validate_creation_riscix_validate_deletion_riscix_validate_partnopcbios.o_pcbios_copychsin_pcbios_copychsout_pcbios_copylogin_pcbios_copylogout_sector.32_pcbios_detect_pcbios_readinfo_pcbios_writeinfoL70L74L73L77_pcbios_allocate_pcbios_validate_changeL102L104L113L109_pcbios_validate_creationL119_pcbios_validate_deletion_pcbios_validate_partnoL144_types.49_pcbios_nexttypeL156L163add.o_part_updatechsL45overlap.o_test_overlapfilecore.ochs.o_part_calcchs___umodsi3L32_close_errno_strerror_zmalloc_open_ioctlsetblocksz.oread.o_read_block_lseek_readerror.o_errmsg_error_set_vsprintf_is_error_set_clear_errordebug.o_debug_level_buffer.6_debug_file_fopenL6zmalloc.o__main.o___DTOR_LIST_____do_global_dtorsL5__exit_dummy_ref__exit_dummy_decl___CTOR_LIST_____do_global_ctorsL11L14L9L20_atexit_initialized.6_eprintf.o_fflush_abort_udivsi3.oLdiv_zeroLgot_resultLnot_really_bigL11L31L21Lnot_too_bigLdo_single_divLend_regular_divideLend_single_divloopLsingle_divloopL12LdivloopL.1.1015L.2.1016L.3.1018L.4.1022L91L.4.1020L.3.1016L.4.1018L.4.1016L.2.1014L.3.1014L.4.1014L.4.1012L.3.1012L.4.1010L.4.1008___div0_umodsi3.o_exit.o_dvmd_tls.o__load.o__BUILTIN_FIXUPS____setfpucw.o__T00001.o___libc_4_627__T00123.o__T00060.o___brk__D00126.o__fpu_control.o__D00120.o__IO_stdin___IO_stdout___IO_list_allfprintf.oprintf.o__U00011.o__T00276.o__T00286.o__T00458.o__T00461.osprintf.o__T00283.o__T00284.o__D00127.o__T00456.oioctl.olseek.ovsprintf.ofopen.o__T00052.o___new_exitfn___exit_funcsfflush.o__T00043.o__libc.oLCSHR01LCSHR02__NEEDS_SHRLIB_libc_4__libc_CONFLICT_LIST__GOT_SIZE__PLT_SIZE__LAST_DATA_ADDRESS__T00146.o__IO_fprintf__T00321.o__IO_printf__T00439.o__IO_sprintf__T00075.o___close__T00310.o___open__T00244.o___ioctl__T00274.o___lseek__T00348.o___read__T00529.o__IO_vsprintf__T00143.o__IO_fopen__T00133.o__IO_fflush__etext_etext__end__edata__bss_start_edata_endacorn-fdisk-3.0.6.orig/lib/partdmp.c0100644000000000000000000000247506503066134015752 0ustar rootroot#include #include "part/part.h" #include "util/error.h" int main(int argc, char *argv[]) { partinfo_t info; geometry_t geo; part_t *part; int i; part = part_open(argv[1], ""); if (!part) { fprintf(stderr, "Unable to open device: %s\n", get_error()); exit(1); } part_getgeometry(part, &geo); printf("Drive: %d cylinders %d heads %d sectors\n\n", geo.cylinders, geo.heads, geo.sectors); printf("Partitioning scheme is: %s\n\n", part_getscheme(part)); i = 0; printf ("Partition | Flgs | Start C /H /S | End C /H /S | Type\n"); printf ("----------+------+---------------------+---------------------+-----------------\n"); while (part_getpartinfo(part, i, &info)) { int ops; ops = part_validops(part, i, &info); printf ("%8s%-2d| %c%c | %08X %4d/%2d/%2d | %08X %4d/%2d/%2d | %03X %s\n", argv[1], info.kern_part_no, ops & VALIDOPS_DELETE ? 'D' : ' ', ops & VALIDOPS_UPDATE ? 'E' : ' ', info.blk_start, info.chs_start.cylinder, info.chs_start.head, info.chs_start.sector, info.blk_end, info.chs_end.cylinder, info.chs_end.head, info.chs_end.sector, info.type, part_typename(part, info.type)); i++; } printf ("----------+------+---------------------+---------------------+-----------------\n"); part_close(part); return 0; } acorn-fdisk-3.0.6.orig/README0100644000000000000000000000367506505010077014251 0ustar rootrootARM FDISK Version 3.0 --------------------- (c) 1998 Russell King. (rmk@arm.uk.linux.org) Disclaimer (read): ------------------ THIS SOFTWARE IS PROVIDED `AS IS'. THE AUTHOR MAKES NO WARRANTY, EXPRESS OR IMPLIED OF ANY KIND, INCLUDING BUT NOT LIMITED TO THE MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR OF THIS SOFTWARE BE LIABLE FOR DAMAGES INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. Features -------- * Support for the following partition types: * Linux partitions on top of Filecore * ICS IDEFS * PowerTec * PC/BIOS partitions (not extended partitions) * Autodetects partitioning scheme General (read) -------------- This is a version of fdisk, a partition management utility for Linux. It has a simple but quite user-unfriendly frontend. Operation is however simple, with feedback on actions. Debug information is written to /tmp/part.debug. If you find a problem, then please include in your problem report a copy of this file. Please gzip & uuencode this before sending it. If it is compressed using any other formats, then your email will be ignored. Don't forget - if you mess up your disks using this program, then it is helpful to have the debug file, however it will not help anyone to recover your disk. Improvements ------------ Improvements in the frontend are welcome - please feed them to myself. This program uses set of libraries to handle the partitions. Please do not modify these without emailing myself (address above) - the code contained within them must remain platform independent, as is the interface between FDISK and the libraries. acorn-fdisk-3.0.6.orig/ChangeLog0100644000000000000000000000110006722735743015137 0ustar rootroot3.0.6 ----- * Fixed problem with writing out PCBIOS tables when we haven't read a valid table. 3.0.5 ----- 3.0.4 ----- 3.0.3 ----- * RiscOS code sync'd: - linux scheme now contains writing code, but is currently disabled. - eesox scheme added. - powertec detection moved later. - ICS IDE scheme writing code, and proper support for unrecognised types. * fdisk now has an extra 'r' command - reopen device as a specific scheme. Useful if you don't have access to command line for some reason (installers). 3.0.2 ----- * >2GB drives now properly supported.