summaryrefslogtreecommitdiff
path: root/sbin/pdisk/hfs_misc.c
diff options
context:
space:
mode:
authorMartin Reindl <martin@cvs.openbsd.org>2006-04-27 19:52:22 +0000
committerMartin Reindl <martin@cvs.openbsd.org>2006-04-27 19:52:22 +0000
commited27cd970afc6b5a1f13bcbcfa6e6f2c17383ea3 (patch)
tree1705907342ecd5f075b44fae6b75b82b0a5d413d /sbin/pdisk/hfs_misc.c
parente317d0527a2e9963eb4d77f7416c9714f02efcfd (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/hfs_misc.c')
-rw-r--r--sbin/pdisk/hfs_misc.c253
1 files changed, 253 insertions, 0 deletions
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);
+}