diff options
author | Martin Reindl <martin@cvs.openbsd.org> | 2006-04-27 19:52:22 +0000 |
---|---|---|
committer | Martin Reindl <martin@cvs.openbsd.org> | 2006-04-27 19:52:22 +0000 |
commit | ed27cd970afc6b5a1f13bcbcfa6e6f2c17383ea3 (patch) | |
tree | 1705907342ecd5f075b44fae6b75b82b0a5d413d /sbin/pdisk | |
parent | e317d0527a2e9963eb4d77f7416c9714f02efcfd (diff) |
update for pdisk 0.8a2, from NetBSD, retaining our local changes;
summing it up:
- Clean up sources - fix naming, delete old email addresses
- Added support for display of Mac volume names
- Fix block 0 display to show logical offset of drivers
- Require confirmation of quit without write
- Fix iteration to not complain about missing devices
- Warn when creating/writing a map with more than 15 entries
and, most important, add do_update_dpme() which allows us to partition
OpenBSD slices without previous MacOS setup.
Tested with shared MacOS install on macppc, procedure there remains the
same.
grammer and spelling help and ok jmc@
ok miod@
Diffstat (limited to 'sbin/pdisk')
34 files changed, 1046 insertions, 356 deletions
diff --git a/sbin/pdisk/HISTORY b/sbin/pdisk/HISTORY index 6ad9ac091ab..4447f842bdf 100644 --- a/sbin/pdisk/HISTORY +++ b/sbin/pdisk/HISTORY @@ -52,3 +52,17 @@ A short history of pdisk name when displaying under another name and allow the MkLinux name to be used on input. Released version 0.7 + +02-04/2000 - Clean up sources - fix naming, delete old email addresses + Added support for display of Mac volume names + Added cvt_pt target (for LinuxPPC team) + Fix block 0 display to show logical offset of drivers + Require confirmation of quit without write + Fix iteration to not complain about missing devices + Warn when creating/writing a map with more than 15 entries + Make initial window larger in Mac version + Fix ATA support to scan buses correctly + Fix linux names (in MacOS) to work correctly with many devices + Change so WORM devices are considered 'CDs' + +05/2000 - Released version 0.8 diff --git a/sbin/pdisk/Makefile b/sbin/pdisk/Makefile index f2fa50e81f2..60d38024785 100644 --- a/sbin/pdisk/Makefile +++ b/sbin/pdisk/Makefile @@ -1,10 +1,12 @@ -# $Id: Makefile,v 1.6 2003/04/26 02:46:14 deraadt Exp $ +# $Id: Makefile,v 1.7 2006/04/27 19:52:21 martin Exp $ .if ${MACHINE} == "macppc" || ${MACHINE} == "mac68k" PROG= pdisk +CFLAGS+=-Wall -D__unix__ + SRCS= bitfield.c convert.c deblock_media.c dump.c errors.c \ - file_media.c io.c media.c partition_map.c pathname.c \ + file_media.c hfs_misc.c io.c media.c partition_map.c pathname.c \ pdisk.c util.c validate.c .else diff --git a/sbin/pdisk/README b/sbin/pdisk/README index 10bd4e36a3b..64a7f6526f1 100644 --- a/sbin/pdisk/README +++ b/sbin/pdisk/README @@ -1,31 +1,39 @@ Product name: pdisk -Version: 0.7 -Ship date: 18 February 1998 -Company name: Apple Computer -Author name: Eryk Vershen <eryk@apple.com> +Version: 0.8 +Ship date: 16 May 2000 +Company name: n/a +Author name: Eryk Vershen -Description: A low-level Apple partition table editor for (Mk)Linux. +Description: A low-level Apple partition table editor for Linux. A MacOS version exists for "standalone" use. -What's New: Added support for ATA/IDE disks without LBA capability +What's New: Clean up sources - fix naming, delete old email addresses + Added support for display of Mac volume names + Added cvt_pt target (for LinuxPPC team) + Fix block 0 display to show logical offset of drivers + Require confirmation of quit without write + Fix iteration to not complain about missing devices + Warn when creating/writing a map with more than 15 entries + Make initial window larger in Mac version + Fix ATA support to scan buses correctly + Fix linux names (in MacOS) to work right with many devices + Change so WORM devices are considered 'CDs' + +Last time: Added support for ATA/IDE disks without LBA capability Fixed bug - create partition with unmodified size failed Added support for new (DR3) MkLinux names - show MkLinux name when displaying under another name and allow the MkLinux name to be used on input. -Last time: MacOS version handles IDE/ATA and ATAPI devices. - Added interactive mode - Added ability to rename a partition - Added 68k target to MacOS CodeWarrior project - -Requirements: MkLinux - just run the binary - Linux - recompile for your hardware +Requirements: Linux PPC - just run the binary MacOS - Distributed binaries for PowerPC or 68000 I haven't tried it except on 7.6.1 and 8.0 Price: Free Legalese: + Modifications copyright 2000 by Eryk Vershen + Copyright 1996,1997,1998 by Apple Computer, Inc. All Rights Reserved @@ -46,10 +54,7 @@ Legalese: WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -Contact Info: Go to <http://www.mklinux.org> to find out about MkLinux. - Go to the Faq-O-Matic (there should be a pointer or three - in the MkLinux pages) and search for 'pdisk'. - You can send mail to the author. There is no guarantee of +Contact Info: You can send mail to the author. There is no guarantee of a response, but it is your best hope of getting a bug fixed or a feature added. @@ -63,9 +68,8 @@ READ the html file or the man page. Finding out about apple partitioning ------------------------------------ The best curently available documentation on the Apple disk partitioning scheme -is "Inside Macintosh: Devices" pages 3-12 to 3-15 combined with the info -in "Inside Macintosh - Volume V" pages V-576 to V-582. This, unfortunately, -does not cover everything. +is "Technote 1189: The Monster Disk Drive Technote". This release is not +completely in sync with that technote. Maybe next time. Building the macintosh application @@ -100,6 +104,7 @@ but is simply an HFS volume. Bootable CD-ROMs have even stranger partition maps since two are laid down: one at 2K offsets and one at 512-byte offsets. If you notice that these overlap then you begin to get an idea of how weird these maps can be. +Apple refers to this "technique" as ghost partitioning. The documentation in Inside Macintosh is only partially correct. The boot-arguments field was left out. A/UX used the boot arguments field @@ -139,6 +144,4 @@ Good luck, -eryk vershen software mechanic - - work: eryk@apple.com - non-work: eryk@cfcl.com + eryk@cfcl.com diff --git a/sbin/pdisk/bitfield.c b/sbin/pdisk/bitfield.c index fbb23716505..252c1052f8a 100644 --- a/sbin/pdisk/bitfield.c +++ b/sbin/pdisk/bitfield.c @@ -1,7 +1,7 @@ // // bitfield.c - extract and set bit fields // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // // See comments in bitfield.h // diff --git a/sbin/pdisk/bitfield.h b/sbin/pdisk/bitfield.h index 57e7f5c810e..d5fa5bcf232 100644 --- a/sbin/pdisk/bitfield.h +++ b/sbin/pdisk/bitfield.h @@ -1,7 +1,7 @@ // // bitfield.h - extract and set bit fields // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // // Bitfields are not particularly transportable between big and little // endian machines. Big endian machines lay out bitfields starting diff --git a/sbin/pdisk/convert.c b/sbin/pdisk/convert.c index 023cefbffcb..f18bc731f9d 100644 --- a/sbin/pdisk/convert.c +++ b/sbin/pdisk/convert.c @@ -1,7 +1,7 @@ // // convert.c - Little-endian conversion // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // // See comments in convert.h // @@ -33,6 +33,7 @@ #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 #define BYTE_ORDER 4321 +//#define BYTE_ORDER 1234 #endif #include "convert.h" diff --git a/sbin/pdisk/convert.h b/sbin/pdisk/convert.h index 69da1878c48..275ead94e81 100644 --- a/sbin/pdisk/convert.h +++ b/sbin/pdisk/convert.h @@ -1,7 +1,7 @@ // // convert.h - Little-endian conversion // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // // The approach taken to conversion is fairly simply. // Keep the in-memory copy in the machine's normal form and diff --git a/sbin/pdisk/deblock_media.c b/sbin/pdisk/deblock_media.c index 75531cd25d9..726d7beae4e 100644 --- a/sbin/pdisk/deblock_media.c +++ b/sbin/pdisk/deblock_media.c @@ -1,7 +1,7 @@ /* * deblock_media.c - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* diff --git a/sbin/pdisk/deblock_media.h b/sbin/pdisk/deblock_media.h index ffd27b44aac..9ea171fad94 100644 --- a/sbin/pdisk/deblock_media.h +++ b/sbin/pdisk/deblock_media.h @@ -1,7 +1,7 @@ /* * deblock_media.h - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* diff --git a/sbin/pdisk/dpme.h b/sbin/pdisk/dpme.h index b50fa87ea7c..175c0cc596a 100644 --- a/sbin/pdisk/dpme.h +++ b/sbin/pdisk/dpme.h @@ -1,7 +1,7 @@ // // dpme.h - Disk Partition Map Entry (dpme) // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // // This file describes structures and values related to the standard // Apple SCSI disk partitioning scheme. @@ -45,10 +45,10 @@ // // Defines // -#define BLOCK0_SIGNATURE 0x4552 /* Signature value. */ +#define BLOCK0_SIGNATURE 0x4552 /* i.e. 'ER' */ #define DPISTRLEN 32 -#define DPME_SIGNATURE 0x504D +#define DPME_SIGNATURE 0x504D /* i.e. 'PM' */ // A/UX only stuff (tradition!) #define dpme_bzb dpme_boot_args diff --git a/sbin/pdisk/dump.c b/sbin/pdisk/dump.c index bd1bee0872b..d5b25cd22a4 100644 --- a/sbin/pdisk/dump.c +++ b/sbin/pdisk/dump.c @@ -1,7 +1,7 @@ // // dump.c - dumping partition maps // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -63,17 +63,44 @@ // Types // typedef struct names { - char *abbr; - char *full; + const char *abbr; + const char *full; } NAMES; +#ifdef __unix__ +typedef unsigned long OSType; +#endif + +typedef struct PatchDescriptor { + OSType patchSig; + unsigned short majorVers; + unsigned short minorVers; + unsigned long flags; + unsigned long patchOffset; + unsigned long patchSize; + unsigned long patchCRC; + unsigned long patchDescriptorLen; + unsigned char patchName[33]; + unsigned char patchVendor[1]; +} PatchDescriptor; +typedef PatchDescriptor * PatchDescriptorPtr; + +typedef struct PatchList { + unsigned short numPatchBlocks; // number of disk blocks to hold the patch list + unsigned short numPatches; // number of patches in list + PatchDescriptor thePatch[1]; +} PatchList; +typedef PatchList *PatchListPtr; + // // Global Constants // NAMES plist[] = { {"Drvr", "Apple_Driver"}, + {"Drv4", "Apple_Driver43"}, {"Free", "Apple_Free"}, + {"Patc", "Apple_Patches"}, {" HFS", "Apple_HFS"}, {" MFS", "Apple_MFS"}, {"PDOS", "Apple_PRODOS"}, @@ -92,6 +119,7 @@ const char * kStringNot = " not"; // int aflag = AFLAG_DEFAULT; /* abbreviate partition types */ int pflag = PFLAG_DEFAULT; /* show physical limits of partition */ +int fflag = FFLAG_DEFAULT; /* show HFS volume names */ // @@ -137,6 +165,7 @@ dump_block_zero(partition_map_header *map) int i; double value; int prefix; + long t; p = map->misc; if (p->sbSig != BLOCK0_SIGNATURE) { @@ -154,9 +183,16 @@ dump_block_zero(partition_map_header *map) printf("Drivers-\n"); m = (DDMap *) p->sbMap; for (i = 0; i < p->sbDrvrCount; i++) { - printf("%u: @ %lu for %u, type=0x%x\n", i+1, - get_align_long(&m[i].ddBlock), - m[i].ddSize, m[i].ddType); + printf("%u: %3u @ %lu, ", i+1, + m[i].ddSize, get_align_long(&m[i].ddBlock)); + if (map->logical_block != p->sbBlkSize) { + t = (m[i].ddSize * p->sbBlkSize) / map->logical_block; + printf("(%lu@", t); + t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize) + / map->logical_block; + printf("%lu) ", t); + } + printf("type=0x%x\n", m[i].ddType); } } printf("\n"); @@ -176,7 +212,7 @@ dump_partition_map(partition_map_header *map, int disk_order) bad_input("No partition map exists"); return; } - alternate = get_mklinux_name(map->name); + alternate = get_linux_name(map->name); if (alternate) { printf("\nPartition map (with %d byte blocks) on '%s' (%s)\n", map->logical_block, map->name, alternate); @@ -230,10 +266,15 @@ dump_partition_entry(partition_map *entry, int type_length, int name_length, int partition_map_header *map; int j; DPME *p; - char *s; + const char *s; u32 size; double bytes; int driver; + // int kind; + char *buf; +#if 1 + BZB *bp; +#endif map = entry->the_map; p = entry->data; @@ -246,14 +287,31 @@ dump_partition_entry(partition_map *entry, int type_length, int name_length, int break; } } - printf("%2ld: %.4s%c%-*.32s ", - entry->disk_address, s, driver, name_length, p->dpme_name); + printf("%2ld: %.4s", entry->disk_address, s); } else { - printf("%2ld: %*.32s%c%-*.32s ", - entry->disk_address, type_length, p->dpme_type, - driver, name_length, p->dpme_name); + printf("%2ld: %*.32s", entry->disk_address, type_length, p->dpme_type); } + buf = (char *) malloc(name_length+1); + if (entry->HFS_name == NULL || fflag == 0) { + strncpy(buf, p->dpme_name, name_length); + buf[name_length] = 0; + } else { + snprintf(buf, name_length + 1, "\"%s\"", entry->HFS_name); + } + printf("%c%-*.32s ", driver, name_length, buf); + free(buf); + /* + switch (entry->HFS_kind) { + case kHFS_std: kind = 'h'; break; + case kHFS_embed: kind = 'e'; break; + case kHFS_plus: kind = '+'; break; + default: + case kHFS_not: kind = ' '; break; + } + printf("%c ", kind); + */ + if (pflag) { printf("%*lu ", digits, p->dpme_pblocks); size = p->dpme_pblocks; @@ -279,7 +337,7 @@ dump_partition_entry(partition_map *entry, int type_length, int name_length, int printf(" (%#5.1f%c)", bytes, j); } -#if 0 +#if 1 // Old A/UX fields that no one pays attention to anymore. bp = (BZB *) (p->dpme_bzb); j = -1; @@ -310,7 +368,7 @@ dump_partition_entry(partition_map *entry, int type_length, int name_length, int break; } if (bzb_slice_get(bp) != 0) { - printf(" s%1d %4s", bzb_slice_get(bp)-1, s); + printf(" s%1ld %4s", bzb_slice_get(bp)-1, s); } else if (j >= 0) { printf(" S%1d %4s", j, s); } else { @@ -352,7 +410,9 @@ list_all_disks() while ((name = step_media_iterator(iter)) != 0) { if ((m = open_pathname_as_media(name, O_RDONLY)) == 0) { +#if defined(__linux__) || defined(__unix__) error(errno, "can't open file '%s'", name); +#endif } else { close_media(m); @@ -378,7 +438,7 @@ show_data_structures(partition_map_header *map) partition_map * entry; DPME *p; BZB *bp; - char *s; + const char *s; if (map == NULL) { printf("No partition map exists\n"); @@ -388,8 +448,9 @@ show_data_structures(partition_map_header *map) printf("map %d blocks out of %d, media %lu blocks (%d byte blocks)\n", map->blocks_in_map, map->maximum_in_map, map->media_size, map->logical_block); - printf("Map is%s writable", (map->writeable)?kStringEmpty:kStringNot); - printf(", but%s changed\n", (map->changed)?kStringEmpty:kStringNot); + printf("Map is%s writable", (map->writable)?kStringEmpty:kStringNot); + printf(", but%s changed", (map->changed)?kStringEmpty:kStringNot); + printf(" and has%s been written\n", (map->written)?kStringEmpty:kStringNot); printf("\n"); if (map->misc == NULL) { @@ -519,14 +580,14 @@ xx: cccc RU *dd s... void -full_dump_partition_entry(partition_map_header *map, int index) +full_dump_partition_entry(partition_map_header *map, int ix) { partition_map * cur; DPME *p; int i; u32 t; - cur = find_entry_by_disk_address(index, map); + cur = find_entry_by_disk_address(ix, map); if (cur == NULL) { printf("No such partition\n"); return; @@ -657,12 +718,18 @@ full_dump_block_zero(partition_map_header *map) dump_block((unsigned char *)&m[i].ddBlock, (&zp->sbMap[247]-((unsigned short *)&m[i].ddBlock))*2); } + void display_patches(partition_map *entry) { long long offset; MEDIA m; static unsigned char *patch_block; + PatchListPtr p; + PatchDescriptorPtr q; + unsigned char *next; + unsigned char *s; + int i; offset = entry->data->dpme_pblock_start; m = entry->the_map->m; @@ -678,7 +745,45 @@ display_patches(partition_map *entry) error(errno, "Can't read patch block"); return; } - dump_block(patch_block, PBLOCK_SIZE); + p = (PatchListPtr) patch_block; + if (p->numPatchBlocks != 1) { + i = p->numPatchBlocks; + free(patch_block); + patch_block = (unsigned char *) malloc(PBLOCK_SIZE*i); + if (patch_block == NULL) { + error(errno, "can't allocate memory for patch blocks buffer"); + return; + } + s = patch_block + PBLOCK_SIZE*i; + while (i > 0) { + s -= PBLOCK_SIZE; + i -= 1; + if (read_media(m, offset+i, PBLOCK_SIZE, (char *)s) == 0) { + error(errno, "Can't read patch block %d", i); + return; + } + } + p = (PatchListPtr) patch_block; + } + printf("Patch list (%d entries)\n", p->numPatches); + q = p->thePatch; + for (i = 0; i < p->numPatches; i++) { + printf("%2d signature: '%.4s'\n", i+1, (char *)&q->patchSig); + printf(" version: %d.%d\n", q->majorVers, q->minorVers); + printf(" flags: 0x%lx\n", q->flags); + printf(" offset: %ld\n", q->patchOffset); + printf(" size: %ld\n", q->patchSize); + printf(" CRC: 0x%lx\n", q->patchCRC); + printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]); + printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]); + next = ((unsigned char *)q) + q->patchDescriptorLen; + s = &q->patchVendor[q->patchVendor[0]+1]; + if (next > s) { + printf("remainder of entry -"); + dump_block(s, next-s); + } + q = (PatchDescriptorPtr)next; + } } int @@ -736,6 +841,17 @@ get_max_name_string_length(partition_map_header *map) if (length > max) { max = length; } + + if (fflag) { + if (entry->HFS_name == NULL) { + length = 0; + } else { + length = strlen(entry->HFS_name) + 2; + } + if (length > max) { + max = length; + } + } } return max; diff --git a/sbin/pdisk/dump.h b/sbin/pdisk/dump.h index 3f84bcc0313..210ac32510a 100644 --- a/sbin/pdisk/dump.h +++ b/sbin/pdisk/dump.h @@ -1,7 +1,7 @@ // // dump.h - dumping partition maps // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -36,6 +36,7 @@ // #define AFLAG_DEFAULT 0 #define PFLAG_DEFAULT 1 +#define FFLAG_DEFAULT 0 // @@ -53,6 +54,7 @@ // extern int aflag; extern int pflag; +extern int fflag; // @@ -62,9 +64,9 @@ void display_patches(partition_map *entry); int dump(char *name); void dump_block(unsigned char *addr, int len); void dump_partition_map(partition_map_header *map, int disk_order); -void full_dump_partition_entry(partition_map_header *map, int index); +void full_dump_partition_entry(partition_map_header *, int); void full_dump_block_zero(partition_map_header *map); -void list_all_disks(); +void list_all_disks(void); void show_data_structures(partition_map_header *map); #endif /* __dump__ */ diff --git a/sbin/pdisk/errors.c b/sbin/pdisk/errors.c index 9c19bee955a..257e95fd179 100644 --- a/sbin/pdisk/errors.c +++ b/sbin/pdisk/errors.c @@ -1,7 +1,7 @@ // // errors.c - error & help routines // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -27,6 +27,7 @@ // for *printf() #include <stdio.h> +#include <errno.h> // for exit() #ifndef __linux__ @@ -78,7 +79,7 @@ extern const char * const sys_errlist[]; void init_program_name(char **argv) { -#if defined(__linux__) || defined(__OpenBSD__) +#if defined(__linux__) || defined(__unix__) if ((program_name = strrchr(argv[0], '/')) != (char *)NULL) { program_name++; } else { @@ -93,25 +94,24 @@ init_program_name(char **argv) void do_help() { -#ifndef __OpenBSD__ - printf("\t%s [-h|--help]\n", program_name); - printf("\t%s [-v|--version]\n", program_name); - printf("\t%s [-l|--list [name ...]]\n", program_name); - printf("\t%s [-r|--readonly] name ...\n", program_name); - printf("\t%s [-i|--interactive]\n", program_name); -#else printf("\t%s [-h]\n", program_name); printf("\t%s [-v]\n", program_name); - printf("\t%s [-l [name ...]]\n", program_name); + printf("\t%s [-l] name [...]\n", program_name); printf("\t%s [-r] name ...\n", program_name); printf("\t%s [-i]\n", program_name); -#endif - printf("\t%s name ...\n", program_name); + printf("\t%s name [...]\n", program_name); +/* + {"debug", no_argument, 0, 'd'}, + {"abbr", no_argument, 0, 'a'}, + {"fs", no_argument, 0, 'f'}, + {"logical", no_argument, 0, kLogicalOption}, + {"compute_size", no_argument, 0, 'c'}, +*/ } void -usage(char *kind) +usage(const char *kind) { error(-1, "bad usage - %s\n", kind); hflag = 1; @@ -124,7 +124,7 @@ usage(char *kind) // the perror(3) message. // void -fatal(int value, char *fmt, ...) +fatal(int value, const char *fmt, ...) { va_list ap; @@ -133,7 +133,7 @@ fatal(int value, char *fmt, ...) vfprintf(stderr, fmt, ap); va_end(ap); -#if defined(__linux__) || defined(NeXT) || defined(__OpenBSD__) +#if defined(__linux__) || defined(NeXT) || defined(__unix__) if (value > 0 && value < sys_nerr) { fprintf(stderr, " (%s)\n", sys_errlist[value]); } else { @@ -141,9 +141,6 @@ fatal(int value, char *fmt, ...) } #else fprintf(stderr, "\n"); -#endif - -#if !defined(__linux__) && !defined(__OpenBSD__) printf("Processing stopped: Choose 'Quit' from the file menu to quit.\n\n"); #endif exit(value); @@ -156,7 +153,7 @@ fatal(int value, char *fmt, ...) // the perror(3) message. // void -error(int value, char *fmt, ...) +error(int value, const char *fmt, ...) { va_list ap; @@ -165,7 +162,7 @@ error(int value, char *fmt, ...) vfprintf(stderr, fmt, ap); va_end(ap); -#if defined(__linux__) || defined(NeXT) || defined(__OpenBSD__) +#if defined(__linux__) || defined(NeXT) || defined(__unix__) if (value > 0 && value < sys_nerr) { fprintf(stderr, " (%s)\n", sys_errlist[value]); } else { diff --git a/sbin/pdisk/errors.h b/sbin/pdisk/errors.h index c90319bef94..aee5dccdb9c 100644 --- a/sbin/pdisk/errors.h +++ b/sbin/pdisk/errors.h @@ -1,7 +1,7 @@ // // errors.h - error & help routines // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -53,10 +53,10 @@ extern int hflag; // // Forward declarations // -void do_help(); +void do_help(void); void init_program_name(char **argv); -void error(int value, char *fmt, ...); -void fatal(int value, char *fmt, ...); -void usage(char *kind); +void error(int value, const char *fmt, ...); +void fatal(int value, const char *fmt, ...); +void usage(const char *kind); #endif /* __errors__ */ diff --git a/sbin/pdisk/file_media.c b/sbin/pdisk/file_media.c index 126e680af7d..f516fe60ff5 100644 --- a/sbin/pdisk/file_media.c +++ b/sbin/pdisk/file_media.c @@ -1,7 +1,7 @@ /* * file_media.c - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* @@ -43,11 +43,12 @@ #include <linux/fs.h> #include <linux/hdreg.h> #include <sys/stat.h> -#endif - -#ifdef __OpenBSD__ +#else +#ifdef __unix__ +#include <sys/ioctl.h> #include <sys/stat.h> #endif +#endif #include "file_media.h" #include "errors.h" @@ -58,7 +59,11 @@ */ #ifdef __linux__ #define LOFF_MAX 9223372036854775807LL -extern __loff_t llseek(int __fd, __loff_t __offset, int __whence); +extern __loff_t llseek (int __fd, __loff_t __offset, int __whence); +#elif defined(__OpenBSD__) || defined(__APPLE__) +#define loff_t off_t +#define llseek lseek +#define LOFF_MAX LLONG_MAX #else #define loff_t long #define llseek lseek @@ -199,7 +204,7 @@ open_file_as_media(char *file, int oflag) FILE_MEDIA a; int fd; loff_t off; -#if defined(__linux__) || defined(__OpenBSD__) +#if defined(__linux__) || defined(__unix__) struct stat info; #endif @@ -228,7 +233,7 @@ open_file_as_media(char *file, int oflag) a->m.do_os_reload = os_reload_file_media; a->fd = fd; a->regular_file = 0; -#if defined(__linux__) || defined(__OpenBSD__) +#if defined(__linux__) || defined(__unix__) if (fstat(fd, &info) < 0) { error(errno, "can't stat file '%s'", file); } else { @@ -255,22 +260,22 @@ read_file_media(MEDIA m, long long offset, unsigned long count, void *address) rtn_value = 0; if (a == 0) { /* no media */ - //printf("no media\n"); + fprintf(stderr,"no media\n"); } else if (a->m.kind != file_info.kind) { /* wrong kind - XXX need to error here - this is an internal problem */ - //printf("wrong kind\n"); + fprintf(stderr,"wrong kind\n"); } else if (count <= 0 || count % a->m.grain != 0) { /* can't handle size */ - //printf("bad size\n"); + fprintf(stderr,"bad size\n"); } else if (offset < 0 || offset % a->m.grain != 0) { /* can't handle offset */ - //printf("bad offset\n"); + fprintf(stderr,"bad offset\n"); } else if (offset + count > a->m.size_in_bytes && a->m.size_in_bytes != (long long) 0) { /* check for offset (and offset+count) too large */ - //printf("offset+count too large\n"); + fprintf(stderr,"offset+count too large\n"); } else if (offset + count > (long long) LOFF_MAX) { /* check for offset (and offset+count) too large */ - //printf("offset+count too large 2\n"); + fprintf(stderr,"offset+count too large 2\n"); } else { /* do the read */ off = offset; @@ -278,10 +283,10 @@ read_file_media(MEDIA m, long long offset, unsigned long count, void *address) if ((t = read(a->fd, address, count)) == count) { rtn_value = 1; } else { - //printf("read failed\n"); + fprintf(stderr,"read failed\n"); } } else { - //printf("lseek failed\n"); + fprintf(stderr,"lseek failed\n"); } } return rtn_value; @@ -347,7 +352,7 @@ os_reload_file_media(MEDIA m) { FILE_MEDIA a; long rtn_value; -#ifdef __linux__ +#if defined(__linux__) int i; int saved_errno; #endif @@ -394,7 +399,9 @@ os_reload_file_media(MEDIA m) } +#if !defined(__linux__) && !defined(__unix__) #pragma mark - +#endif FILE_MEDIA_ITERATOR @@ -450,7 +457,9 @@ step_file_iterator(MEDIA_ITERATOR m) FILE_MEDIA_ITERATOR a; char *result; struct stat info; - size_t len = 20; + int fd; + int bump; + int value; a = (FILE_MEDIA_ITERATOR) m; if (a == 0) { @@ -479,7 +488,7 @@ step_file_iterator(MEDIA_ITERATOR m) } #endif /* generate result */ - result = (char *) malloc(len); + result = (char *) malloc(20); if (result != NULL) { /* * for DR3 we should actually iterate through: @@ -489,35 +498,60 @@ step_file_iterator(MEDIA_ITERATOR m) * /dev/scd[0...] # first missing is end of list * * and stop in each group when either a stat of - * the name fails or if an open fails (except opens - * will fail if you run not as root) + * the name fails or if an open fails for + * particular reasons. */ + bump = 0; + value = (int) a->index; switch (a->style) { case kSCSI_Disks: -#ifdef __OpenBSD__ - snprintf(result, len, "/dev/sd%dc", (int)a->index); -#else - snprintf(result, len, "/dev/sd%c", 'a'+(int)a->index); -#endif + if (value < 26) { + snprintf(result, 20, "/dev/sd%c", 'a'+value); + } else if (value < 676) { + snprintf(result, 20, "/dev/sd%c%c", + 'a' + value / 26, + 'a' + value % 26); + } else { + bump = -1; + } break; case kATA_Devices: -#ifdef __OpenBSD__ - snprintf(result, len, "/dev/wd%dc", (int)a->index); -#else - snprintf(result, len, "/dev/hd%c", 'a'+(int)a->index); -#endif + if (value < 26) { + snprintf(result, 20, "/dev/hd%c", 'a'+value); + } else { + bump = -1; + } break; case kSCSI_CDs: -#ifdef __OpenBSD__ - snprintf(result, len, "/dev/cd%dc", (int)a->index); -#else - snprintf(result, len, "/dev/scd%c", '0'+(int)a->index); -#endif + if (value < 10) { + snprintf(result, 20, "/dev/scd%c", '0'+value); + } else { + bump = -1; + } break; } - if (stat(result, &info) < 0) { - a->style += 1; /* next style */ - a->index = 0; /* first index again */ + if (bump != 0) { + // already set don't even check + } else if (stat(result, &info) < 0) { + bump = 1; + } else if ((fd = open(result, O_RDONLY)) >= 0) { + close(fd); +#if defined(__linux__) || defined(__unix__) + } else if (errno == ENXIO || errno == ENODEV) { + if (a->style == kATA_Devices) { + bump = -1; + } else { + bump = 1; + } +#endif + } + if (bump) { + if (bump > 0) { + a->style += 1; /* next style */ + a->index = 0; /* first index again */ + } else { + a->index += 1; /* next index */ + } free(result); continue; } diff --git a/sbin/pdisk/file_media.h b/sbin/pdisk/file_media.h index 1360b93e994..09fe0c7d8e9 100644 --- a/sbin/pdisk/file_media.h +++ b/sbin/pdisk/file_media.h @@ -1,7 +1,7 @@ /* * file_media.h - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* diff --git a/sbin/pdisk/hfs_misc.c b/sbin/pdisk/hfs_misc.c new file mode 100644 index 00000000000..f87ce52c4cc --- /dev/null +++ b/sbin/pdisk/hfs_misc.c @@ -0,0 +1,253 @@ +// +// hfs_misc.c - hfs routines +// +// Written by Eryk Vershen +// + +/* + * Copyright 2000 by Eryk Vershen + */ + +// for *printf() +#include <stdio.h> + +// for malloc(), calloc() & free() +#ifndef __linux__ +#include <stdlib.h> +#else +#include <malloc.h> +#endif + +// for strncpy() & strcmp() +#include <string.h> +// for O_RDONLY & O_RDWR +#include <fcntl.h> +// for errno +#include <errno.h> + +#include "hfs_misc.h" +#include "partition_map.h" +#include "convert.h" +#include "errors.h" + + +// +// Defines +// +#define MDB_OFFSET 2 +#define HFS_SIG 0x4244 /* i.e 'BD' */ +#define HFS_PLUS_SIG 0x482B /* i.e 'H+' */ + +#define get_align_long(x) (*(u32*)(x)) + + +// +// Types +// +typedef long long u64; + +typedef struct ExtDescriptor { // extent descriptor + u16 xdrStABN; // first allocation block + u16 xdrNumABlks; // number of allocation blocks +} ext_descriptor; + +typedef struct ExtDataRec { + ext_descriptor ed[3]; // extent data record +} ext_data_rec; + +/* + * The crazy "u16 x[2]" stuff here is to get around the fact + * that I can't convince the Mac compiler to align on 32 bit + * quantities on 16 bit boundaries... + */ +struct mdb_record { // master directory block + u16 drSigWord; // volume signature + u16 drCrDate[2]; // date and time of volume creation + u16 drLsMod[2]; // date and time of last modification + u16 drAtrb; // volume attributes + u16 drNmFls; // number of files in root directory + u16 drVBMSt; // first block of volume bitmap + u16 drAllocPtr; // start of next allocation search + u16 drNmAlBlks; // number of allocation blocks in volume + u32 drAlBlkSiz; // size (in bytes) of allocation blocks + u32 drClpSiz; // default clump size + u16 drAlBlSt; // first allocation block in volume + u16 drNxtCNID[2]; // next unused catalog node ID + u16 drFreeBks; // number of unused allocation blocks + char drVN[28]; // volume name + u16 drVolBkUp[2]; // date and time of last backup + u16 drVSeqNum; // volume backup sequence number + u16 drWrCnt[2]; // volume write count + u16 drXTClpSiz[2]; // clump size for extents overflow file + u16 drCTClpSiz[2]; // clump size for catalog file + u16 drNmRtDirs; // number of directories in root directory + u32 drFilCnt; // number of files in volume + u32 drDirCnt; // number of directories in volume + u32 drFndrInfo[8]; // information used by the Finder +#ifdef notdef + u16 drVCSize; // size (in blocks) of volume cache + u16 drVBMCSize; // size (in blocks) of volume bitmap cache + u16 drCtlCSize; // size (in blocks) of common volume cache +#else + u16 drEmbedSigWord; // type of embedded volume + ext_descriptor drEmbedExtent; // embedded volume extent +#endif + u16 drXTFlSize[2]; // size of extents overflow file + ext_data_rec drXTExtRec; // extent record for extents overflow file + u16 drCTFlSize[2]; // size of catalog file + ext_data_rec drCTExtRec; // extent record for catalog file +}; + + +typedef u32 HFSCatalogNodeID; + +typedef struct HFSPlusExtentDescriptor { + u32 startBlock; + u32 blockCount; +} HFSPlusExtentDescriptor; + +typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[ 8]; + +typedef struct HFSPlusForkData { + u64 logicalSize; + u32 clumpSize; + u32 totalBlocks; + HFSPlusExtentRecord extents; +} HFSPlusForkData; + +struct HFSPlusVolumeHeader { + u16 signature; + u16 version; + u32 attributes; + u32 lastMountedVersion; + u32 reserved; + u32 createDate; + u32 modifyDate; + u32 backupDate; + u32 checkedDate; + u32 fileCount; + u32 folderCount; + u32 blockSize; + u32 totalBlocks; + u32 freeBlocks; + u32 nextAllocation; + u32 rsrcClumpSize; + u32 dataClumpSize; + HFSCatalogNodeID nextCatalogID; + u32 writeCount; + u64 encodingsBitmap; + u8 finderInfo[ 32]; + HFSPlusForkData allocationFile; + HFSPlusForkData extentsFile; + HFSPlusForkData catalogFile; + HFSPlusForkData attributesFile; + HFSPlusForkData startupFile; +} HFSPlusVolumeHeader; + + +// +// Global Constants +// + + +// +// Global Variables +// + + +// +// Forward declarations +// +u32 embeded_offset(struct mdb_record *mdb, u32 sector); +int read_partition_block(partition_map *entry, unsigned long num, char *buf); + + +// +// Routines +// +u32 +embeded_offset(struct mdb_record *mdb, u32 sector) +{ + u32 e_offset; + + e_offset = mdb->drAlBlSt + mdb->drEmbedExtent.xdrStABN * (mdb->drAlBlkSiz / 512); + + return e_offset + sector; +} + + +char * +get_HFS_name(partition_map *entry, int *kind) +{ + DPME *data; + struct mdb_record *mdb; + //struct HFSPlusVolumeHeader *mdb2; + char *name = NULL; + int len; + + *kind = kHFS_not; + + mdb = (struct mdb_record *) malloc(PBLOCK_SIZE); + if (mdb == NULL) { + error(errno, "can't allocate memory for MDB"); + return NULL; + } + + data = entry->data; + if (strcmp(data->dpme_type, kHFSType) == 0) { + if (read_partition_block(entry, 2, (char *)mdb) == 0) { + error(-1, "Can't read block %d from partition %d", 2, entry->disk_address); + goto not_hfs; + } + if (mdb->drSigWord == HFS_PLUS_SIG) { + // pure HFS Plus + // printf("%lu HFS Plus\n", entry->disk_address); + *kind = kHFS_plus; + } else if (mdb->drSigWord != HFS_SIG) { + // not HFS !!! + printf("%lu not HFS\n", entry->disk_address); + *kind = kHFS_not; + } else if (mdb->drEmbedSigWord != HFS_PLUS_SIG) { + // HFS + // printf("%lu HFS\n", entry->disk_address); + *kind = kHFS_std; + len = mdb->drVN[0]; + name = (char *) malloc(len+1); + strncpy(name, &mdb->drVN[1], len); + name[len] = 0; + } else { + // embedded HFS plus + // printf("%lu embedded HFS Plus\n", entry->disk_address); + *kind = kHFS_embed; + len = mdb->drVN[0]; + name = (char *) malloc(len+1); + strncpy(name, &mdb->drVN[1], len); + name[len] = 0; + } + } +not_hfs: + free(mdb); + return name; +} + +// really need a function to read block n from partition m + +int +read_partition_block(partition_map *entry, unsigned long num, char *buf) +{ + DPME *data; + partition_map_header * map; + u32 base; + u64 offset; + + map = entry->the_map; + data = entry->data; + base = data->dpme_pblock_start; + + if (num >= data->dpme_pblocks) { + return 0; + } + offset = ((long long) base) * map->logical_block + num * 512; + + return read_media(map->m, offset, 512, (void *)buf); +} diff --git a/sbin/pdisk/hfs_misc.h b/sbin/pdisk/hfs_misc.h new file mode 100644 index 00000000000..80add2a832d --- /dev/null +++ b/sbin/pdisk/hfs_misc.h @@ -0,0 +1,41 @@ +// +// hfs_misc.h - hfs routines +// +// Written by Eryk Vershen +// + +/* + * Copyright 2000 by Eryk Vershen + */ + +#ifndef __hfs_misc__ +#define __hfs_misc__ + +#include "partition_map.h" + +// +// Defines +// + + +// +// Types +// + + +// +// Global Constants +// + + +// +// Global Variables +// + + +// +// Forward declarations +// +char *get_HFS_name(partition_map *entry, int *kind); + +#endif /* __hfs_misc__ */ diff --git a/sbin/pdisk/io.c b/sbin/pdisk/io.c index 84584e3f710..00b9640a08a 100644 --- a/sbin/pdisk/io.c +++ b/sbin/pdisk/io.c @@ -1,7 +1,7 @@ // // io.c - simple io and input parsing routines // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -29,7 +29,7 @@ #include <stdio.h> // for malloc() & free() -#if !defined(__linux__) && !defined(__unix__) || defined(__OpenBSD__) +#if !defined(__linux__) #include <stdlib.h> #else #include <malloc.h> @@ -89,7 +89,7 @@ char io_buffer[MAXIOSIZE]; // long get_number(int first_char); char* get_string(int eos); -int my_getch(); +int my_getch(void); void my_ungetch(int c); @@ -145,7 +145,7 @@ flush_to_newline(int keep_newline) int -get_okay(char *prompt, int default_value) +get_okay(const char *prompt, int default_value) { int c; @@ -176,7 +176,7 @@ get_okay(char *prompt, int default_value) int -get_command(char *prompt, int promptBeforeGet, int *command) +get_command(const char *prompt, int promptBeforeGet, int *command) { int c; @@ -202,7 +202,7 @@ get_command(char *prompt, int promptBeforeGet, int *command) int -get_number_argument(char *prompt, long *number, long default_value) +get_number_argument(const char *prompt, long *number, long default_value) { int c; int result = 0; @@ -281,7 +281,7 @@ get_number(int first_char) int -get_string_argument(char *prompt, char **string, int reprompt) +get_string_argument(const char *prompt, char **string, int reprompt) { int c; int result = 0; @@ -451,7 +451,7 @@ number_of_digits(unsigned long value) // Print a message on standard error & flush the input. // void -bad_input(char *fmt, ...) +bad_input(const char *fmt, ...) { va_list ap; diff --git a/sbin/pdisk/io.h b/sbin/pdisk/io.h index 197ca7ab884..971d0408ef1 100644 --- a/sbin/pdisk/io.h +++ b/sbin/pdisk/io.h @@ -1,7 +1,7 @@ // // io.h - simple io and input parsing routines // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -54,14 +54,14 @@ extern const long kDefault; // // Forward declarations // -void bad_input(char *fmt, ...); +void bad_input(const char *fmt, ...); void flush_to_newline(int keep_newline); -int get_command(char *prompt, int promptBeforeGet, int *command); +int get_command(const char *prompt, int promptBeforeGet, int *command); unsigned long get_multiplier(long divisor); -int get_number_argument(char *prompt, long *number, long default_value); -int get_okay(char *prompt, int default_value); +int get_number_argument(const char *prompt, long *number, long default_value); +int get_okay(const char *prompt, int default_value); int get_partition_modifier(void); -int get_string_argument(char *prompt, char **string, int reprompt); +int get_string_argument(const char *prompt, char **string, int reprompt); int number_of_digits(unsigned long value); #endif /* __io__ */ diff --git a/sbin/pdisk/media.c b/sbin/pdisk/media.c index a9330cb3a4b..31b999d22cd 100644 --- a/sbin/pdisk/media.c +++ b/sbin/pdisk/media.c @@ -1,7 +1,7 @@ /* * media.c - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* @@ -52,7 +52,7 @@ /* * Global Variables */ -static media_kind = 0; +static long media_kind = 0; /* * Forward declarations @@ -166,7 +166,9 @@ os_reload_media(MEDIA m) } +#if !defined(__linux__) && !defined(__unix__) #pragma mark - +#endif diff --git a/sbin/pdisk/media.h b/sbin/pdisk/media.h index 1b4209073be..6933e491d0e 100644 --- a/sbin/pdisk/media.h +++ b/sbin/pdisk/media.h @@ -1,7 +1,7 @@ /* * media.h - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* diff --git a/sbin/pdisk/partition_map.c b/sbin/pdisk/partition_map.c index 0751d336614..bddff40ee83 100644 --- a/sbin/pdisk/partition_map.c +++ b/sbin/pdisk/partition_map.c @@ -1,7 +1,7 @@ // // partition_map.c - partition map routines // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -44,6 +44,7 @@ #include "partition_map.h" #include "pathname.h" +#include "hfs_misc.h" #include "deblock_media.h" #include "io.h" #include "convert.h" @@ -95,13 +96,14 @@ extern int cflag; // // Forward declarations // -int add_data_to_map(struct dpme *data, long index, partition_map_header *map); +int add_data_to_map(struct dpme *, long, partition_map_header *); int coerce_block0(partition_map_header *map); int contains_driver(partition_map *entry); void combine_entry(partition_map *entry); long compute_device_size(partition_map_header *map, partition_map_header *oldmap); DPME* create_data(const char *name, const char *dptype, u32 base, u32 length); void delete_entry(partition_map *entry); +char *get_HFS_name(partition_map *entry, int *kind); void insert_in_base_order(partition_map *entry); void insert_in_disk_order(partition_map *entry); int read_block(partition_map_header *map, unsigned long num, char *buf); @@ -121,8 +123,8 @@ open_partition_map(char *name, int *valid_file, int ask_logical_size) { MEDIA m; partition_map_header * map; - int writeable; - int size; + int writable; + long size; m = open_pathname_as_media(name, (rflag)?O_RDONLY:O_RDWR); if (m == 0) { @@ -132,10 +134,10 @@ open_partition_map(char *name, int *valid_file, int ask_logical_size) *valid_file = 0; return NULL; } else { - writeable = 0; + writable = 0; } } else { - writeable = 1; + writable = 1; } *valid_file = 1; @@ -146,8 +148,9 @@ open_partition_map(char *name, int *valid_file, int ask_logical_size) return NULL; } map->name = name; - map->writeable = (rflag)?0:writeable; + map->writable = (rflag)?0:writable; map->changed = 0; + map->written = 0; map->disk_order = NULL; map->base_order = NULL; @@ -173,10 +176,10 @@ open_partition_map(char *name, int *valid_file, int ask_logical_size) if (ask_logical_size && interactive) { size = PBLOCK_SIZE; - printf("A logical block is %d bytes: ", size); + printf("A logical block is %ld bytes: ", size); flush_to_newline(0); get_number_argument("what should be the logical block size? ", - (long *)&size, size); + &size, size); size = (size / PBLOCK_SIZE) * PBLOCK_SIZE; if (size < PBLOCK_SIZE) { size = PBLOCK_SIZE; @@ -223,6 +226,7 @@ close_partition_map(partition_map_header *map) for (entry = map->disk_order; entry != NULL; entry = next) { next = entry->next_on_disk; free(entry->data); + free(entry->HFS_name); free(entry); } close_media(map->m); @@ -235,7 +239,7 @@ read_partition_map(partition_map_header *map) { DPME *data; u32 limit; - int index; + int ix; int old_logical; double d; @@ -277,17 +281,17 @@ read_partition_map(partition_map_header *map) //printf("logical = %d, physical = %d\n", map->logical_block, map->physical_block); limit = data->dpme_map_entries; - index = 1; + ix = 1; while (1) { - if (add_data_to_map(data, index, map) == 0) { + if (add_data_to_map(data, ix, map) == 0) { free(data); return -1; } - if (index >= limit) { + if (ix >= limit) { break; } else { - index++; + ix++; } data = (DPME *) malloc(PBLOCK_SIZE); @@ -296,14 +300,14 @@ read_partition_map(partition_map_header *map) return -1; } - if (read_block(map, index, (char *)data) == 0) { - error(-1, "Can't read block %u from '%s'", index, map->name); + if (read_block(map, ix, (char *)data) == 0) { + error(-1, "Can't read block %u from '%s'", ix, map->name); free(data); return -1; } else if (convert_dpme(data, 1) || (data->dpme_signature != DPME_SIGNATURE && dflag == 0) || (data->dpme_map_entries != limit && dflag == 0)) { - error(-1, "Bad data in block %u from '%s'", index, map->name); + error(-1, "Bad data in block %u from '%s'", ix, map->name); free(data); return -1; } @@ -319,7 +323,7 @@ write_partition_map(partition_map_header *map) char *block; partition_map * entry; int i = 0; - int result; + int result = 0; m = map->m; if (map->misc != NULL) { @@ -345,6 +349,8 @@ write_partition_map(partition_map_header *map) error(errno, "Unable to write block %d", i); } } + +#ifdef __linux__ // zap the block after the map (if possible) to get around a bug. if (map->maximum_in_map > 0 && i < map->maximum_in_map) { i += 1; @@ -357,6 +363,8 @@ write_partition_map(partition_map_header *map) free(block); } } +#endif + if (interactive) printf("The partition table has been altered!\n\n"); @@ -365,11 +373,11 @@ write_partition_map(partition_map_header *map) int -add_data_to_map(struct dpme *data, long index, partition_map_header *map) +add_data_to_map(struct dpme *data, long ix, partition_map_header *map) { partition_map *entry; -//printf("add data %d to map\n", index); +//printf("add data %d to map\n", ix); entry = (partition_map *) malloc(sizeof(partition_map)); if (entry == NULL) { error(errno, "can't allocate memory for map entries"); @@ -379,10 +387,11 @@ add_data_to_map(struct dpme *data, long index, partition_map_header *map) entry->prev_on_disk = NULL; entry->next_by_base = NULL; entry->prev_by_base = NULL; - entry->disk_address = index; + entry->disk_address = ix; entry->the_map = map; entry->data = data; entry->contains_driver = contains_driver(entry); + entry->HFS_name = get_HFS_name(entry, &entry->HFS_kind); insert_in_disk_order(entry); insert_in_base_order(entry); @@ -430,7 +439,7 @@ create_partition_map(char *name, partition_map_header *oldmap) DPME *data; unsigned long default_number; unsigned long number; - int size; + long size; unsigned long multiple; m = open_pathname_as_media(name, (rflag)?O_RDONLY:O_RDWR); @@ -447,7 +456,7 @@ create_partition_map(char *name, partition_map_header *oldmap) return NULL; } map->name = name; - map->writeable = (rflag)?0:1; + map->writable = (rflag)?0:1; map->changed = 1; map->disk_order = NULL; map->base_order = NULL; @@ -460,10 +469,10 @@ create_partition_map(char *name, partition_map_header *oldmap) m = open_deblock_media(PBLOCK_SIZE, m); map->m = m; if (interactive) { - printf("A physical block is %d bytes: ", size); + printf("A physical block is %ld bytes: ", size); flush_to_newline(0); get_number_argument("what should be the physical block size? ", - (long *)&size, size); + &size, size); size = (size / PBLOCK_SIZE) * PBLOCK_SIZE; if (size < PBLOCK_SIZE) { size = PBLOCK_SIZE; @@ -481,18 +490,20 @@ create_partition_map(char *name, partition_map_header *oldmap) size = PBLOCK_SIZE; } if (interactive) { - printf("A logical block is %d bytes: ", size); + printf("A logical block is %ld bytes: ", size); flush_to_newline(0); get_number_argument("what should be the logical block size? ", - (long *)&size, size); + &size, size); size = (size / PBLOCK_SIZE) * PBLOCK_SIZE; if (size < PBLOCK_SIZE) { size = PBLOCK_SIZE; } } +#if 0 if (size > map->physical_block) { size = map->physical_block; } +#endif map->logical_block = size; map->blocks_in_map = 0; @@ -622,7 +633,38 @@ add_partition_to_map(const char *name, const char *dptype, u32 base, u32 length, (cur->data->dpme_pblock_start + cur->data->dpme_pblocks)) { break; } else { - cur = cur->next_by_base; + // check if request is past end of existing partitions, but on disk + if ((cur->next_by_base == NULL) && + (base + length <= map->media_size)) { + // Expand final free partition + if ((istrncmp(cur->data->dpme_type, kFreeType, DPISTRLEN) == 0) && + base >= cur->data->dpme_pblock_start) { + cur->data->dpme_pblocks = + map->media_size - cur->data->dpme_pblock_start; + break; + } + // create an extra free partition + if (base >= cur->data->dpme_pblock_start + cur->data->dpme_pblocks) { + if (map->maximum_in_map < 0) { + limit = map->media_size; + } else { + limit = map->maximum_in_map; + } + if (map->blocks_in_map + 1 > limit) { + printf("the map is not big enough\n"); + return 0; + } + data = create_data(kFreeName, kFreeType, + cur->data->dpme_pblock_start + cur->data->dpme_pblocks, + map->media_size - (cur->data->dpme_pblock_start + cur->data->dpme_pblocks)); + if (data != NULL) { + if (add_data_to_map(data, cur->disk_address, map) == 0) { + free(data); + } + } + } + } + cur = cur->next_by_base; } } // if it is not Extra then punt @@ -719,33 +761,82 @@ create_data(const char *name, const char *dptype, u32 base, u32 length) strncpy(data->dpme_type, dptype, DPISTRLEN); data->dpme_lblock_start = 0; data->dpme_lblocks = data->dpme_pblocks; - if (strcmp(data->dpme_type, kHFSType) == 0) { /* XXX this is gross, fix it! */ - data->dpme_flags = APPLE_HFS_FLAGS_VALUE; - } - else { - dpme_writable_set(data, 1); - dpme_readable_set(data, 1); - dpme_bootable_set(data, 0); - dpme_in_use_set(data, 0); - dpme_allocated_set(data, 1); - dpme_valid_set(data, 1); - } + dpme_init_flags(data); } return data; } +void +dpme_init_flags(DPME *data) +{ + if (istrncmp(data->dpme_type, kHFSType, DPISTRLEN) == 0) { /* XXX this is gross, fix it! */ + data->dpme_flags = APPLE_HFS_FLAGS_VALUE; + } + else { + dpme_writable_set(data, 1); + dpme_readable_set(data, 1); + dpme_bootable_set(data, 0); + dpme_in_use_set(data, 0); + dpme_allocated_set(data, 1); + dpme_valid_set(data, 1); + } +} + +/* These bits are appropriate for Apple_UNIX_SVR2 partitions + * used by OpenBSD. They may be ok for A/UX, but have not been + * tested. + */ +void +bzb_init_slice(BZB *bp, int slice) +{ + memset(bp,0,sizeof(BZB)); + if ((slice >= 'A') && (slice <= 'Z')) { + slice += 'a' - 'A'; + } + if ((slice != 0) && ((slice < 'a') || (slice > 'z'))) { + error(-1,"Bad bzb slice"); + slice = 0; + } + switch (slice) { + case 0: + case 'c': + return; + case 'a': + bp->bzb_type = FST; + strlcpy(bp->bzb_mount_point, "/", sizeof(bp->bzb_mount_point)); + bp->bzb_inode = 1; + bzb_root_set(bp,1); + bzb_usr_set(bp,1); + break; + case 'b': + bp->bzb_type = FSTSFS; + strlcpy(bp->bzb_mount_point, "(swap)", sizeof(bp->bzb_mount_point)); + break; + case 'g': + strlcpy(bp->bzb_mount_point, "/usr", sizeof(bp->bzb_mount_point)); + /* Fall through */ + default: + bp->bzb_type = FST; + bp->bzb_inode = 1; + bzb_usr_set(bp,1); + break; + } + bzb_slice_set(bp,0); // XXX OpenBSD disksubr.c ignores slice + // bzb_slice_set(bp,slice-'a'+1); + bp->bzb_magic = BZBMAGIC; +} void renumber_disk_addresses(partition_map_header *map) { partition_map * cur; - long index; + long ix; // reset disk addresses cur = map->disk_order; - index = 1; + ix = 1; while (cur != NULL) { - cur->disk_address = index++; + cur->disk_address = ix++; cur->data->dpme_map_entries = map->blocks_in_map; cur = cur->next_on_disk; } @@ -872,7 +963,7 @@ sync_device_size(partition_map_header *map) return; } d = map->media_size; - size = (d * map->logical_block) / map->physical_block; + size = (d * map->logical_block) / p->sbBlkSize; if (p->sbBlkCount != size) { p->sbBlkCount = size; } @@ -895,6 +986,20 @@ delete_partition_from_map(partition_map *entry) return; } } + // if past end of disk, delete it completely + if (entry->next_by_base == NULL && + entry->data->dpme_pblock_start >= entry->the_map->media_size) { + if (entry->contains_driver) { + remove_driver(entry); // update block0 if necessary + } + delete_entry(entry); + return; + } + // If at end of disk, incorporate extra disk space to partition + if (entry->next_by_base == NULL) { + entry->data->dpme_pblocks = + entry->the_map->media_size - entry->data->dpme_pblock_start; + } data = create_data(kFreeName, kFreeType, entry->data->dpme_pblock_start, entry->data->dpme_pblocks); if (data == NULL) { @@ -904,6 +1009,9 @@ delete_partition_from_map(partition_map *entry) remove_driver(entry); // update block0 if necessary } free(entry->data); + free(entry->HFS_name); + entry->HFS_kind = kHFS_not; + entry->HFS_name = 0; entry->data = data; combine_entry(entry); map = entry->the_map; @@ -1035,18 +1143,19 @@ delete_entry(partition_map *entry) } free(entry->data); + free(entry->HFS_name); free(entry); } partition_map * -find_entry_by_disk_address(long index, partition_map_header *map) +find_entry_by_disk_address(long ix, partition_map_header *map) { partition_map * cur; cur = map->disk_order; while (cur != NULL) { - if (cur->disk_address == index) { + if (cur->disk_address == ix) { break; } cur = cur->next_on_disk; @@ -1070,9 +1179,24 @@ find_entry_by_type(const char *type_name, partition_map_header *map) return cur; } +partition_map * +find_entry_by_base(u32 base, partition_map_header *map) +{ + partition_map * cur; + + cur = map->base_order; + while (cur != NULL) { + if (cur->data->dpme_pblock_start == base) { + break; + } + cur = cur->next_by_base; + } + return cur; +} + void -move_entry_in_map(long old_index, long index, partition_map_header *map) +move_entry_in_map(long old_index, long ix, partition_map_header *map) { partition_map * cur; @@ -1081,7 +1205,7 @@ move_entry_in_map(long old_index, long index, partition_map_header *map) printf("No such partition\n"); } else { remove_from_disk_order(cur); - cur->disk_address = index; + cur->disk_address = ix; insert_in_disk_order(cur); renumber_disk_addresses(map); map->changed = 1; diff --git a/sbin/pdisk/partition_map.h b/sbin/pdisk/partition_map.h index d53032bcfde..963584cc6fc 100644 --- a/sbin/pdisk/partition_map.h +++ b/sbin/pdisk/partition_map.h @@ -1,7 +1,7 @@ // // partition_map.h - partition map routines // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -36,6 +36,7 @@ // Defines // #define PBLOCK_SIZE 512 +#define MAX_LINUX_MAP 15 // @@ -47,8 +48,9 @@ struct partition_map_header { struct partition_map * disk_order; struct partition_map * base_order; Block0 *misc; - int writeable; + int writable; int changed; + int written; int physical_block; // must be == sbBlockSize int logical_block; // must be <= physical_block int blocks_in_map; @@ -66,9 +68,19 @@ struct partition_map { struct partition_map_header * the_map; int contains_driver; DPME *data; + int HFS_kind; + char *HFS_name; }; typedef struct partition_map partition_map; +/* Identifies the HFS kind. */ +enum { + kHFS_not = 0, // ' ' + kHFS_std = 1, // 'h' + kHFS_embed = 2, // 'e' + kHFS_plus = 3 // '+' +}; + // // Global Constants @@ -96,12 +108,15 @@ int add_partition_to_map(const char *name, const char *dptype, u32 base, u32 len void close_partition_map(partition_map_header *map); partition_map_header* create_partition_map(char *name, partition_map_header *oldmap); void delete_partition_from_map(partition_map *entry); -partition_map* find_entry_by_disk_address(long index, partition_map_header *map); +partition_map* find_entry_by_disk_address(long, partition_map_header *); partition_map* find_entry_by_type(const char *type_name, partition_map_header *map); +partition_map* find_entry_by_base(u32 base, partition_map_header *map); partition_map_header* init_partition_map(char *name, partition_map_header* oldmap); -void move_entry_in_map(long old_index, long index, partition_map_header *map); +void move_entry_in_map(long, long, partition_map_header *); partition_map_header* open_partition_map(char *name, int *valid_file, int ask_logical_size); void resize_map(long new_size, partition_map_header *map); void write_partition_map(partition_map_header *map); +void bzb_init_slice(BZB *bp, int slice); +void dpme_init_flags(DPME *data); #endif /* __partition_map__ */ diff --git a/sbin/pdisk/pathname.c b/sbin/pdisk/pathname.c index 1a437a69a09..16d2bd73003 100644 --- a/sbin/pdisk/pathname.c +++ b/sbin/pdisk/pathname.c @@ -1,7 +1,7 @@ /* * pathname.c - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* @@ -62,7 +62,7 @@ */ /* - * Note that open_pathname_as_media() and get_mklinux_name() have almost + * Note that open_pathname_as_media() and get_linux_name() have almost * identical structures. If one changes the other must also! */ MEDIA @@ -76,10 +76,12 @@ open_pathname_as_media(char *path, int oflag) if (strncmp("/dev/", path, 5) == 0) { if (strncmp("/dev/scsi", path, 9) == 0) { if (path[9] >= '0' && path[9] <= '7' && path[10] == 0) { + // scsi[0-7] id = path[9] - '0'; m = open_old_scsi_as_media(id); } else if (path[9] >= '0' && path[9] <= '7' && path[10] == '.' && path[11] >= '0' && path[11] <= '7' && path[12] == 0) { + // scsi[0-7].[0-7] id = path[11] - '0'; bus = path[9] - '0'; m = open_scsi_as_media(bus, id); @@ -87,28 +89,40 @@ open_pathname_as_media(char *path, int oflag) } else if (strncmp("/dev/ata", path, 8) == 0 || strncmp("/dev/ide", path, 8) == 0) { if (path[8] >= '0' && path[8] <= '7' && path[9] == 0) { + // ata[0-7], ide[0-7] bus = path[8] - '0'; m = open_ata_as_media(bus, 0); } else if (path[8] >= '0' && path[8] <= '7' && path[9] == '.' && path[10] >= '0' && path[10] <= '1' && path[11] == 0) { + // ata[0-7].[0-1], ide[0-7].[0-1] id = path[10] - '0'; bus = path[8] - '0'; m = open_ata_as_media(bus, id); } } else if (strncmp("/dev/sd", path, 7) == 0) { if (path[7] >= 'a' && path[7] <= 'z' && path[8] == 0) { + // sd[a-z] id = path[7] - 'a'; - m = open_mklinux_scsi_as_media(id, 0); + m = open_linux_scsi_as_media(id, 0); + } else if (path[7] >= 'a' && path[7] <= 'z' && path[8] == '.' + && path[9] >= 'a' && path[9] <= 'z' && path[10] == 0) { + // sd[a-z][a-z] + bus = path[7] - 'a'; + id = path[9] - 'a'; + id += bus * 26; + m = open_linux_scsi_as_media(id, 0); } } else if (strncmp("/dev/scd", path, 8) == 0) { if (path[8] >= '0' && path[8] <= '9' && path[9] == 0) { + // scd[0-9] id = path[8] - '0'; - m = open_mklinux_scsi_as_media(id, 1); + m = open_linux_scsi_as_media(id, 1); } } else if (strncmp("/dev/hd", path, 7) == 0) { if (path[7] >= 'a' && path[7] <= 'z' && path[8] == 0) { + // hd[a-z] id = path[7] - 'a'; - m = open_mklinux_ata_as_media(id); + m = open_linux_ata_as_media(id); } } } else @@ -122,7 +136,7 @@ open_pathname_as_media(char *path, int oflag) char * -get_mklinux_name(char *path) +get_linux_name(char *path) { char *result = 0; #if !defined(__linux__) && !defined(__unix__) @@ -133,27 +147,31 @@ get_mklinux_name(char *path) if (strncmp("/dev/scsi", path, 9) == 0) { if (path[9] >= '0' && path[9] <= '7' && path[10] == 0) { /* old scsi */ + // scsi[0-7] id = path[9] - '0'; - result = mklinux_old_scsi_name(id); + result = linux_old_scsi_name(id); } else if (path[9] >= '0' && path[9] <= '7' && path[10] == '.' && path[11] >= '0' && path[11] <= '7' && path[12] == 0) { /* new scsi */ + // scsi[0-7].[0-7] id = path[11] - '0'; bus = path[9] - '0'; - result = mklinux_scsi_name(bus, id); + result = linux_scsi_name(bus, id); } } else if (strncmp("/dev/ata", path, 8) == 0 || strncmp("/dev/ide", path, 8) == 0) { if (path[8] >= '0' && path[8] <= '7' && path[9] == 0) { /* ata/ide - master device */ + // ata[0-7], ide[0-7] bus = path[8] - '0'; - result = mklinux_ata_name(bus, 0); + result = linux_ata_name(bus, 0); } else if (path[8] >= '0' && path[8] <= '7' && path[9] == '.' && path[10] >= '0' && path[10] <= '1' && path[11] == 0) { /* ata/ide */ + // ata[0-7].[0-1], ide[0-7].[0-1] id = path[10] - '0'; bus = path[8] - '0'; - result = mklinux_ata_name(bus, id); + result = linux_ata_name(bus, id); } } } @@ -175,17 +193,17 @@ MEDIA_ITERATOR next_media_kind(long *state) { MEDIA_ITERATOR result; - long index; + long ix; result = 0; - index = *state; + ix = *state; - switch (index) { + switch (ix) { case 0: #if defined(__linux__) || defined(__unix__) result = create_file_iterator(); #endif - index = 1; + ix = 1; if (result != 0) { break; } @@ -195,7 +213,7 @@ next_media_kind(long *state) #if !defined(__linux__) && !defined(__unix__) result = create_ata_iterator(); #endif - index = 2; + ix = 2; if (result != 0) { break; } @@ -205,7 +223,7 @@ next_media_kind(long *state) #if !defined(__linux__) && !defined(__unix__) result = create_scsi_iterator(); #endif - index = 3; + ix = 3; if (result != 0) { break; } @@ -216,7 +234,7 @@ next_media_kind(long *state) break; } - *state = index; + *state = ix; return result; } diff --git a/sbin/pdisk/pathname.h b/sbin/pdisk/pathname.h index eddf78a8c06..19a8fdf8fb7 100644 --- a/sbin/pdisk/pathname.h +++ b/sbin/pdisk/pathname.h @@ -1,7 +1,7 @@ /* * pathname.h - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* @@ -57,6 +57,6 @@ MEDIA open_pathname_as_media(char *path, int oflag); MEDIA_ITERATOR first_media_kind(long *state); MEDIA_ITERATOR next_media_kind(long *state); -char *get_mklinux_name(char *name); +char *get_linux_name(char *name); #endif /* __pathname__ */ diff --git a/sbin/pdisk/pdisk.8 b/sbin/pdisk/pdisk.8 index 2000a9cad27..c9d9e8250a5 100644 --- a/sbin/pdisk/pdisk.8 +++ b/sbin/pdisk/pdisk.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pdisk.8,v 1.12 2005/04/25 01:32:16 martin Exp $ +.\" $OpenBSD: pdisk.8,v 1.13 2006/04/27 19:52:21 martin Exp $ .\" .\" Copyright 1996,1997,1998 by Apple Computer, Inc. .\" All Rights Reserved @@ -19,7 +19,7 @@ .\" NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION .\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd September 26, 1997 +.Dd April 11, 2006 .Dt PDISK 8 .Os .Sh NAME @@ -27,7 +27,6 @@ .Nd HFS(DPME) partition maintenance program .Sh SYNOPSIS .Nm pdisk -.Op Fl c .Op Fl h .Op Fl i .Op Fl l @@ -58,11 +57,6 @@ is usually one of the following: .Pp The options are as follows: .Bl -tag -width Ds -.It Fl c -Causes -.Nm -to always ignore the device size listed in the partition table -and compute the device size by other means. .It Fl h Prints a rather lame set of help messages for the .Nm @@ -169,6 +163,7 @@ other arguments. The .Em n (name) command allows the name of a partition to be changed. +The name must not contain any spaces. Note that the various "Apple_Driver" partitions depend on the name field for proper functioning. I am not aware of any other partition types with this limitation. @@ -201,13 +196,22 @@ disk and the kernel where must be issued to cause the kernel to reinterpret the new label. .Sh SEE ALSO .Xr disklabel 8 , -.Xr fdisk 8 +.Xr fdisk 8 , +.Xr newfs 8 +.Sh HISTORY +The +.Nm +utility was originally developed for MkLinux. .Sh AUTHORS -.An Eryk Vershen Aq eryk@apple.com . +.An Eryk Vershen .Sh BUGS Some people believe there should really be just one disk partitioning utility. .Pp .Nm should be able to create HFS partitions that work. .Pp +Filesystem volume names are out of place in a partition utility. +This utility supports HFS volume names, but not volume names +of any other filesystem types. +.Pp Even more help should be available during user input. diff --git a/sbin/pdisk/pdisk.c b/sbin/pdisk/pdisk.c index c36365532fc..c8cbafb772c 100644 --- a/sbin/pdisk/pdisk.c +++ b/sbin/pdisk/pdisk.c @@ -1,7 +1,7 @@ // // pdisk - an editor for Apple format partition tables // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // // Still under development (as of 15 January 1998) // @@ -30,17 +30,23 @@ // for printf() #include <stdio.h> -#ifdef __linux__ +#if defined(__linux__) || defined(__OpenBSD__) #include <getopt.h> +#endif +#ifdef __linux__ #include <malloc.h> -#elif defined(__OpenBSD__) -#include <stdlib.h> #else // for malloc() & free() #include <stdlib.h> +#if !defined(__unix__) // for SIOUXsettings #include <SIOUX.h> #endif +#endif + +#ifdef __unix__ +#include <unistd.h> +#endif // for strncpy() & strlen() #include <string.h> @@ -59,6 +65,7 @@ #include "io.h" #include "partition_map.h" #include "pathname.h" +#include "hfs_misc.h" #include "errors.h" #include "dump.h" #include "validate.h" @@ -115,6 +122,9 @@ static int first_get = 1; // Forward declarations // void do_change_map_size(partition_map_header *map); +#ifdef __m68k__ +void do_update_dpme(partition_map *entry); +#endif void do_create_partition(partition_map_header *map, int get_type); void do_delete_partition(partition_map_header *map); void do_display_block(partition_map_header *map, char *alt_name); @@ -130,10 +140,12 @@ int get_base_argument(long *number, partition_map_header *map); int get_command_line(int *argc, char ***argv); int get_size_argument(long *number, partition_map_header *map); int get_options(int argc, char **argv); -void interact(); -void print_edit_notes(); -void print_expert_notes(); -void print_top_notes(); +void interact(void); +void print_edit_notes(void); +void print_expert_notes(void); +#ifdef __linux__ +void print_top_notes(void); +#endif // @@ -142,9 +154,10 @@ void print_top_notes(); int main(int argc, char **argv) { -#if defined(__linux__) || defined (__OpenBSD__) +#if defined(__linux__) || defined(__unix__) int name_index; #else + SIOUXSettings.rows = 100; printf("This app uses the SIOUX console library\n"); printf("Choose 'Quit' from the file menu to quit.\n\n"); printf("Use fake disk names (/dev/scsi<bus>.<id>; i.e. /dev/scsi0.1, /dev/scsi1.3, etc.).\n\n"); @@ -168,14 +181,14 @@ main(int argc, char **argv) } versionstr = (char *)get_version_string(); if (versionstr) { - if (strcmp(VERSION, versionstr) != 0) { + if (strcmp(VERSION, versionstr) != 0) { fatal(-1, "Version string static form (%s) does not match dynamic form (%s)\n", VERSION, versionstr); - } - free(versionstr); + } + free(versionstr); } -#if defined(__linux__) || defined(__OpenBSD__) +#if defined(__linux__) || defined(__unix__) name_index = get_options(argc, argv); if (vflag) { @@ -193,7 +206,12 @@ main(int argc, char **argv) dump(argv[name_index++]); } } else { +#ifdef __linux__ list_all_disks(); +#else + usage("no device argument"); + do_help(); +#endif } } else if (name_index < argc) { while (name_index < argc) { @@ -216,16 +234,19 @@ main(int argc, char **argv) } +#ifdef __linux__ void print_top_notes() { printf("Notes:\n"); printf(" Disks have fake names of the form /dev/scsi<bus>.<id>\n"); printf(" For example, /dev/scsi0.1, /dev/scsi1.3, and so on.\n"); - printf(" MkLinux style names are also allowed (i.e /dev/sda or /dev/hda),\n"); - printf(" and these names follow the MkLinux DR3 conventions.\n"); + printf(" Linux style names are also allowed (i.e /dev/sda or /dev/hda).\n"); + printf(" Due to some technical problems these names may not match\n"); + printf(" the 'real' linux names.\n"); printf("\n"); } +#endif void @@ -241,7 +262,9 @@ interact() switch (command) { case '?': +#ifdef __linux__ print_top_notes(); +#endif // fall through case 'H': case 'h': @@ -249,10 +272,13 @@ interact() printf(" h print help\n"); printf(" v print the version number and release date\n"); printf(" l list device's map\n"); +#ifdef __linux__ printf(" L list all devices' maps\n"); +#endif printf(" e edit device's map\n"); printf(" E (edit map with specified block size)\n"); printf(" r toggle readonly flag\n"); + printf(" f toggle show filesystem name flag\n"); if (dflag) { printf(" a toggle abbreviate flag\n"); printf(" p toggle physical flag\n"); @@ -270,9 +296,11 @@ interact() case 'v': printf("version " VERSION " (" RELEASE_DATE ")\n"); break; +#ifdef __linux__ case 'L': list_all_disks(); break; +#endif case 'l': if (get_string_argument("Name of device: ", &name, 1) == 0) { bad_input("Bad name"); @@ -300,6 +328,15 @@ interact() } printf("Now in %s mode.\n", (rflag)?"readonly":"read/write"); break; + case 'F': + case 'f': + if (fflag) { + fflag = 0; + } else { + fflag = 1; + } + printf("Now in show %s name mode.\n", (fflag)?"filesystem":"partition"); + break; case 'A': case 'a': if (dflag) { @@ -365,11 +402,12 @@ interact() } -#ifdef __linux__ +#if defined(__linux__) || defined(__unix__) int get_options(int argc, char **argv) { int c; +#if defined(__linux__) || defined(__OpenBSD__) static struct option long_options[] = { // name has_arg &flag val @@ -379,14 +417,20 @@ get_options(int argc, char **argv) {"debug", no_argument, 0, 'd'}, {"readonly", no_argument, 0, 'r'}, {"abbr", no_argument, 0, 'a'}, + {"fname", no_argument, 0, 'f'}, {"logical", no_argument, 0, kLogicalOption}, {"interactive", no_argument, 0, 'i'}, {"compute_size", no_argument, 0, 'c'}, {0, 0, 0, 0} }; int option_index = 0; - extern int optind; - extern char *optarg; +#else + extern int opterr; /* who does error messages */ + extern int optopt; /* char that caused the error */ + int getopt_error; /* getopt choked */ +#endif + extern int optind; /* next argv index */ + extern char *optarg; /* pointer to argument */ int flag = 0; lflag = LFLAG_DEFAULT; @@ -399,10 +443,25 @@ get_options(int argc, char **argv) pflag = PFLAG_DEFAULT; interactive = INTERACT_DEFAULT; cflag = CFLAG_DEFAULT; + fflag = FFLAG_DEFAULT; +#if defined(__linux__) || defined(__OpenBSD__) optind = 0; // reset option scanner logic - while ((c = getopt_long(argc, argv, "hlvdric", long_options, - &option_index)) >= 0) { + while ((c = getopt_long(argc, argv, "hlvdraLicf", long_options, + &option_index)) >= 0) +#else + opterr = 0; /* tell getopt to be quiet */ + while ((c = getopt(argc, argv, "hlvdraLicf")) != EOF) +#endif + { +#if !(defined(__linux__) || defined(__OpenBSD__)) + if (c == '?') { + getopt_error = 1; + c = optopt; + } else { + getopt_error = 0; + } +#endif switch (c) { case kLongOption: // option_index would be used here @@ -430,68 +489,8 @@ get_options(int argc, char **argv) case 'r': rflag = (RFLAG_DEFAULT)?0:1; break; - case 'i': - interactive = (INTERACT_DEFAULT)?0:1; - break; - case 'a': - aflag = (AFLAG_DEFAULT)?0:1; - break; - case kLogicalOption: - pflag = (PFLAG_DEFAULT)?0:1; - break; - case kBadOption: - default: - flag = 1; - break; - } - } - if (flag) { - usage("bad arguments"); - } - return optind; -} -#endif - -#ifdef __OpenBSD__ -int -get_options(int argc, char **argv) -{ - int c; - extern int optind; - extern char *optarg; - int flag = 0; - - lflag = LFLAG_DEFAULT; - lfile = NULL; - vflag = VFLAG_DEFAULT; - hflag = HFLAG_DEFAULT; - dflag = DFLAG_DEFAULT; - rflag = RFLAG_DEFAULT; - aflag = AFLAG_DEFAULT; - pflag = PFLAG_DEFAULT; - interactive = INTERACT_DEFAULT; - cflag = CFLAG_DEFAULT; - - optind = 1; // reset option scanner logic - while ((c = getopt(argc, argv, "hlvdric")) != -1) { - switch (c) { - case 'h': - hflag = (HFLAG_DEFAULT)?0:1; - break; - case 'l': - lflag = (LFLAG_DEFAULT)?0:1; - break; - case 'v': - vflag = (VFLAG_DEFAULT)?0:1; - break; - case 'd': - dflag = (DFLAG_DEFAULT)?0:1; - break; - case 'c': - cflag = (CFLAG_DEFAULT)?0:1; - break; - case 'r': - rflag = (RFLAG_DEFAULT)?0:1; + case 'f': + fflag = (FFLAG_DEFAULT)?0:1; break; case 'i': interactive = (INTERACT_DEFAULT)?0:1; @@ -499,9 +498,11 @@ get_options(int argc, char **argv) case 'a': aflag = (AFLAG_DEFAULT)?0:1; break; + case 'L': case kLogicalOption: pflag = (PFLAG_DEFAULT)?0:1; break; + case kBadOption: default: flag = 1; break; @@ -548,6 +549,12 @@ edit(char *name, int ask_logical_size) printf("Edit %s -\n", name); +#if 0 /* this check is not found in linux fdisk-0.1 */ + if (map != NULL && map->blocks_in_map > MAX_LINUX_MAP) { + error(-1, "Map contains more than %d blocks - Linux may have trouble", MAX_LINUX_MAP); + } +#endif + while (get_command("Command (? for help): ", first_get, &command)) { first_get = 0; order = 1; @@ -560,21 +567,21 @@ edit(char *name, int ask_logical_size) case 'H': case 'h': printf("Commands are:\n"); + printf(" C (create with type also specified)\n"); + printf(" c create new partition (standard OpenBSD root)\n"); + printf(" d delete a partition\n"); printf(" h help\n"); - printf(" p print the partition table\n"); - printf(" P (print ordered by base address)\n"); printf(" i initialize partition map\n"); - printf(" s change size of partition map\n"); - printf(" c create new partition (standard OpenBSD type)\n"); - printf(" C (create with type also specified)\n"); printf(" n (re)name a partition\n"); - printf(" d delete a partition\n"); + printf(" P (print ordered by base address)\n"); + printf(" p print the partition table\n"); + printf(" q quit editing\n"); printf(" r reorder partition entry in map\n"); + printf(" s change size of partition map\n"); printf(" t change a partition's type\n"); if (!rflag) { printf(" w write the partition table\n"); } - printf(" q quit editing (don't save changes)\n"); if (dflag) { printf(" x extra extensions for experts\n"); } @@ -587,6 +594,11 @@ edit(char *name, int ask_logical_size) break; case 'Q': case 'q': + if (map && map->changed) { + if (get_okay("Discard changes? [n/y]: ", 0) != 1) { + break; + } + } flush_to_newline(1); goto finis; break; @@ -648,20 +660,41 @@ finis: close_partition_map(map); } +#ifdef __m68k__ +void +do_update_dpme(partition_map *entry) +{ + int slice = 0; + if (!entry) return; + dpme_init_flags(entry->data); + entry->HFS_name = get_HFS_name(entry, &entry->HFS_kind); + if (istrncmp(entry->data->dpme_type, kUnixType, DPISTRLEN) == 0) { + printf("Available partition slices for %s:\n",entry->data->dpme_type); + printf(" a root partition\n"); + printf(" b swap partition\n"); + printf(" c do not set any bzb bits\n"); + printf(" g user partition\n"); + printf("Other lettered values will create user partitions\n"); + get_command("Select a slice for default bzb values: ",0,&slice); + } + bzb_init_slice((BZB *)entry->data->dpme_bzb,slice); + entry->the_map->changed = 1; +} +#endif void do_create_partition(partition_map_header *map, int get_type) { long base; long length; - char *name; - char *type_name; + char *name = 0; + char *type_name = 0; if (map == NULL) { bad_input("No partition map exists"); return; } - if (!rflag && map->writeable == 0) { + if (!rflag && map->writable == 0) { printf("The map is not writable.\n"); } // XXX add help feature (i.e. '?' in any argument routine prints help string) @@ -678,8 +711,12 @@ do_create_partition(partition_map_header *map, int get_type) } if (get_type == 0) { add_partition_to_map(name, kUnixType, base, length, map); +#if 0 /* this check is not found in linux fdisk-0.1 */ + if (map->blocks_in_map > MAX_LINUX_MAP) { + error(-1, "Map contains more than %d blocks - Linux may have trouble", MAX_LINUX_MAP); + } goto xit1; - +#endif } else if (get_string_argument("Type of partition: ", &type_name, 1) == 0) { bad_input("Bad type"); goto xit1; @@ -693,11 +730,21 @@ do_create_partition(partition_map_header *map, int get_type) goto xit2; } add_partition_to_map(name, type_name, base, length, map); +#if 0 /* this check is not found in linux fdisk-0.1 */ + if (map->blocks_in_map > MAX_LINUX_MAP) { + error(-1, "Map contains more than %d blocks - Linux may have trouble", MAX_LINUX_MAP); + } +#endif } +#ifdef __m68k__ + do_update_dpme(find_entry_by_base(base,map)); +#endif xit2: - free(type_name); + if (type_name) + free(type_name); xit1: - free(name); + if (name) + free(name); return; } @@ -762,17 +809,17 @@ void do_rename_partition(partition_map_header *map) { partition_map * entry; - long index; + long ix; char *name; if (map == NULL) { bad_input("No partition map exists"); return; } - if (!rflag && map->writeable == 0) { + if (!rflag && map->writable == 0) { printf("The map is not writable.\n"); } - if (get_number_argument("Partition number: ", &index, kDefault) == 0) { + if (get_number_argument("Partition number: ", &ix, kDefault) == 0) { bad_input("Bad partition number"); return; } @@ -782,7 +829,7 @@ do_rename_partition(partition_map_header *map) } // find partition and change it - entry = find_entry_by_disk_address(index, map); + entry = find_entry_by_disk_address(ix, map); if (entry == NULL) { printf("No such partition\n"); } else { @@ -798,7 +845,7 @@ void do_change_type(partition_map_header *map) { partition_map * entry; - long index; + long ix; char *type = NULL; if (map == NULL) { @@ -806,16 +853,16 @@ do_change_type(partition_map_header *map) return; } - if (!rflag && map->writeable == 0) { + if (!rflag && map->writable == 0) { printf("The map is not writable.\n"); } - if (get_number_argument("Partition number: ", &index, kDefault) == 0) { + if (get_number_argument("Partition number: ", &ix, kDefault) == 0) { bad_input("Bad partition number"); return; } - entry = find_entry_by_disk_address(index, map); + entry = find_entry_by_disk_address(ix, map); if (entry == NULL ) { printf("No such partition\n"); @@ -829,6 +876,9 @@ do_change_type(partition_map_header *map) } strncpy(entry->data->dpme_type, type, DPISTRLEN); +#ifdef __m68k__ + do_update_dpme(entry); +#endif map->changed = 1; out: @@ -842,22 +892,22 @@ void do_delete_partition(partition_map_header *map) { partition_map * cur; - long index; + long ix; if (map == NULL) { bad_input("No partition map exists"); return; } - if (!rflag && map->writeable == 0) { + if (!rflag && map->writable == 0) { printf("The map is not writable.\n"); } - if (get_number_argument("Partition number: ", &index, kDefault) == 0) { + if (get_number_argument("Partition number: ", &ix, kDefault) == 0) { bad_input("Bad partition number"); return; } // find partition and delete it - cur = find_entry_by_disk_address(index, map); + cur = find_entry_by_disk_address(ix, map); if (cur == NULL) { printf("No such partition\n"); } else { @@ -870,25 +920,25 @@ void do_reorder(partition_map_header *map) { long old_index; - long index; + long ix; if (map == NULL) { bad_input("No partition map exists"); return; } - if (!rflag && map->writeable == 0) { + if (!rflag && map->writable == 0) { printf("The map is not writable.\n"); } if (get_number_argument("Partition number: ", &old_index, kDefault) == 0) { bad_input("Bad partition number"); return; } - if (get_number_argument("New number: ", &index, kDefault) == 0) { + if (get_number_argument("New number: ", &ix, kDefault) == 0) { bad_input("Bad partition number"); return; } - move_entry_in_map(old_index, index, map); + move_entry_in_map(old_index, ix, map); } @@ -899,14 +949,19 @@ do_write_partition_map(partition_map_header *map) bad_input("No partition map exists"); return; } - if (map->changed == 0) { + if (map->changed == 0 && map->written == 0) { bad_input("The map has not been changed."); return; } - if (map->writeable == 0) { + if (map->writable == 0) { bad_input("The map is not writable."); return; } +#if 0 /* this check is not found in linux fdisk-0.1 */ + if (map->blocks_in_map > MAX_LINUX_MAP) { + error(-1, "Map contains more than %d blocks - Linux may have trouble", MAX_LINUX_MAP); + } +#endif printf("Writing the map destroys what was there before. "); if (get_okay("Is that okay? [n/y]: ", 0) != 1) { return; @@ -914,6 +969,9 @@ do_write_partition_map(partition_map_header *map) write_partition_map(map); + map->changed = 0; + map->written = 1; + // exit(0); } @@ -954,13 +1012,18 @@ do_expert(partition_map_header *map, char *name) printf(" v validate map\n"); printf(" e examine patch partition\n"); printf(" q return to main edit menu\n"); - printf(" Q quit without saving changes\n"); + printf(" Q quit editing\n"); break; case 'q': flush_to_newline(1); goto finis; break; case 'Q': + if (map->changed) { + if (get_okay("Discard changes? [n/y]: ", 0) != 1) { + break; + } + } quit = 1; goto finis; break; @@ -990,9 +1053,6 @@ do_expert(partition_map_header *map, char *name) do_examine_patch_partition(map); break; default: -#ifndef __OpenBSD__ - do_error: -#endif bad_input("No such command (%c)", command); break; } @@ -1010,7 +1070,7 @@ do_change_map_size(partition_map_header *map) bad_input("No partition map exists"); return; } - if (!rflag && map->writeable == 0) { + if (!rflag && map->writable == 0) { printf("The map is not writable.\n"); } if (get_number_argument("New size: ", &size, kDefault) == 0) { @@ -1030,6 +1090,7 @@ do_display_block(partition_map_header *map, char *alt_name) static unsigned char *display_block; static int display_g; int g; + static long next_number = -1; if (map != NULL) { name = 0; @@ -1058,7 +1119,7 @@ do_display_block(partition_map_header *map, char *alt_name) g = PBLOCK_SIZE; } } - if (get_number_argument("Block number: ", &number, kDefault) == 0) { + if (get_number_argument("Block number: ", &number, next_number) == 0) { bad_input("Bad block number"); goto xit; } @@ -1075,7 +1136,9 @@ do_display_block(partition_map_header *map, char *alt_name) display_g = g; } if (read_media(m, ((long long)number) * g, g, (char *)display_block) != 0) { + printf("block %ld -", number); dump_block((unsigned char*) display_block, g); + next_number = number + 1; } xit: diff --git a/sbin/pdisk/pdisk.h b/sbin/pdisk/pdisk.h index 29a745c0ce4..546ffe932f2 100644 --- a/sbin/pdisk/pdisk.h +++ b/sbin/pdisk/pdisk.h @@ -1,7 +1,7 @@ // // pdisk.h - general header for pdisk program // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* diff --git a/sbin/pdisk/util.c b/sbin/pdisk/util.c index 68fc272d8b8..be983546a03 100644 --- a/sbin/pdisk/util.c +++ b/sbin/pdisk/util.c @@ -1,7 +1,7 @@ /* * util.c - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* @@ -105,8 +105,8 @@ TrapAvailable(short theTrap) int istrncmp(const char *x, const char *y, long len) { - unsigned char *p = (unsigned char *)x; - unsigned char *q = (unsigned char *)y; + const unsigned char *p = (const unsigned char *)x; + const unsigned char *q = (const unsigned char *)y; while (len > 0) { if (tolower(*p) != tolower(*q)) { @@ -141,21 +141,21 @@ get_version_string(void) if (kVersionBugFix != 0) { if (kVersionStage == final) { if (asprintf(&dynamic_version, "%d.%d.%d", kVersionMajor, - kVersionMinor, kVersionBugFix) == -1) + kVersionMinor, kVersionBugFix) == -1) err(1, "asprintf"); } else { if (asprintf(&dynamic_version, "%d.%d.%d%c%d", kVersionMajor, - kVersionMinor, kVersionBugFix, stage, kVersionDelta) == -1) - err(1, "asprintf"); + kVersionMinor, kVersionBugFix, stage, kVersionDelta) == -1) + err(1, "asprintf"); } } else { if (kVersionStage == final) { if (asprintf(&dynamic_version, "%d.%d", kVersionMajor, - kVersionMinor) == -1) + kVersionMinor) == -1) err(1, "asprintf"); } else { if (asprintf(&dynamic_version, "%d.%d%c%d", kVersionMajor, - kVersionMinor, stage, kVersionDelta) == -1) + kVersionMinor, stage, kVersionDelta) == -1) err(1, "asprintf"); } } diff --git a/sbin/pdisk/util.h b/sbin/pdisk/util.h index 0a1ec52afb3..b0569f2b9a4 100644 --- a/sbin/pdisk/util.h +++ b/sbin/pdisk/util.h @@ -1,7 +1,7 @@ /* * util.h - * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* diff --git a/sbin/pdisk/validate.c b/sbin/pdisk/validate.c index 779d3296899..e25165f9408 100644 --- a/sbin/pdisk/validate.c +++ b/sbin/pdisk/validate.c @@ -1,7 +1,7 @@ // // validate.c - // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* @@ -300,7 +300,7 @@ print_range_list(range_list *list) { range_list *cur; int printed; - char *s; + const char *s = NULL; if (list == 0) { printf("Empty range list\n"); @@ -399,6 +399,7 @@ validate_map(partition_map_header *map) // XXX size & count match DeviceCapacity // XXX number of descriptors matches array size // XXX each descriptor wholly contained in a partition + // XXX the range below here is in physical blocks but the map is in logical blocks!!! add_range(&list, 1, b0->sbBlkCount-1, 0); /* subtract one since args are base & len */ check_map: diff --git a/sbin/pdisk/validate.h b/sbin/pdisk/validate.h index 550bbc4dfd0..3d65e084c49 100644 --- a/sbin/pdisk/validate.h +++ b/sbin/pdisk/validate.h @@ -1,7 +1,7 @@ // // validate.h - // -// Written by Eryk Vershen (eryk@apple.com) +// Written by Eryk Vershen // /* diff --git a/sbin/pdisk/version.h b/sbin/pdisk/version.h index dc49b376d46..73da0f217a8 100644 --- a/sbin/pdisk/version.h +++ b/sbin/pdisk/version.h @@ -1,7 +1,7 @@ /* * version.h - version number for pdisk program * - * Written by Eryk Vershen (eryk@apple.com) + * Written by Eryk Vershen */ /* @@ -47,17 +47,17 @@ * version will be represented by a larger number. */ -#define VERSION "0.7a3" -#define RELEASE_DATE "18 February 1998" +#define VERSION "0.8a2" +#define RELEASE_DATE "16 May 2000" #define kVersionMajor 0x00 /* ie. N has two BCD digits */ -#define kVersionMinor 0x7 /* ie. M has a single BCD digit */ +#define kVersionMinor 0x8 /* ie. M has a single BCD digit */ #define kVersionBugFix 0x0 /* ie. X has a single BCD digit */ #define kVersionStage alpha /* ie. y is one of the set - */ /* {development,alpha,beta,final} * also, release is a synonym for final */ -#define kVersionDelta 0x03 /* ie. Z has two BCD digits */ +#define kVersionDelta 0x02 /* ie. Z has two BCD digits */ /* |