one less, 6 left.

This commit is contained in:
christos 2013-03-23 16:32:04 +00:00
parent a24c340b1b
commit 3e3be60bf3
46 changed files with 0 additions and 13519 deletions

1240
dist/pdisk/ATA_media.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
/*
* ATA_media.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __ATA_media__
#define __ATA_media__
#include "media.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
MEDIA ATA_FindDevice(long dRefNum);
MEDIA open_ata_as_media(long bus, long device);
MEDIA open_atapi_as_media(long bus, long device);
MEDIA_ITERATOR create_ata_iterator(void);
MEDIA open_linux_ata_as_media(long index);
char *linux_ata_name(long bus, long id);
#endif /* __ATA_media__ */

View File

@ -1,649 +0,0 @@
/*
* DoScsiCommand.c
*
* This is the common entry to the original and asynchronous SCSI Manager calls:
* if the asynchronous SCSI Manager is requested, it calls it. Otherwise, it
* calls the original SCSI Manager and executes Request Sense if necessary.
*
* This function returns "autosense" in the SCSI_Sense_Data area. This will
* be formatted in the senseMessage string.
*/
/*
* Copyright 1992, 1993, 1997, 1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "DoScsiCommand.h"
#include "util.h"
//
// Defines
//
#define kSCSICommandTimeout (5 * 1000L) /* Five seconds */
/*
* This is the maximum number of times we try to grab the SCSI Bus
*/
#define kMaxSCSIRetries 40 /* 10 seconds, 4 times/sec */
/*
* This test is TRUE if the SCSI bus status indicates "busy" (which is the case
* if either the BSY or SEL bit is set).
*/
#ifndef kScsiStatBSY
#define kScsiStatBSY (1 << 6)
#endif
#ifndef kScsiStatSEL
#define kScsiStatSEL (1 << 1)
#endif
#define ScsiBusBusy() ((SCSIStat() & (kScsiStatBSY | kScsiStatSEL)) != 0)
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
int gSCSIHiBusID;
SCSIExecIOPB *gSCSIExecIOPBPtr;
UInt32 gSCSIExecIOPBPtrLen;
//
// Forward declarations
//
UInt16 GetCommandLength(const SCSI_CommandPtr cmdPtr);
Boolean IsVirtualMemoryRunning(void);
OSErr OriginalSCSI(
DeviceIdent scsiDevice,
const SCSI_CommandPtr scsiCommand,
UInt8 scsiCommandLen,
Ptr dataBuffer,
ByteCount dataLength,
UInt32 scsiFlags,
ByteCount *actualTransferCount,
UInt8 *scsiStatusByte
);
OSErr DoOriginalSCSICommand(
DeviceIdent scsiDevice,
const SCSI_CommandPtr theSCSICommand,
uint16_t cmdBlockLength,
Ptr dataBuffer,
ByteCount dataLength,
UInt32 scsiFlags,
ByteCount *actualTransferCount,
SCSI_Sense_Data *sensePtr
);
//
// Routines
//
/*
* This returns TRUE if the command failed with "Illegal Request." We need this
* so we can ignore LogSense or ReadDefectData if the device doesn't support
* these functions.
*/
Boolean
IsIllegalRequest(
OSErr scsiStatus,
const SCSI_Sense_Data *senseDataPtr
)
{
Boolean result;
#define SENSE (*senseDataPtr)
result = FALSE;
if (scsiStatus == scsiNonZeroStatus
&& (SENSE.senseKey & kScsiSenseKeyMask) == kScsiSenseIllegalReq
&& SENSE.additionalSenseLength >= 4) {
switch ((SENSE.additionalSenseCode << 8) | SENSE.additionalSenseQualifier) {
case 0x0000:
case 0x2000:
case 0x2022: /* Obsolete */
result = TRUE;
break;
default:
break;
}
}
return (result);
#undef SENSE
}
/*
* This returns TRUE if the command failed with Device Not Ready (No Media Present)
*/
Boolean
IsNoMedia(
OSErr scsiStatus,
const SCSI_Sense_Data *senseDataPtr
)
{
Boolean result;
#define SENSE (*senseDataPtr)
result = FALSE;
if (scsiStatus == scsiNonZeroStatus
&& (SENSE.senseKey & kScsiSenseKeyMask) == kScsiSenseNotReady
&& SENSE.additionalSenseLength >= 4) {
switch ((SENSE.additionalSenseCode << 8) | SENSE.additionalSenseQualifier) {
case 0x0000:
case 0x3A00:
result = TRUE;
break;
default:
break;
}
}
return (result);
#undef SENSE
}
/*
* Do one SCSI Command. If the device returns Check Condition, issue Request Sense
* (original SCSI Manager only) and interpret the sense data. The original SCSI
* command status is in SCB.status. If it is statusErr or scsiNonZeroStatus,
* the sense data is in SCB.sense and the Request Sense status is in
* SCB.requestSenseStatus.
*
* If sensePtr[0] is non-zero, there is a message.
*/
OSErr
DoSCSICommand(
DeviceIdent scsiDevice,
ConstStr255Param currentAction,
const SCSI_CommandPtr callerSCSICommand,
Ptr dataBuffer,
ByteCount dataLength,
UInt32 scsiFlags,
ByteCount *actualTransferCount,
SCSI_Sense_Data *sensePtr,
StringPtr senseMessage
)
{
OSErr status;
SCSI_Command theSCSICommand;
uint16_t cmdBlockLength;
// SpinSpinner(&gCurrentInfoPtr->spinnerRecord);
// ShowProgressAction(currentAction);
/*
* Store the LUN information in the command block - this is needed
* for devices that only examine the command block for LUN values.
* (On SCSI-II, the asynchronous SCSI Manager also includes the
* LUN in the identify message).
*/
theSCSICommand = *callerSCSICommand;
theSCSICommand.scsi[1] &= ~0xE0;
theSCSICommand.scsi[1] |= (scsiDevice.LUN & 0x03) << 5;
cmdBlockLength = GetCommandLength(&theSCSICommand);
if (senseMessage != NULL)
senseMessage[0] = 0;
if (sensePtr != NULL)
sensePtr->errorCode = 0;
if (scsiDevice.bus == kOriginalSCSIBusAdaptor) {
status = DoOriginalSCSICommand(
scsiDevice,
&theSCSICommand,
cmdBlockLength,
dataBuffer,
dataLength,
scsiFlags,
actualTransferCount,
sensePtr
);
}
else {
clear_memory(gSCSIExecIOPBPtr, gSCSIExecIOPBPtrLen);
#define PB (*gSCSIExecIOPBPtr)
PB.scsiPBLength = gSCSIExecIOPBPtrLen;
PB.scsiFunctionCode = SCSIExecIO;
PB.scsiDevice = scsiDevice;
PB.scsiTimeout = kSCSICommandTimeout;
/*
* Fiddle the flags so they're the least disruptive possible.
*/
PB.scsiFlags = scsiFlags | (scsiSIMQNoFreeze | scsiDontDisconnect);
if (sensePtr != NULL) {
PB.scsiSensePtr = (UInt8 *) sensePtr;
PB.scsiSenseLength = sizeof *sensePtr;
}
BlockMoveData(&theSCSICommand, &PB.scsiCDB.cdbBytes[0], cmdBlockLength);
PB.scsiCDBLength = cmdBlockLength;
if (dataBuffer != NULL) {
PB.scsiDataPtr = (UInt8 *) dataBuffer;
PB.scsiDataLength = dataLength;
PB.scsiDataType = scsiDataBuffer;
PB.scsiTransferType = scsiTransferPolled;
}
status = SCSIAction((SCSI_PB *) &PB);
if (status == noErr)
status = PB.scsiResult;
if (status == scsiSelectTimeout)
status = scsiDeviceNotThere;
if (actualTransferCount != NULL) {
/*
* Make sure that the actual transfer count does not exceed
* the allocation count (some devices spit extra data at us!)
*/
*actualTransferCount = dataLength - PB.scsiDataResidual;
if (*actualTransferCount > dataLength)
*actualTransferCount = dataLength;
}
#undef PB
}
if (status == scsiNonZeroStatus
&& sensePtr != NULL
&& sensePtr->errorCode != 0
&& senseMessage != NULL) {
// FormatSenseMessage(sensePtr, senseMessage);
// ShowProgressAction(senseMessage);
}
return (status);
}
/*
* Do a command with autosense using the original SCSI manager.
*/
OSErr
DoOriginalSCSICommand(
DeviceIdent scsiDevice,
const SCSI_CommandPtr theSCSICommand,
uint16_t cmdBlockLength,
Ptr dataBuffer,
ByteCount dataLength,
UInt32 scsiFlags,
ByteCount *actualTransferCount,
SCSI_Sense_Data *sensePtr
)
{
OSErr status;
UInt8 scsiStatusByte;
SCSI_Command scsiStatusCommand;
status = OriginalSCSI(
scsiDevice,
theSCSICommand,
cmdBlockLength,
dataBuffer,
dataLength,
scsiFlags,
actualTransferCount,
&scsiStatusByte
);
if (status == scsiNonZeroStatus
&& scsiStatusByte == kScsiStatusCheckCondition
&& sensePtr != NULL) {
CLEAR(scsiStatusCommand);
CLEAR(*sensePtr);
scsiStatusCommand.scsi6.opcode = kScsiCmdRequestSense;
scsiStatusCommand.scsi[1] |= (scsiDevice.LUN & 0x03) << 5;
scsiStatusCommand.scsi6.len = sizeof *sensePtr;
status = OriginalSCSI(
scsiDevice,
&scsiStatusCommand,
sizeof scsiStatusCommand.scsi6,
(Ptr) sensePtr,
sizeof *sensePtr,
scsiDirectionIn,
NULL,
&scsiStatusByte
);
if (status != noErr && status != scsiDataRunError) {
#ifdef notdef
if (gDebugOnError && scsiStatusByte != kScsiStatusCheckCondition) {
Str255 work;
pstrcpy(work, "\pAutosense failed ");
AppendSigned(work, status);
AppendChar(work, ' ');
AppendHexLeadingZeros(work, scsiStatusByte, 2);
DebugStr(work);
}
#endif
sensePtr->errorCode = 0;
status = scsiAutosenseFailed;
}
else {
status = scsiNonZeroStatus;
}
}
return (status);
}
OSErr
OriginalSCSI(
DeviceIdent scsiDevice,
const SCSI_CommandPtr scsiCommand,
UInt8 scsiCommandLen,
Ptr dataBuffer,
ByteCount dataLength,
UInt32 scsiFlags,
ByteCount *actualTransferCount,
UInt8 *scsiStatusBytePtr
)
{
OSErr status; /* Final status */
OSErr completionStatus; /* Status from ScsiComplete */
short totalTries; /* Get/Select retries */
short getTries; /* Get retries */
short iCount; /* Bus free counter */
uint32_t watchdog; /* Timeout after this */
uint32_t myTransferCount; /* Gets TIB loop counter */
short scsiStatusByte; /* Gets SCSIComplete result */
short scsiMsgByte; /* Gets SCSIComplete result */
Boolean bufferHoldFlag;
/*
* The TIB has the following format:
* [0] scInc user buffer transferQuantum or transferSize
* [1] scAdd &theTransferCount 1
* [2] scLoop -> tib[0] transferSize / transferQuantum
* [3] scStop
* The intent of this is to return, in actualTransferCount, the number
* of times we cycled through the tib[] loop. This will be the actual
* transfer count if transferQuantum equals one, or the number of
* "blocks" if transferQuantum is the length of one sector.
*/
SCSIInstr tib[4]; /* Current TIB */
status = noErr;
bufferHoldFlag = FALSE;
scsiStatusByte = 0xFF;
scsiMsgByte = 0xFF;
myTransferCount = 0;
/*
* If there is a data transfer, setup the tib.
*/
if (dataBuffer != NULL) {
tib[0].scOpcode = scInc;
tib[0].scParam1 = (uint32_t) dataBuffer;
tib[0].scParam2 = 1;
tib[1].scOpcode = scAdd;
tib[1].scParam1 = (uint32_t) &myTransferCount;
tib[1].scParam2 = 1;
tib[2].scOpcode = scLoop;
tib[2].scParam1 = (-2 * sizeof (SCSIInstr));
tib[2].scParam2 = dataLength / tib[0].scParam2;
tib[3].scOpcode = scStop;
tib[3].scParam1 = 0;
tib[3].scParam2 = 0;
}
if (IsVirtualMemoryRunning() && dataBuffer != NULL) {
/*
* Lock down the user buffer, if any. In a real-world application
* or driver, this would be done before calling the SCSI interface.
*/
#ifdef notdef
FailOSErr(
HoldMemory(dataBuffer, dataLength),
"\pCan't lock data buffer in physical memory"
);
#else
HoldMemory(dataBuffer, dataLength);
#endif
bufferHoldFlag = TRUE;
}
/*
* Arbitrate for the scsi bus. This will fail if some other device is
* accessing the bus at this time (which is unlikely).
*
*** Do not set breakpoints or call any functions that may require device
*** I/O (such as display code that accesses font resources between
*** SCSIGet and SCSIComplete,
*
*/
for (totalTries = 0; totalTries < kMaxSCSIRetries; totalTries++) {
for (getTries = 0; getTries < 4; getTries++) {
/*
* Wait for the bus to go free.
*/
watchdog = TickCount() + 300; /* 5 second timeout */
while (ScsiBusBusy()) {
if (/*gStopNow || StopNow() ||*/ TickCount() > watchdog) {
status = scsiBusy;
goto exit;
}
}
/*
* The bus is free, try to grab it
*/
for (iCount = 0; iCount < 4; iCount++) {
if ((status = SCSIGet()) == noErr)
break;
}
if (status == noErr) {
break; /* Success: we have the bus */
}
/*
* The bus became busy again. Try to wait for it to go free.
*/
for (iCount = 0;
/*gStopNow == FALSE && StopNow() == FALSE &&*/ iCount < 100 && ScsiBusBusy();
iCount++)
;
} /* The getTries loop */
if (status != noErr) {
/*
* The SCSI Manager thinks the bus is not busy and not selected,
* but "someone" has set its internal semaphore that signals
* that the SCSI Manager itself is busy. The application will have
* to handle this problem. (We tried getTries * 4 times).
*/
status = scsiBusy;
goto exit;
}
/*
* We now own the SCSI bus. Try to select the device.
*/
if ((status = SCSISelect(scsiDevice.targetID)) != noErr) {
switch (status) {
/*
* We get scBadParmsErr if we try to arbitrate for the initiator.
*/
case scBadParmsErr: status = scsiTIDInvalid; break;
case scCommErr: status = scsiDeviceNotThere; break;
case scArbNBErr: status = scsiBusy; break;
case scSequenceErr: status = scsiRequestInvalid; break;
}
goto exit;
}
/*
* From this point on, we must exit through SCSIComplete() even if an
* error is detected. Send a command to the selected device. There are
* several failure modes, including an illegal command (such as a
* write to a read-only device). If the command failed because of
* "device busy", we will try it again.
*/
status = SCSICmd((Ptr) scsiCommand, scsiCommandLen);
if (status != noErr) {
switch (status) {
case scCommErr: status = scsiCommandTimeout; break;
case scPhaseErr: status = scsiSequenceFailed; break;
}
}
if (status == noErr && dataBuffer != NULL) {
/*
* This command requires a data transfer.
*/
if (scsiFlags == scsiDirectionOut) {
status = SCSIWrite((Ptr) tib);
} else {
status = SCSIRead((Ptr) tib);
}
switch (status) {
case scCommErr: status = scsiCommandTimeout; break;
case scBadParmsErr: status = scsiRequestInvalid; break;
case scPhaseErr: status = noErr; /* Don't care */ break;
case scCompareErr: /* Can't happen */ break;
}
}
/*
* SCSIComplete "runs" the bus-phase algorithm until the bitter end,
* returning the status and command-completion message bytes..
*/
completionStatus = SCSIComplete(
&scsiStatusByte,
&scsiMsgByte,
5 * 60L
);
if (status == noErr && completionStatus != noErr) {
switch (completionStatus) {
case scCommErr: status = scsiCommandTimeout; break;
case scPhaseErr: status = scsiSequenceFailed; break;
case scComplPhaseErr: status = scsiSequenceFailed; break;
}
}
if (completionStatus == noErr && scsiStatusByte == kScsiStatusBusy) {
/*
* ScsiComplete is happy. If the device is busy,
* pause for 1/4 second and try again.
*/
watchdog = TickCount() + 15;
while (TickCount() < watchdog)
;
continue; /* Do next totalTries attempt */
}
/*
* This is the normal exit (success) or final failure exit.
*/
break;
} /* totalTries loop */
exit:
if (bufferHoldFlag) {
(void) UnholdMemory(dataBuffer, dataLength);
}
/*
* Return the number of bytes transferred to the caller. If the caller
* supplied an actual count and the count is no greater than the maximum,
* ignore any phase errors.
*/
if (actualTransferCount != NULL) {
*actualTransferCount = myTransferCount;
if (*actualTransferCount > dataLength) {
*actualTransferCount = dataLength;
}
}
/*
* Also, there is a bug in the combination of System 7.0.1 and the 53C96
* that may cause the real SCSI Status Byte to be in the Message byte.
*/
if (scsiStatusByte == kScsiStatusGood
&& scsiMsgByte == kScsiStatusCheckCondition) {
scsiStatusByte = kScsiStatusCheckCondition;
}
if (status == noErr) {
switch (scsiStatusByte) {
case kScsiStatusGood: break;
case kScsiStatusBusy: status = scsiBusy; break;
case 0xFF: status = scsiProvideFail; break;
default: status = scsiNonZeroStatus; break;
}
}
if (status == noErr
&& (scsiFlags & scsiDirectionMask) != scsiDirectionNone
&& myTransferCount != dataLength) {
status = scsiDataRunError;
}
if (scsiStatusBytePtr != NULL) {
*scsiStatusBytePtr = scsiStatusByte;
}
return (status);
}
UInt16
GetCommandLength(
const SCSI_CommandPtr cmdPtr
)
{
uint16_t result;
/*
* Look at the "group code" in the command operation. Return zero
* error for the reserved (3, 4) and vendor-specific command (6, 7)
* command groups. Otherwise, set the command length from the group code
* value as specified in the SCSI-II spec.
*/
switch (cmdPtr->scsi6.opcode & 0xE0) {
case (0 << 5): result = 6; break;
case (1 << 5):
case (2 << 5): result = 10; break;
case (5 << 5): result = 12; break;
default: result = 0; break;
}
return (result);
}
Boolean
IsVirtualMemoryRunning(void)
{
OSErr status;
long response;
status = Gestalt(gestaltVMAttr, &response);
/*
* VM is active iff Gestalt succeeded and the response is appropriate.
*/
return (status == noErr && ((response & (1 << gestaltVMPresent)) != 0));
}
void
AllocatePB()
{
OSErr status;
SCSIBusInquiryPB busInquiryPB;
#define PB (busInquiryPB)
if (gSCSIExecIOPBPtr == NULL) {
CLEAR(PB);
PB.scsiPBLength = sizeof PB;
PB.scsiFunctionCode = SCSIBusInquiry;
PB.scsiDevice.bus = 0xFF; /* Get info about the XPT */
status = SCSIAction((SCSI_PB *) &PB);
if (status == noErr)
status = PB.scsiResult;
if (PB.scsiHiBusID == 0xFF) {
gSCSIHiBusID = -1;
} else {
gSCSIHiBusID = PB.scsiHiBusID;
}
gSCSIExecIOPBPtrLen = PB.scsiMaxIOpbSize;
if (gSCSIExecIOPBPtrLen != 0)
gSCSIExecIOPBPtr = (SCSIExecIOPB *) NewPtrClear(gSCSIExecIOPBPtrLen);
}
#undef PB
}

View File

@ -1,130 +0,0 @@
/*
* DoScsiCommand.h -
*
* Modifed by Eryk Vershen
* from an original by Martin Minow
*/
/*
* Copyright 1993-1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __DoScsiCommand__
#define __DoScsiCommand__
#include <SCSI.h>
#include "MacSCSICommand.h"
/*
* Defines
*/
#ifndef EXTERN
#define EXTERN extern
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define kOriginalSCSIBusAdaptor (0xFF)
#define SameSCSIDevice(a, b) ((*((UInt32 *) &a)) == (*((UInt32 *) &b)))
/*
* Cheap 'n dirty memory clear routine.
*/
#define CLEAR(dst) clear_memory((void *) &dst, sizeof dst)
/*
* Types
*/
#if !defined(__NewTypesDefined__)
#define __NewTypesDefined__
typedef int8_t SInt8;
typedef int16_t SInt16;
typedef int32_t SInt32;
typedef uint8_t UInt8;
typedef uint16_t UInt16;
typedef uint32_t UInt32;
typedef uint32_t ItemCount;
typedef uint32_t ByteCount;
#endif
/*
* Global Constants
*/
enum {
bit0 = (1 << 0),
bit1 = (1 << 1),
bit2 = (1 << 2),
bit3 = (1 << 3),
bit4 = (1 << 4),
bit5 = (1 << 5),
bit6 = (1 << 6),
bit7 = (1 << 7)
};
/*
* Global Variables
*/
EXTERN int gSCSIHiBusID;
EXTERN SCSIExecIOPB *gSCSIExecIOPBPtr;
EXTERN UInt32 gSCSIExecIOPBPtrLen;
/*
* Forward declarations
*/
void AllocatePB();
Boolean IsIllegalRequest(OSErr scsiStatus, const SCSI_Sense_Data *senseDataPtr);
Boolean IsNoMedia(OSErr scsiStatus, const SCSI_Sense_Data *senseDataPtr);
/*
* All SCSI Commands come here.
* if scsiDevice.busID == kOriginalSCSIBusAdaptor, IM-IV SCSI will be called.
* scsiFlags should be scsiDirectionNone, scsiDirectionIn, or scsiDirectionOut
* actualTransferCount may be NULL if you don't care.
* Both old and new SCSI return SCSI Manager 4.3 errors.
*
* DoSCSICommand throws really serious errors, but returns SCSI errors such
* as dataRunError and scsiDeviceNotThere.
*/
OSErr DoSCSICommand(
DeviceIdent scsiDevice,
ConstStr255Param currentAction,
const SCSI_CommandPtr callerSCSICommand,
Ptr dataBuffer,
ByteCount dataLength,
UInt32 scsiFlags,
ByteCount *actualTransferCount,
SCSI_Sense_Data *sensePtr,
StringPtr senseMessage
);
#endif /* __DoScsiCommand__ */

68
dist/pdisk/HISTORY vendored
View File

@ -1,68 +0,0 @@
A short history of pdisk
------------------------
11/1996 - Spent a week to create a minimal partitioner
that reads maps, initializes maps, can add and delete partitions.
Released as version 0.1 to MkLinux team
12/1996 - Spent three weeks adding more commands, writing
documentation, fixing bugs and making it prettier.
Released version 0.2 to Gilbert
Fixed a few more bugs.
Released as version 0.3
01/1997 - Spent two weeks creating MacOS version and fixing
a few more bugs.
Released as version 0.4
03/1997 - Spent an evening adding device driver deletion
and a couple of flags to private version.
07/1997 - Some one else ported it to Rhapsody.
Spent a couple of weeks adding variable block
size support to Rhapsody version.
Took the time to stop using rich man's source code control
(multiple copies) in linux/mac and put sources under RCS.
Folded linux/mac version changes into Rhapsody and
brought some of the Rhapsody changes into linux/mac
09/1997 - Fixed bugs in MacOS version of variable block size.
Added new dump routines.
Added case-insensitive string matching.
Released one copy of version 0.5a3 source internally.
10/1997 - Wrote MacOS documentation
Minor fixes
11/1997 - A few more fixes
Released as version 0.5
12/1997 - Integrated new media abstraction
(includes support for ATA and ATAPI on MacOS)
01/1998 - Added media iterators (to fix grunge in dump.c)
Added os_reload_media (to get rid of ioctl's in write_partition_map)
Added rename partition command ('n' in edit mode)
Added /dev/hd? and /dev/scd? to MkLinux list all disks
Added 68k target to CW project
02/1998 - Released version 0.6
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.
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 confimation 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 when many devices
Change so WORM devices are considered 'CDs'
05/2000 - Released version 0.8

View File

@ -1,420 +0,0 @@
/*
File: MacSCSICommand.h
Contains: SCSI specific definitions.
Written by: Martin Minow
*/
/*
* Copyright 1995, 1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Scsi-specific definitions.
*/
#ifndef __MacSCSICommand__
#define __MacSCSICommand__
/*
* The 6-byte commands are used for most simple
* I/O requests.
*/
struct SCSI_6_Byte_Command { /* Six-byte command */
uint8_t opcode; /* 0 */
uint8_t lbn3; /* 1 lbn in low 5 */
uint8_t lbn2; /* 2 */
uint8_t lbn1; /* 3 */
uint8_t len; /* 4 */
uint8_t ctrl; /* 5 */
};
typedef struct SCSI_6_Byte_Command SCSI_6_Byte_Command;
struct SCSI_10_Byte_Command { /* Ten-byte command */
uint8_t opcode; /* 0 */
uint8_t lun; /* 1 */
uint8_t lbn4; /* 2 */
uint8_t lbn3; /* 3 */
uint8_t lbn2; /* 4 */
uint8_t lbn1; /* 5 */
uint8_t pad; /* 6 */
uint8_t len2; /* 7 */
uint8_t len1; /* 8 */
uint8_t ctrl; /* 9 */
};
typedef struct SCSI_10_Byte_Command SCSI_10_Byte_Command;
struct SCSI_12_Byte_Command { /* Twelve-byte command */
uint8_t opcode; /* 0 */
uint8_t lun; /* 1 */
uint8_t lbn4; /* 2 */
uint8_t lbn3; /* 3 */
uint8_t lbn2; /* 4 */
uint8_t lbn1; /* 5 */
uint8_t len4; /* 6 */
uint8_t len3; /* 7 */
uint8_t len2; /* 8 */
uint8_t len1; /* 9 */
uint8_t pad; /* 10 */
uint8_t ctrl; /* 11 */
};
typedef struct SCSI_12_Byte_Command SCSI_12_Byte_Command;
/*
* This union defines all scsi commands.
*/
union SCSI_Command {
SCSI_6_Byte_Command scsi6;
SCSI_10_Byte_Command scsi10;
SCSI_12_Byte_Command scsi12;
uint8_t scsi[12];
};
typedef union SCSI_Command SCSI_Command, *SCSI_CommandPtr;
/*
* Returned by a read-capacity command.
*/
struct SCSI_Capacity_Data {
uint8_t lbn4; /* Number */
uint8_t lbn3; /* of */
uint8_t lbn2; /* logical */
uint8_t lbn1; /* blocks */
uint8_t len4; /* Length */
uint8_t len3; /* of each */
uint8_t len2; /* logical block */
uint8_t len1; /* in bytes */
};
typedef struct SCSI_Capacity_Data SCSI_Capacity_Data;
struct SCSI_Inquiry_Data { /* Inquiry returns this */
uint8_t devType; /* 0 Device type, */
uint8_t devTypeMod; /* 1 Device type modifier */
uint8_t version; /* 2 ISO/ECMA/ANSI version */
uint8_t format; /* 3 Response data format */
uint8_t length; /* 4 Additional Length */
uint8_t reserved5; /* 5 Reserved */
uint8_t reserved6; /* 6 Reserved */
uint8_t flags; /* 7 Capability flags */
uint8_t vendor[8]; /* 8-15 Vendor-specific */
uint8_t product[16]; /* 16-31 Product id */
uint8_t revision[4]; /* 32-35 Product revision */
uint8_t vendorSpecific[20]; /* 36-55 Vendor stuff */
uint8_t moreReserved[40]; /* 56-95 Reserved */
};
typedef struct SCSI_Inquiry_Data SCSI_Inquiry_Data;
/*
* This bit may be set in SCSI_Inquiry_Data.devTypeMod
*/
enum {
kScsiInquiryRMB = 0x80 /* Removable medium if set */
};
/*
* These bits may be set in SCSI_Inquiry_Data.flags
*/
enum {
kScsiInquiryRelAdr = 0x80, /* Has relative addressing */
kScsiInquiryWBus32 = 0x40, /* Wide (32-bit) transfers */
kScsiInquiryWBus16 = 0x20, /* Wide (16-bit) transfers */
kScsiInquirySync = 0x10, /* Synchronous transfers */
kScsiInquiryLinked = 0x08, /* Linked commands ok */
kScsiInquiryReserved = 0x04,
kScsiInquiryCmdQue = 0x02, /* Tagged cmd queuing ok */
kScsiInquirySftRe = 0x01 /* Soft reset alternative */
};
/*
* These bits may be set in SCSI_Inquiry_Data.devType
*/
enum {
kScsiDevTypeDirect = 0,
kScsiDevTypeSequential,
kScsiDevTypePrinter,
kScsiDevTypeProcessor,
kScsiDevTypeWorm, /* Write-once, read mult */
kScsiDevTypeCDROM,
kScsiDevTypeScanner,
kScsiDevTypeOptical,
kScsiDevTypeChanger,
kScsiDevTypeComm,
kScsiDevTypeGraphicArts0A,
kScsiDevTypeGraphicArts0B,
kScsiDevTypeFirstReserved, /* Reserved sequence start */
kScsiDevTypeUnknownOrMissing = 0x1F,
kScsiDevTypeMask = 0x1F
};
/*
* These are device type qualifiers. We need them to distinguish between "unknown"
* and "missing" devices.
*/
enum {
kScsiDevTypeQualifierConnected = 0x00, /* Exists and is connected */
kScsiDevTypeQualifierNotConnected = 0x20, /* Logical unit exists */
kScsiDevTypeQualifierReserved = 0x40,
kScsiDevTypeQualifierMissing = 0x60, /* No such logical unit */
kScsiDevTypeQualifierVendorSpecific = 0x80, /* Other bits are unspecified */
kScsiDevTypeQualifierMask = 0xE0
};
#define kScsiDevTypeMissing \
(kScsiDevTypeUnknownOrMissing | kScsiDevTypeQualifierMissing)
/*
* This is the data that is returned after a GetExtendedStatus
* request. The errorCode gives a general indication of the error,
* which may be qualified by the additionalSenseCode and
* additionalSenseQualifier fields. These may be device (vendor)
* specific values, however. The info[] field contains additional
* information. For a media error, it contains the failing
* logical block number (most-significant byte first).
*/
struct SCSI_Sense_Data { /* Request Sense result */
uint8_t errorCode; /* 0 Class code, valid lbn */
uint8_t segmentNumber; /* 1 Segment number */
uint8_t senseKey; /* 2 Sense key and flags */
uint8_t info[4];
uint8_t additionalSenseLength;
uint8_t reservedForCopy[4];
uint8_t additionalSenseCode;
uint8_t additionalSenseQualifier;
uint8_t fruCode; /* Field replacable unit code */
uint8_t senseKeySpecific[2];
uint8_t additional[101];
};
typedef struct SCSI_Sense_Data SCSI_Sense_Data;
/*
* The high-bit of errorCode signals whether there is a logical
* block. The low value signals whether there is a valid sense
*/
#define kScsiSenseHasLBN 0x80 /* Logical block number set */
#define kScsiSenseInfoValid 0x70 /* Is sense key valid? */
#define kScsiSenseInfoMask 0x70 /* Mask for sense info */
/*
* These bits may be set in the sense key
*/
#define kScsiSenseKeyMask 0x0F
#define kScsiSenseILI 0x20 /* Illegal logical Length */
#define kScsiSenseEOM 0x40 /* End of media */
#define kScsiSenseFileMark 0x80 /* End of file mark */
/*
* SCSI sense codes. (Returned after request sense).
*/
#define kScsiSenseNone 0x00 /* No error */
#define kScsiSenseRecoveredErr 0x01 /* Warning */
#define kScsiSenseNotReady 0x02 /* Device not ready */
#define kScsiSenseMediumErr 0x03 /* Device medium error */
#define kScsiSenseHardwareErr 0x04 /* Device hardware error */
#define kScsiSenseIllegalReq 0x05 /* Illegal request for dev. */
#define kScsiSenseUnitAtn 0x06 /* Unit attention (not err) */
#define kScsiSenseDataProtect 0x07 /* Data protection */
#define kScsiSenseBlankCheck 0x08 /* Tape-specific error */
#define kScsiSenseVendorSpecific 0x09 /* Vendor-specific error */
#define kScsiSenseCopyAborted 0x0a /* Copy request cancelled */
#define kScsiSenseAbortedCmd 0x0b /* Initiator aborted cmd. */
#define kScsiSenseEqual 0x0c /* Comparison equal */
#define kScsiSenseVolumeOverflow 0x0d /* Write past end mark */
#define kScsiSenseMiscompare 0x0e /* Comparison failed */
#define kScsiSenseCurrentErr 0x70
#define kScsiSenseDeferredErr 0x71
/*
* Mode sense parameter header
*/
struct SCSI_ModeParamHeader {
uint8_t modeDataLength;
uint8_t mediumType;
uint8_t deviceSpecific;
uint8_t blockDescriptorLength;
};
typedef struct SCSI_ModeParamHeader SCSI_ModeParamHeader;
struct SCSI_ModeParamBlockDescriptor {
uint8_t densityCode;
uint8_t numberOfBlocks[3];
uint8_t reserved;
uint8_t blockLength[3];
};
typedef struct SCSI_ModeParamBlockDescriptor SCSI_ModeParamBlockDescriptor;
union SCSI_ModeParamPage {
uint8_t data[1];
struct {
uint8_t code;
uint8_t length;
} page;
};
typedef union SCSI_ModeParamPage SCSI_ModeParamPage;
/*
* LogSense parameter header
*/
struct SCSI_LogSenseParamHeader {
uint8_t pageCode;
uint8_t reserved;
uint8_t pageLength[2];
};
typedef struct SCSI_LogSenseParamHeader SCSI_LogSenseParamHeader;
/*
* Log parameter pages are variable-length with a fixed length header.
*/
union SCSI_LogSenseParamPage {
uint8_t data[1];
struct {
uint8_t parameterCode[2];
uint8_t flags;
uint8_t parameterLength;
} page;
};
typedef union SCSI_LogSenseParamPage SCSI_LogSenseParamPage;
/*
* SCSI command status (from status phase)
*/
#define kScsiStatusGood 0x00 /* Normal completion */
#define kScsiStatusCheckCondition 0x02 /* Need GetExtendedStatus */
#define kScsiStatusConditionMet 0x04
#define kScsiStatusBusy 0x08 /* Device busy (self-test?) */
#define kScsiStatusIntermediate 0x10 /* Intermediate status */
#define kScsiStatusResConflict 0x18 /* Reservation conflict */
#define kScsiStatusQueueFull 0x28 /* Target can't do command */
#define kScsiStatusReservedMask 0x3e /* Vendor specific? */
/*
* SCSI command codes. Commands defined as ...6, ...10, ...12, are
* six-byte, ten-byte, and twelve-byte variants of the indicated command.
*/
/*
* These commands are supported for all devices.
*/
#define kScsiCmdChangeDefinition 0x40
#define kScsiCmdCompare 0x39
#define kScsiCmdCopy 0x18
#define kScsiCmdCopyAndVerify 0x3a
#define kScsiCmdInquiry 0x12
#define kScsiCmdLogSelect 0x4c
#define kScsiCmdLogSense 0x4d
#define kScsiCmdModeSelect10 0x55
#define kScsiCmdModeSelect6 0x15
#define kScsiCmdModeSense10 0x5a
#define kScsiCmdModeSense6 0x1a
#define kScsiCmdReadBuffer 0x3c
#define kScsiCmdRecvDiagResult 0x1c
#define kScsiCmdRequestSense 0x03
#define kScsiCmdSendDiagnostic 0x1d
#define kScsiCmdTestUnitReady 0x00
#define kScsiCmdWriteBuffer 0x3b
/*
* These commands are supported by direct-access devices only.
*/
#define kScsiCmdFormatUnit 0x04
#define kSCSICmdCopy 0x18
#define kSCSICmdCopyAndVerify 0x3a
#define kScsiCmdLockUnlockCache 0x36
#define kScsiCmdPrefetch 0x34
#define kScsiCmdPreventAllowRemoval 0x1e
#define kScsiCmdRead6 0x08
#define kScsiCmdRead10 0x28
#define kScsiCmdReadCapacity 0x25
#define kScsiCmdReadDefectData 0x37
#define kScsiCmdReadLong 0x3e
#define kScsiCmdReassignBlocks 0x07
#define kScsiCmdRelease 0x17
#define kScsiCmdReserve 0x16
#define kScsiCmdRezeroUnit 0x01
#define kScsiCmdSearchDataEql 0x31
#define kScsiCmdSearchDataHigh 0x30
#define kScsiCmdSearchDataLow 0x32
#define kScsiCmdSeek6 0x0b
#define kScsiCmdSeek10 0x2b
#define kScsiCmdSetLimits 0x33
#define kScsiCmdStartStopUnit 0x1b
#define kScsiCmdSynchronizeCache 0x35
#define kScsiCmdVerify 0x2f
#define kScsiCmdWrite6 0x0a
#define kScsiCmdWrite10 0x2a
#define kScsiCmdWriteAndVerify 0x2e
#define kScsiCmdWriteLong 0x3f
#define kScsiCmdWriteSame 0x41
/*
* These commands are supported by sequential devices.
*/
#define kScsiCmdRewind 0x01
#define kScsiCmdWriteFilemarks 0x10
#define kScsiCmdSpace 0x11
#define kScsiCmdLoadUnload 0x1B
/*
* ANSI SCSI-II for CD-ROM devices.
*/
#define kScsiCmdReadCDTableOfContents 0x43
/*
* Message codes (for Msg In and Msg Out phases).
*/
#define kScsiMsgAbort 0x06
#define kScsiMsgAbortTag 0x0d
#define kScsiMsgBusDeviceReset 0x0c
#define kScsiMsgClearQueue 0x0e
#define kScsiMsgCmdComplete 0x00
#define kScsiMsgDisconnect 0x04
#define kScsiMsgIdentify 0x80
#define kScsiMsgIgnoreWideResdue 0x23
#define kScsiMsgInitiateRecovery 0x0f
#define kScsiMsgInitiatorDetectedErr 0x05
#define kScsiMsgLinkedCmdComplete 0x0a
#define kScsiMsgLinkedCmdCompleteFlag 0x0b
#define kScsiMsgParityErr 0x09
#define kScsiMsgRejectMsg 0x07
#define kScsiMsgModifyDataPtr 0x00 /* Extended msg */
#define kScsiMsgNop 0x08
#define kScsiMsgHeadOfQueueTag 0x21 /* Two byte msg */
#define kScsiMsgOrderedQueueTag 0x22 /* Two byte msg */
#define kScsiMsgSimpleQueueTag 0x20 /* Two byte msg */
#define kScsiMsgReleaseRecovery 0x10
#define kScsiMsgRestorePointers 0x03
#define kScsiMsgSaveDataPointers 0x02
#define kScsiMsgSyncXferReq 0x01 /* Extended msg */
#define kScsiMsgWideDataXferReq 0x03 /* Extended msg */
#define kScsiMsgTerminateIOP 0x11
#define kScsiMsgExtended 0x01
#define kScsiMsgEnableDisconnectMask 0x40
#define kScsiMsgTwoByte 0x20
#define kScsiMsgTwoByteMin 0x20
#define kScsiMsgTwoByteMax 0x2f
/*
* Default timeout times for SCSI commands (times are in Msec).
*/
#define kScsiNormalCompletionTime (500L) /* 1/2 second */
/*
* Dratted DAT tape.
*/
#define kScsiDATCompletionTime (60L * 1000L); /* One minute */
/*
* Yes, we do allow 90 seconds for spin-up of those dratted tape drives.
*/
#define kScsiSpinUpCompletionTime (90L * 1000L)
#endif /* __MacSCSICommand__ */

147
dist/pdisk/README vendored
View File

@ -1,147 +0,0 @@
Product name: pdisk
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 Linux.
A MacOS version exists for "standalone" use.
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 confimation 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 when 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.
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
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appears in all copies and
that both the copyright notice and this permission notice appear in
supporting documentation.
APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
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.
Other info:
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 "Technote 1189: The Monster Disk Drive Technote". This release is not
completely in sync with that technote. Maybe next time.
Building the macintosh application
----------------------------------
I have only built this under Code Warrior Pro. The project file is included.
Thanks to Martin Minow for the SCSI support code.
Some notes on the apple partitioning
------------------------------------
The apple disk partitioning scheme was developed in 1986. It attempted to
be forward thinking as it was intended to handle drives of sizes up to several
hundred megabytes. There was a design document, but like most such documents
it was neither complete nor unambiguous.
While the original intent was to handle various block sizes, in practice
most devices use a partitioning block size of 512 bytes.
Since the various address fields are 32 bits unsigned this means the format
can handle disks up to 2 Terabytes in size. (32bits + 9 bits = 41 bits)
Because the format was designed around SCSI, there is no knowledge of
cylinders or heads, all block address are in absolute sector form.
A correct map should describe every block on the disk except for block zero.
An aside on CDROMs. Most old apple CDROMs have incorrect data in block zero.
Since the HFS file-system could only handle 512 byte blocks, apple drives had
a special mode where they would do deblocking (i.e. converting 2k blocks
into four 512byte blocks and accepting 512byte block addresses.) The partition
maps laid down on these disks are for the deblocked form. In many cases the
partition maps they contain have only the minimum number of fields correct.
At least one CDROM I have seen doesn't even contain a partition map at all,
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 wierd 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
for something that was called the bzb (block zero block - don't ask me why).
This structure evolved over the course of A/UX. I have recapitulated this
in the dpme.h header file.
Making a disk with Apple & Intel partitioning
---------------------------------------------
Don't cringe. I know it is an awful hack, but sometimes...
While I don't recommend doing this, it can be useful.
The procedure below is what we did.
The intel map can contain NO MORE THAN FOUR PRIMARY PARTITIONS.
You can't have any extended or logical partitions. (Well, you might get it
to work but I wouldn't want to try it.) The disk will NOT BE INTEL BOOTABLE.
1) Use pdisk to initialize an apple partition map. Don't add any partitions
yet, just write the map out and quit.
2) Use fdisk to create the primary partitions. Go into the expert 'x' menu
in fdisk and print out the table with the sector addresses. Write the
start and lengths down some where. Write the table out.
3) Use pdisk again. Shrink the partition map down, if necessary, so it
does not overlap any intel partition. Create an apple partition for each
intel partition using the start and length value you got from fdisk.
Write out the map and quit.
At present file systems are not compatible between Linux & MkLinux, but you
can tar stuff into these partitions and tar them out on another machine.
Good luck,
-eryk vershen
software mechanic
eryk@cfcl.com

1109
dist/pdisk/SCSI_media.c vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,65 +0,0 @@
/*
* SCSI_media.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __SCSI_media__
#define __SCSI_media__
#include "media.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
MEDIA SCSI_FindDevice(long dRefNum);
MEDIA open_old_scsi_as_media(long device);
MEDIA open_scsi_as_media(long bus, long device);
MEDIA_ITERATOR create_scsi_iterator(void);
MEDIA open_linux_scsi_as_media(long index, int is_cdrom);
char *linux_scsi_name(long bus, long id);
char *linux_old_scsi_name(long id);
#endif /* __SCSI_media__ */

102
dist/pdisk/bitfield.c vendored
View File

@ -1,102 +0,0 @@
//
// bitfield.c - extract and set bit fields
//
// Written by Eryk Vershen
//
// See comments in bitfield.h
//
/*
* Copyright 1996, 1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdint.h>
#include "bitfield.h"
//
// Defines
//
//
// Types
//
//
// Global Constants
//
const uint32_t masks[] = {
0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,
0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,
0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,
0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF
};
//
// Global Variables
//
//
// Forward declarations
//
//
// Routines
//
uint32_t
bitfield_set(uint32_t *bf, int base, int length, uint32_t value)
{
uint32_t t;
uint32_t m;
int s;
// compute shift & mask, coerce value to correct number of bits,
// zap the old bits and stuff the new value
// return the masked value in case someone wants it.
s = (base + 1) - length;
m = masks[length];
t = value & m;
*bf = (*bf & ~(m << s)) | (t << s);
return t;
}
uint32_t
bitfield_get(uint32_t bf, int base, int length)
{
uint32_t m;
int s;
// compute shift & mask
// return the correct number of bits (shifted to low end)
s = (base + 1) - length;
m = masks[length];
return ((bf >> s) & m);
}

73
dist/pdisk/bitfield.h vendored
View File

@ -1,73 +0,0 @@
//
// bitfield.h - extract and set bit fields
//
// Written by Eryk Vershen
//
// Bitfields are not particularly transportable between big and little
// endian machines. Big endian machines lay out bitfields starting
// from the most significant bit of the (one, two or four byte) number,
// whereas little endian machines lay out bitfields starting from the
// least signifcant bit.
//
// These routines were written to support some bitfields in a disk
// data structure (partition map) whose original definition was on
// a big-endian machine.
//
// They only work on 32-bit values because I didn't need 16-bit support.
// The bits in the long word are numbered from 0 (least significant) to
// 31 (most significant).
//
/*
* Copyright 1996,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __bitfield__
#define __bitfield__
//
// Defines
//
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
uint32_t bitfield_set(uint32_t *bf, int base, int length, uint32_t value);
uint32_t bitfield_get(uint32_t bf, int base, int length);
#endif /* __bitfield__ */

206
dist/pdisk/convert.c vendored
View File

@ -1,206 +0,0 @@
//
// convert.c - Little-endian conversion
//
// Written by Eryk Vershen
//
// See comments in convert.h
//
/*
* Copyright 1996,1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifdef __linux__
#include <endian.h>
#elif __NetBSD__
#include <machine/endian.h>
#else
#define LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321
#define BYTE_ORDER 4321
//#define BYTE_ORDER 1234
#endif
#include "convert.h"
//
// Defines
//
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
void reverse2(uint8_t *bytes);
void reverse4(uint8_t *bytes);
//
// Routines
//
int
convert_dpme(DPME *data, int to_cpu_form)
{
#if BYTE_ORDER == LITTLE_ENDIAN
// Since we will toss the block if the signature doesn't match
// we don't need to check the signature down here.
reverse2((uint8_t *)&data->dpme_signature);
reverse2((uint8_t *)&data->dpme_reserved_1);
reverse4((uint8_t *)&data->dpme_map_entries);
reverse4((uint8_t *)&data->dpme_pblock_start);
reverse4((uint8_t *)&data->dpme_pblocks);
reverse4((uint8_t *)&data->dpme_lblock_start);
reverse4((uint8_t *)&data->dpme_lblocks);
reverse4((uint8_t *)&data->dpme_flags);
reverse4((uint8_t *)&data->dpme_boot_block);
reverse4((uint8_t *)&data->dpme_boot_bytes);
reverse4((uint8_t *)&data->dpme_load_addr);
reverse4((uint8_t *)&data->dpme_load_addr_2);
reverse4((uint8_t *)&data->dpme_goto_addr);
reverse4((uint8_t *)&data->dpme_goto_addr_2);
reverse4((uint8_t *)&data->dpme_checksum);
convert_bzb((BZB *)data->dpme_bzb, to_cpu_form);
#endif
return 0;
}
#if BYTE_ORDER == LITTLE_ENDIAN
int
convert_bzb(BZB *data, int to_cpu_form)
{
// Since the data here varies according to the type of partition we
// do not want to convert willy-nilly. We use the flag to determine
// whether to check for the signature before or after we flip the bytes.
if (to_cpu_form) {
reverse4((uint8_t *)&data->bzb_magic);
if (data->bzb_magic != BZBMAGIC) {
reverse4((uint8_t *)&data->bzb_magic);
if (data->bzb_magic != BZBMAGIC) {
return 0;
}
}
} else {
if (data->bzb_magic != BZBMAGIC) {
return 0;
}
reverse4((uint8_t *)&data->bzb_magic);
}
reverse2((uint8_t *)&data->bzb_inode);
reverse4((uint8_t *)&data->bzb_flags);
reverse4((uint8_t *)&data->bzb_tmade);
reverse4((uint8_t *)&data->bzb_tmount);
reverse4((uint8_t *)&data->bzb_tumount);
return 0;
}
#endif
int
convert_block0(Block0 *data, int to_cpu_form)
{
#if BYTE_ORDER == LITTLE_ENDIAN
DDMap *m;
uint16_t count;
int i;
// Since this data is optional we do not want to convert willy-nilly.
// We use the flag to determine whether to check for the signature
// before or after we flip the bytes and to determine which form of
// the count to use.
if (to_cpu_form) {
reverse2((uint8_t *)&data->sbSig);
if (data->sbSig != BLOCK0_SIGNATURE) {
reverse2((uint8_t *)&data->sbSig);
if (data->sbSig != BLOCK0_SIGNATURE) {
return 0;
}
}
} else {
if (data->sbSig != BLOCK0_SIGNATURE) {
return 0;
}
reverse2((uint8_t *)&data->sbSig);
}
reverse2((uint8_t *)&data->sbBlkSize);
reverse4((uint8_t *)&data->sbBlkCount);
reverse2((uint8_t *)&data->sbDevType);
reverse2((uint8_t *)&data->sbDevId);
reverse4((uint8_t *)&data->sbData);
if (to_cpu_form) {
reverse2((uint8_t *)&data->sbDrvrCount);
count = data->sbDrvrCount;
} else {
count = data->sbDrvrCount;
reverse2((uint8_t *)&data->sbDrvrCount);
}
if (count > 0) {
m = (DDMap *) data->sbMap;
for (i = 0; i < count; i++) {
reverse4((uint8_t *)&m[i].ddBlock);
reverse2((uint8_t *)&m[i].ddSize);
reverse2((uint8_t *)&m[i].ddType);
}
}
#endif
return 0;
}
void
reverse2(uint8_t *bytes)
{
uint8_t t;
t = *bytes;
*bytes = bytes[1];
bytes[1] = t;
}
void
reverse4(uint8_t *bytes)
{
uint8_t t;
t = *bytes;
*bytes = bytes[3];
bytes[3] = t;
t = bytes[1];
bytes[1] = bytes[2];
bytes[2] = t;
}

65
dist/pdisk/convert.h vendored
View File

@ -1,65 +0,0 @@
//
// convert.h - Little-endian conversion
//
// Written by Eryk Vershen
//
// The approach taken to conversion is fairly simply.
// Keep the in-memory copy in the machine's normal form and
// Convert as necessary when reading and writing.
//
/*
* Copyright 1996,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __convert__
#define __convert__
#include "dpme.h"
//
// Defines
//
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
int convert_block0(Block0 *data, int to_cpu_form);
int convert_bzb(BZB *data, int to_cpu_form);
int convert_dpme(DPME *data, int to_cpu_form);
#endif /* __convert__ */

203
dist/pdisk/cvt_pt.c vendored
View File

@ -1,203 +0,0 @@
/*
* cvt_pt.c
*
* Covert partition type. $Revision: 1.6 $
*
* Copyright (c) 1999, Eryk Vershen
*
* History:
* Log: cvt_pt.c,v
* Revision 1.2 2000/05/16 13:56:11 eryk
* Minor fixes
*
* Revision 1.1 2000/02/13 22:04:08 eryk
* Initial revision
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <ctype.h>
#include "partition_map.h"
#include "errors.h"
/*
* Defines / Constants
*/
#define CFLAG_DEFAULT 0
#define DFLAG_DEFAULT 0
#define HFLAG_DEFAULT 0
#define INTERACT_DEFAULT 0
#define RFLAG_DEFAULT 0
/*
* Structs / Types
*/
/*
* Global variables
*/
int hflag = HFLAG_DEFAULT; /* show help */
int dflag = DFLAG_DEFAULT; /* turn on debugging commands and printout */
int rflag = RFLAG_DEFAULT; /* open device read Only */
int interactive = INTERACT_DEFAULT;
int cflag = CFLAG_DEFAULT; /* compute device size */
/*
* Forward declarations
*/
void process(char *filename);
/*
* Start here ...
*/
int
main(int argc, char **argv)
{
register int i;
#ifdef notdef
register int c;
extern char *optarg; /* pointer to argument */
extern int optind; /* next argv index */
extern int opterr; /* who does error messages */
extern int optopt; /* char that caused the error */
int getopt_error; /* getopt choked */
char option_error[100]; /* buffer for error message */
char *arg_option = 0;
int bool_option = 0;
#else
int optind = 1;
#endif
init_program_name(argv);
#ifdef notdef
opterr = 0; /* tell getopt to be quiet */
/*
* Changes to getopt's last argument should
* be reflected in the string printed by the
* usage() function.
*/
while ((c = getopt(argc, argv, "a:b")) != EOF) {
if (c == '?') {
getopt_error = 1;
c = optopt;
} else {
getopt_error = 0;
}
switch (c) {
case 'a':
if (getopt_error) {
usage("missing argument");
} else {
arg_option = optarg;
}
break;
case 'b':
bool_option = 1;
break;
default:
snprintf(option_error, sizeof(option_error),
"no such option as -%c", c);
usage(option_error);
}
}
#endif
if (optind >= argc) {
usage("no file argument");
}
for (i = optind ; i < argc; i++) {
process(argv[i]);
}
return 0;
}
int
trim_num(char *s)
{
char *t;
int n;
for (t = s; *t; t++) {
}
for (t--; t >= s; t--) {
if (!isdigit((uint8_t)*t)) {
t++;
if (*t) {
n = atoi(t);
*t = 0;
} else {
n = -1;
}
return n;
}
}
return -1;
}
/*
* The operation to apply to each file ...
*/
void
process(char *filename)
{
char *s;
int index;
partition_map_header *map;
int valid_file;
partition_map * entry;
//printf("Processing %s\n", filename);
// 1) strip off number from end of filename
s = strdup(filename);
index = trim_num(s);
if (index < 0) {
fatal(-1, "%s does not end in a number", filename);
}
// 2) open prefix of filename as partition map
map = open_partition_map(s, &valid_file, 0);
if (!valid_file) {
fatal(-1, "%s does not have a partition map", s);
return;
}
// 3) verify the type for the partition;
if (map->writable == 0) {
fatal(-1, "The map is not writable");
return;
}
// 4) find partition and change it
entry = find_entry_by_disk_address(index, map);
if (entry == NULL) {
fatal(-1, "No such partition");
} else if (strcmp(entry->data->dpme_type, kHFSType) != 0) {
fatal(-1, "Can't convert a partition with type %s",
entry->data->dpme_type);
} else {
// 4a) modify the type
strncpy(entry->data->dpme_type, kUnixType, DPISTRLEN);
// 5) and write back.
write_partition_map(map);
}
}

View File

@ -1,335 +0,0 @@
/*
* deblock_media.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
// for malloc() & free()
#include <stdlib.h>
// for memcpy()
#include <string.h>
#include "deblock_media.h"
/*
* Defines
*/
/*
* Types
*/
typedef struct deblock_media *DEBLOCK_MEDIA;
struct deblock_media {
struct media m;
long need_filtering;
MEDIA next_media;
uint32_t next_block_size;
uint8_t *buffer;
};
struct deblock_globals {
long exists;
long kind;
};
/*
* Global Constants
*/
/*
* Global Variables
*/
static long deblock_inited = 0;
static struct deblock_globals deblock_info;
/*
* Forward declarations
*/
void deblock_init(void);
DEBLOCK_MEDIA new_deblock_media(void);
long read_deblock_media(MEDIA m, long long offset, uint32_t count, void *address);
long write_deblock_media(MEDIA m, long long offset, uint32_t count, void *address);
long close_deblock_media(MEDIA m);
long os_reload_deblock_media(MEDIA m);
/*
* Routines
*/
void
deblock_init(void)
{
if (deblock_inited != 0) {
return;
}
deblock_inited = 1;
deblock_info.kind = allocate_media_kind();
}
DEBLOCK_MEDIA
new_deblock_media(void)
{
return (DEBLOCK_MEDIA) new_media(sizeof(struct deblock_media));
}
MEDIA
open_deblock_media(uint32_t new_block_size, MEDIA m)
{
DEBLOCK_MEDIA a;
uint32_t block_size;
if (deblock_inited == 0) {
deblock_init();
}
a = 0;
if (m != 0) {
block_size = media_granularity(m);
if (new_block_size == block_size) {
return m;
} else if (new_block_size > block_size) {
if ((new_block_size % block_size) == 0) {
/* no filtering necessary */
a = new_deblock_media();
if (a != 0) {
a->need_filtering = 0;
a->next_block_size = block_size;
a->buffer = 0;
}
} else {
/* too hard to bother with */
}
} else /* new_block_size < block_size */ {
if ((block_size % new_block_size) == 0) {
/* block & unblock */
a = new_deblock_media();
if (a != 0) {
a->need_filtering = 1;
a->next_block_size = block_size;
a->buffer = malloc(block_size);
}
} else {
/* too hard to bother with */
}
}
if (a != 0) {
a->m.kind = deblock_info.kind;
a->m.grain = new_block_size;
a->m.size_in_bytes = media_total_size(m);
a->m.do_read = read_deblock_media;
a->m.do_write = write_deblock_media;
a->m.do_close = close_deblock_media;
a->m.do_os_reload = os_reload_deblock_media;
a->next_media = m;
}
}
return (MEDIA) a;
}
long
read_deblock_media(MEDIA m, long long offset, uint32_t count, void *address)
{
DEBLOCK_MEDIA a;
long rtn_value;
uint32_t next_size;
uint32_t partial_offset;
uint32_t partial_count;
long long cur_offset;
uint32_t remainder;
uint8_t *addr;
a = (DEBLOCK_MEDIA) m;
rtn_value = 0;
if (a == 0) {
/* no media */
} else if (a->m.kind != deblock_info.kind) {
/* wrong kind - XXX need to error here - this is an internal problem */
} else if (count <= 0 || count % a->m.grain != 0) {
/* can't handle size */
} else if (offset < 0 || offset % a->m.grain != 0) {
/* can't handle offset */
} else if (a->need_filtering == 0) {
rtn_value = read_media(a->next_media, offset, count, address);
} else {
next_size = a->next_block_size;
addr = address;
cur_offset = offset;
remainder = count;
rtn_value = 1;
/* read partial */
partial_offset = cur_offset % next_size;
if (partial_offset != 0) {
partial_count = next_size - partial_offset;
if (partial_count > remainder) {
partial_count = remainder;
}
rtn_value = read_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer);
if (rtn_value != 0) {
memcpy (addr, a->buffer + partial_offset, partial_count);
addr += partial_count;
cur_offset += partial_count;
remainder -= partial_count;
}
}
/* read fulls as long as needed */
if (rtn_value != 0 && remainder > next_size) {
partial_count = remainder - (remainder % next_size);
rtn_value = read_media(a->next_media, cur_offset, partial_count, addr);
addr += partial_count;
cur_offset += partial_count;
remainder -= partial_count;
}
/* read partial */
if (rtn_value != 0 && remainder > 0) {
partial_count = remainder;
rtn_value = read_media(a->next_media, cur_offset, next_size, a->buffer);
if (rtn_value != 0) {
memcpy (addr, a->buffer, partial_count);
}
}
}
return rtn_value;
}
long
write_deblock_media(MEDIA m, long long offset, uint32_t count, void *address)
{
DEBLOCK_MEDIA a;
long rtn_value;
uint32_t next_size;
uint32_t partial_offset;
uint32_t partial_count;
long long cur_offset;
uint32_t remainder;
uint8_t *addr;
a = (DEBLOCK_MEDIA) m;
rtn_value = 0;
if (a == 0) {
/* no media */
} else if (a->m.kind != deblock_info.kind) {
/* wrong kind - XXX need to error here - this is an internal problem */
} else if (count <= 0 || count % a->m.grain != 0) {
/* can't handle size */
} else if (offset < 0 || offset % a->m.grain != 0) {
/* can't handle offset */
} else if (a->need_filtering == 0) {
rtn_value = write_media(a->next_media, offset, count, address);
} else {
next_size = a->next_block_size;
addr = address;
cur_offset = offset;
remainder = count;
rtn_value = 1;
/* write partial */
partial_offset = cur_offset % next_size;
if (partial_offset != 0) {
partial_count = next_size - partial_offset;
if (partial_count > remainder) {
partial_count = remainder;
}
rtn_value = read_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer);
if (rtn_value != 0) {
memcpy (a->buffer + partial_offset, addr, partial_count);
rtn_value = write_media(a->next_media, cur_offset - partial_offset, next_size, a->buffer);
addr += partial_count;
cur_offset += partial_count;
remainder -= partial_count;
}
}
/* write fulls as long as needed */
if (rtn_value != 0 && remainder > next_size) {
partial_count = remainder - (remainder % next_size);
rtn_value = write_media(a->next_media, cur_offset, partial_count, addr);
addr += partial_count;
cur_offset += partial_count;
remainder -= partial_count;
}
/* write partial */
if (rtn_value != 0 && remainder > 0) {
partial_count = remainder;
rtn_value = read_media(a->next_media, cur_offset, next_size, a->buffer);
if (rtn_value != 0) {
memcpy (a->buffer, addr, partial_count);
rtn_value = write_media(a->next_media, cur_offset, next_size, a->buffer);
}
}
}
/* recompute size to handle file media */
a->m.size_in_bytes = media_total_size(a->next_media);
return rtn_value;
}
long
close_deblock_media(MEDIA m)
{
DEBLOCK_MEDIA a;
a = (DEBLOCK_MEDIA) m;
if (a == 0) {
return 0;
} else if (a->m.kind != deblock_info.kind) {
/* XXX need to error here - this is an internal problem */
return 0;
}
close_media(a->next_media);
free(a->buffer);
return 1;
}
long
os_reload_deblock_media(MEDIA m)
{
DEBLOCK_MEDIA a;
a = (DEBLOCK_MEDIA) m;
if (a == 0) {
return 0;
} else if (a->m.kind != deblock_info.kind) {
/* XXX need to error here - this is an internal problem */
return 0;
}
os_reload_media(a->next_media);
return 1;
}

View File

@ -1,59 +0,0 @@
/*
* deblock_media.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __deblock_media__
#define __deblock_media__
#include "media.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
MEDIA open_deblock_media(uint32_t new_block_size, MEDIA m);
#endif /* __deblock_media__ */

215
dist/pdisk/dpme.h vendored
View File

@ -1,215 +0,0 @@
//
// dpme.h - Disk Partition Map Entry (dpme)
//
// Written by Eryk Vershen
//
// This file describes structures and values related to the standard
// Apple SCSI disk partitioning scheme.
//
// Each entry is (and shall remain) 512 bytes long.
//
// For more information see:
// "Inside Macintosh: Devices" pages 3-12 to 3-15.
// "Inside Macintosh - Volume V" pages V-576 to V-582
// "Inside Macintosh - Volume IV" page IV-292
//
// There is a kernel file with much of the same info (under different names):
// /usr/src/mklinux-1.0DR2/osfmk/src/mach_kernel/ppc/POWERMAC/mac_label.h
//
/*
* Copyright 1996 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __dpme__
#define __dpme__
#include "bitfield.h"
//
// Defines
//
#define BLOCK0_SIGNATURE 0x4552 /* i.e. 'ER' */
#define DPISTRLEN 32
#define DPME_SIGNATURE 0x504D /* i.e. 'PM' */
// A/UX only stuff (tradition!)
#define dpme_bzb dpme_boot_args
#define BZBMAGIC 0xABADBABE /* BZB magic number */
#define FST ((uint8_t) 0x1) /* standard UNIX FS */
#define FSTEFS ((uint8_t) 0x2) /* Autorecovery FS */
#define FSTSFS ((uint8_t) 0x3) /* Swap FS */
//
// Types
//
// Physical block zero of the disk has this format
struct Block0 {
uint16_t sbSig; /* unique value for SCSI block 0 */
uint16_t sbBlkSize; /* block size of device */
uint32_t sbBlkCount; /* number of blocks on device */
uint16_t sbDevType; /* device type */
uint16_t sbDevId; /* device id */
uint32_t sbData; /* not used */
uint16_t sbDrvrCount; /* driver descriptor count */
uint16_t sbMap[247]; /* descriptor map */
};
typedef struct Block0 Block0;
// Where &sbMap[0] is actually an array DDMap[sbDrvrCount]
// kludge to get around alignment junk
struct DDMap {
uint32_t ddBlock; /* 1st driver's starting block (in sbBlkSize blocks!) */
uint16_t ddSize; /* size of 1st driver (512-byte blks) */
uint16_t ddType; /* system type (1 for Mac+) */
};
typedef struct DDMap DDMap;
// Each partition map entry (blocks 1 through n) has this format
struct dpme {
uint16_t dpme_signature ;
uint16_t dpme_reserved_1 ;
uint32_t dpme_map_entries ;
uint32_t dpme_pblock_start ;
uint32_t dpme_pblocks ;
char dpme_name[DPISTRLEN] ; /* name of partition */
char dpme_type[DPISTRLEN] ; /* type of partition */
uint32_t dpme_lblock_start ;
uint32_t dpme_lblocks ;
uint32_t dpme_flags;
#if 0
uint32_t dpme_reserved_2 : 23 ; /* Bit 9 through 31. */
uint32_t dpme_os_specific_1 : 1 ; /* Bit 8. */
uint32_t dpme_os_specific_2 : 1 ; /* Bit 7. */
uint32_t dpme_os_pic_code : 1 ; /* Bit 6. */
uint32_t dpme_writable : 1 ; /* Bit 5. */
uint32_t dpme_readable : 1 ; /* Bit 4. */
uint32_t dpme_bootable : 1 ; /* Bit 3. */
uint32_t dpme_in_use : 1 ; /* Bit 2. */
uint32_t dpme_allocated : 1 ; /* Bit 1. */
uint32_t dpme_valid : 1 ; /* Bit 0. */
#endif
uint32_t dpme_boot_block ;
uint32_t dpme_boot_bytes ;
uint32_t dpme_load_addr ;
uint32_t dpme_load_addr_2 ;
uint32_t dpme_goto_addr ;
uint32_t dpme_goto_addr_2 ;
uint32_t dpme_checksum ;
char dpme_process_id[16] ;
uint32_t dpme_boot_args[32] ;
uint32_t dpme_reserved_3[62] ;
};
typedef struct dpme DPME;
#define dpme_diskdriver_set(p, v) bitfield_set(&p->dpme_flags, 9, 1, v)
#define dpme_chainable_set(p, v) bitfield_set(&p->dpme_flags, 8, 1, v)
#define dpme_os_specific_1_set(p, v) bitfield_set(&p->dpme_flags, 8, 1, v)
#define dpme_os_specific_2_set(p, v) bitfield_set(&p->dpme_flags, 7, 1, v)
#define dpme_os_pic_code_set(p, v) bitfield_set(&p->dpme_flags, 6, 1, v)
#define dpme_writable_set(p, v) bitfield_set(&p->dpme_flags, 5, 1, v)
#define dpme_readable_set(p, v) bitfield_set(&p->dpme_flags, 4, 1, v)
#define dpme_bootable_set(p, v) bitfield_set(&p->dpme_flags, 3, 1, v)
#define dpme_in_use_set(p, v) bitfield_set(&p->dpme_flags, 2, 1, v)
#define dpme_allocated_set(p, v) bitfield_set(&p->dpme_flags, 1, 1, v)
#define dpme_valid_set(p, v) bitfield_set(&p->dpme_flags, 0, 1, v)
#define dpme_diskdriver_get(p) bitfield_get(p->dpme_flags, 9, 1)
#define dpme_chainable_get(p) bitfield_get(p->dpme_flags, 8, 1)
#define dpme_os_specific_1_get(p) bitfield_get(p->dpme_flags, 8, 1)
#define dpme_os_specific_2_get(p) bitfield_get(p->dpme_flags, 7, 1)
#define dpme_os_pic_code_get(p) bitfield_get(p->dpme_flags, 6, 1)
#define dpme_writable_get(p) bitfield_get(p->dpme_flags, 5, 1)
#define dpme_readable_get(p) bitfield_get(p->dpme_flags, 4, 1)
#define dpme_bootable_get(p) bitfield_get(p->dpme_flags, 3, 1)
#define dpme_in_use_get(p) bitfield_get(p->dpme_flags, 2, 1)
#define dpme_allocated_get(p) bitfield_get(p->dpme_flags, 1, 1)
#define dpme_valid_get(p) bitfield_get(p->dpme_flags, 0, 1)
// A/UX only data structures (sentimental reasons?)
// Alternate block map (aka bad block remaping) [Never really used]
struct abm /* altblk map info stored in bzb */
{
uint32_t abm_size; /* size of map in bytes */
uint32_t abm_ents; /* number of used entries */
uint32_t abm_start; /* start of altblk map */
};
typedef struct abm ABM;
// BZB (Block Zero Block, but I can't remember the etymology)
// Where &dpme_boot_args[0] is actually the address of a struct bzb
// kludge to get around alignment junk
struct bzb /* block zero block format */
{
uint32_t bzb_magic; /* magic number */
uint8_t bzb_cluster; /* Autorecovery cluster grouping */
uint8_t bzb_type; /* FS type */
uint16_t bzb_inode; /* bad block inode number */
uint32_t bzb_flags;
#if 0
uint16_t bzb_root:1, /* FS is a root FS */
bzb_usr:1, /* FS is a usr FS */
bzb_crit:1, /* FS is a critical FS */
bzb_rsrvd:8, /* reserved for later use */
bzb_slice:5; /* slice number to associate with plus one */
uint16_t bzb_filler; /* pad bitfield to 32 bits */
#endif
uint32_t bzb_tmade; /* time of FS creation */
uint32_t bzb_tmount; /* time of last mount */
uint32_t bzb_tumount; /* time of last umount */
ABM bzb_abm; /* altblk map info */
uint32_t bzb_fill2[7]; /* for expansion of ABM (ha!ha!) */
uint8_t bzb_mount_point[64]; /* default mount point name */
};
typedef struct bzb BZB;
#define bzb_root_set(p, v) bitfield_set(&p->bzb_flags, 31, 1, v)
#define bzb_usr_set(p, v) bitfield_set(&p->bzb_flags, 30, 1, v)
#define bzb_crit_set(p, v) bitfield_set(&p->bzb_flags, 29, 1, v)
#define bzb_slice_set(p, v) bitfield_set(&p->bzb_flags, 20, 5, v)
#define bzb_root_get(p) bitfield_get(p->bzb_flags, 31, 1)
#define bzb_usr_get(p) bitfield_get(p->bzb_flags, 30, 1)
#define bzb_crit_get(p) bitfield_get(p->bzb_flags, 29, 1)
#define bzb_slice_get(p) bitfield_get(p->bzb_flags, 20, 5)
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
#endif /* __dpme__ */

906
dist/pdisk/dump.c vendored
View File

@ -1,906 +0,0 @@
//
// dump.c - dumping partition maps
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for *printf()
#include <stdio.h>
// for malloc() & free()
#ifndef __linux__
#include <stdlib.h>
//#include <unistd.h>
#else
#include <malloc.h>
#endif
// for strcmp()
#include <string.h>
// for O_RDONLY
#include <fcntl.h>
// for errno
#include <errno.h>
#include <inttypes.h>
#include "dump.h"
#include "pathname.h"
#include "io.h"
#include "errors.h"
//
// Defines
//
#if DPISTRLEN != 32
#error Change in strlen in partition entries! Fix constants
#endif
#define get_align_long(x) (*(x))
//
// Types
//
typedef struct names {
const char *abbr;
const char *full;
} NAMES;
#ifdef __unix__
typedef uint32_t OSType;
#endif
typedef struct PatchDescriptor {
OSType patchSig;
uint16_t majorVers;
uint16_t minorVers;
uint32_t flags;
uint32_t patchOffset;
uint32_t patchSize;
uint32_t patchCRC;
uint32_t patchDescriptorLen;
uint8_t patchName[33];
uint8_t patchVendor[1];
} PatchDescriptor;
typedef PatchDescriptor * PatchDescriptorPtr;
typedef struct PatchList {
uint16_t numPatchBlocks; // number of disk blocks to hold the patch list
uint16_t 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"},
{"junk", "Apple_Scratch"},
{"unix", "Apple_UNIX_SVR2"},
{" map", "Apple_partition_map"},
{0, 0},
};
const char * kStringEmpty = "";
const char * kStringNot = " not";
//
// Global Variables
//
int aflag = AFLAG_DEFAULT; /* abbreviate partition types */
int pflag = PFLAG_DEFAULT; /* show physical limits of partition */
int fflag = FFLAG_DEFAULT; /* show HFS volume names */
//
// Forward declarations
//
void adjust_value_and_compute_prefix(double *value, int *prefix);
void dump_block_zero(partition_map_header *map);
void dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits);
int get_max_base_or_length(partition_map_header *map);
int get_max_name_string_length(partition_map_header *map);
int get_max_type_string_length(partition_map_header *map);
//
// Routines
//
int
dump(char *name)
{
partition_map_header *map;
int junk;
map = open_partition_map(name, &junk, 0);
if (map == NULL) {
//error(-1, "No partition map in '%s'", name);
return 0;
}
dump_partition_map(map, 1);
close_partition_map(map);
return 1;
}
void
dump_block_zero(partition_map_header *map)
{
Block0 *p;
DDMap *m;
int i;
double value;
int prefix;
int32_t t;
p = map->misc;
if (p->sbSig != BLOCK0_SIGNATURE) {
return;
}
value = ((double)p->sbBlkCount) * p->sbBlkSize;
adjust_value_and_compute_prefix(&value, &prefix);
printf("\nDevice block size=%u, Number of Blocks=%"PRIu32" (%1.1f%c)\n",
p->sbBlkSize, p->sbBlkCount, value, prefix);
printf("DeviceType=0x%x, DeviceId=0x%x\n",
p->sbDevType, p->sbDevId);
if (p->sbDrvrCount > 0) {
printf("Drivers-\n");
m = (DDMap *) p->sbMap;
for (i = 0; i < p->sbDrvrCount; i++) {
printf("%u: %3u @ %"PRIu32", ", 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("(%"PRIu32"@", t);
t = (get_align_long(&m[i].ddBlock) * p->sbBlkSize)
/ map->logical_block;
printf("%"PRIu32") ", t);
}
printf("type=0x%x\n", m[i].ddType);
}
}
printf("\n");
}
void
dump_partition_map(partition_map_header *map, int disk_order)
{
partition_map * entry;
int max_type_length;
int max_name_length;
int digits;
char *alternate;
if (map == NULL) {
bad_input("No partition map exists");
return;
}
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);
free(alternate);
} else {
printf("\nPartition map (with %d byte blocks) on '%s'\n",
map->logical_block, map->name);
}
digits = number_of_digits(get_max_base_or_length(map));
if (digits < 6) {
digits = 6;
}
if (aflag) {
max_type_length = 4;
} else {
max_type_length = get_max_type_string_length(map);
if (max_type_length < 4) {
max_type_length = 4;
}
}
max_name_length = get_max_name_string_length(map);
if (max_name_length < 6) {
max_name_length = 6;
}
printf(" #: %*s %-*s %*s %-*s ( size )\n",
max_type_length, "type",
max_name_length, "name",
digits, "length", digits, "base");
if (disk_order) {
for (entry = map->disk_order; entry != NULL;
entry = entry->next_on_disk) {
dump_partition_entry(entry, max_type_length, max_name_length, digits);
}
} else {
for (entry = map->base_order; entry != NULL;
entry = entry->next_by_base) {
dump_partition_entry(entry, max_type_length, max_name_length, digits);
}
}
dump_block_zero(map);
}
void
dump_partition_entry(partition_map *entry, int type_length, int name_length, int digits)
{
partition_map_header *map;
int j;
DPME *p;
const char *s;
uint32_t size;
double bytes;
int driver;
// int kind;
char *buf;
#if 1
BZB *bp;
#endif
map = entry->the_map;
p = entry->data;
driver = entry->contains_driver? '*': ' ';
if (aflag) {
s = "????";
for (j = 0; plist[j].abbr != 0; j++) {
if (strcmp(p->dpme_type, plist[j].full) == 0) {
s = plist[j].abbr;
break;
}
}
printf("%2"PRIu32": %.4s", entry->disk_address, s);
} else {
printf("%2"PRIu32": %*.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("%*"PRIu32" ", digits, p->dpme_pblocks);
size = p->dpme_pblocks;
} else if (p->dpme_lblocks + p->dpme_lblock_start != p->dpme_pblocks) {
printf("%*"PRIu32"+", digits, p->dpme_lblocks);
size = p->dpme_lblocks;
} else if (p->dpme_lblock_start != 0) {
printf("%*"PRIu32" ", digits, p->dpme_lblocks);
size = p->dpme_lblocks;
} else {
printf("%*"PRIu32" ", digits, p->dpme_pblocks);
size = p->dpme_pblocks;
}
if (pflag || p->dpme_lblock_start == 0) {
printf("@ %-*"PRIu32"", digits, p->dpme_pblock_start);
} else {
printf("@~%-*"PRIu32"", digits, p->dpme_pblock_start + p->dpme_lblock_start);
}
bytes = ((double)size) * map->logical_block;
adjust_value_and_compute_prefix(&bytes, &j);
if (j != ' ' && j != 'K') {
printf(" (%#5.1f%c)", bytes, j);
}
#if 1
// Old A/UX fields that no one pays attention to anymore.
bp = (BZB *) (p->dpme_bzb);
j = -1;
if (bp->bzb_magic == BZBMAGIC) {
switch (bp->bzb_type) {
case FSTEFS:
s = "EFS";
break;
case FSTSFS:
s = "SFS";
j = 1;
break;
case FST:
default:
if (bzb_root_get(bp) != 0) {
if (bzb_usr_get(bp) != 0) {
s = "RUFS";
} else {
s = "RFS";
}
j = 0;
} else if (bzb_usr_get(bp) != 0) {
s = "UFS";
j = 2;
} else {
s = "FS";
}
break;
}
if (bzb_slice_get(bp) != 0) {
printf(" s%1"PRId32" %4s", bzb_slice_get(bp)-1, s);
} else if (j >= 0) {
printf(" S%1d %4s", j, s);
} else {
printf(" %4s", s);
}
if (bzb_crit_get(bp) != 0) {
printf(" K%1d", bp->bzb_cluster);
} else if (j < 0) {
printf(" ");
} else {
printf(" k%1d", bp->bzb_cluster);
}
if (bp->bzb_mount_point[0] != 0) {
printf(" %.64s", bp->bzb_mount_point);
}
}
#endif
printf("\n");
}
void
list_all_disks(void)
{
MEDIA_ITERATOR iter;
MEDIA m;
DPME * data;
char *name;
long mark;
data = (DPME *) malloc(PBLOCK_SIZE);
if (data == NULL) {
error(errno, "can't allocate memory for try buffer");
return;
}
for (iter = first_media_kind(&mark); iter != 0; iter = next_media_kind(&mark)) {
while ((name = step_media_iterator(iter)) != 0) {
if ((m = open_pathname_as_media(name, O_RDONLY)) == 0) {
#if defined(__linux__) || defined(__unix__)
error(errno, "can't open file '%s'", name);
#endif
} else {
close_media(m);
dump(name);
}
free(name);
}
delete_media_iterator(iter);
}
free(data);
}
void
show_data_structures(partition_map_header *map)
{
Block0 *zp;
DDMap *m;
int i;
int j;
partition_map * entry;
DPME *p;
BZB *bp;
const char *s;
if (map == NULL) {
printf("No partition map exists\n");
return;
}
printf("Header:\n");
printf("map %d blocks out of %d, media %"PRIu32" 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->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) {
printf("No block zero\n");
} else {
zp = map->misc;
printf("Block0:\n");
printf("signature 0x%x", zp->sbSig);
if (zp->sbSig == BLOCK0_SIGNATURE) {
printf("\n");
} else {
printf(" should be 0x%x\n", BLOCK0_SIGNATURE);
}
printf("Block size=%u, Number of Blocks=%"PRIu32"\n",
zp->sbBlkSize, zp->sbBlkCount);
printf("DeviceType=0x%x, DeviceId=0x%x, sbData=0x%"PRIx32"\n",
zp->sbDevType, zp->sbDevId, zp->sbData);
if (zp->sbDrvrCount == 0) {
printf("No drivers\n");
} else {
printf("%u driver%s-\n", zp->sbDrvrCount,
(zp->sbDrvrCount>1)?"s":kStringEmpty);
m = (DDMap *) zp->sbMap;
for (i = 0; i < zp->sbDrvrCount; i++) {
printf("%u: @ %"PRIu32" for %u, type=0x%x\n", i+1,
get_align_long(&m[i].ddBlock),
m[i].ddSize, m[i].ddType);
}
}
}
printf("\n");
/*
uint32_t dpme_boot_args[32] ;
uint32_t dpme_reserved_3[62] ;
*/
printf(" #: type length base "
"flags (logical)\n");
for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
p = entry->data;
printf("%2"PRIu32": %20.32s ",
entry->disk_address, p->dpme_type);
printf("%7"PRIu32" @ %-7"PRIu32" ", p->dpme_pblocks, p->dpme_pblock_start);
printf("%c%c%c%c%c%c%c%c%c%c%c%c ",
(dpme_valid_get(p))?'V':'.',
(dpme_allocated_get(p))?'A':'.',
(dpme_in_use_get(p))?'I':'.',
(dpme_bootable_get(p))?'B':'.',
(dpme_readable_get(p))?'R':'.',
(dpme_writable_get(p))?'W':'.',
(dpme_os_pic_code_get(p))?'P':'.',
(dpme_os_specific_2_get(p))?'2':'.',
(dpme_chainable_get(p))?'C':'.',
(dpme_diskdriver_get(p))?'D':'.',
(bitfield_get(p->dpme_flags, 30, 1))?'M':'.',
(bitfield_get(p->dpme_flags, 31, 1))?'X':'.');
if (p->dpme_lblock_start != 0 || p->dpme_pblocks != p->dpme_lblocks) {
printf("(%"PRIu32" @ %"PRIu32")", p->dpme_lblocks, p->dpme_lblock_start);
}
printf("\n");
}
printf("\n");
printf(" #: booter bytes load_address "
"goto_address checksum processor\n");
for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
p = entry->data;
printf("%2"PRIu32": ", entry->disk_address);
printf("%7"PRIu32" ", p->dpme_boot_block);
printf("%7"PRIu32" ", p->dpme_boot_bytes);
printf("%8"PRIx32" ", (uint32_t)p->dpme_load_addr);
printf("%8"PRIx32" ", (uint32_t)p->dpme_load_addr_2);
printf("%8"PRIx32" ", (uint32_t)p->dpme_goto_addr);
printf("%8"PRIx32" ", (uint32_t)p->dpme_goto_addr_2);
printf("%8"PRIx32" ", p->dpme_checksum);
printf("%.32s", p->dpme_process_id);
printf("\n");
}
printf("\n");
/*
xx: cccc RU *dd s...
*/
printf(" #: type RU *slice mount_point (A/UX only fields)\n");
for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
p = entry->data;
printf("%2"PRIu32": ", entry->disk_address);
bp = (BZB *) (p->dpme_bzb);
j = -1;
if (bp->bzb_magic == BZBMAGIC) {
switch (bp->bzb_type) {
case FSTEFS:
s = "esch";
break;
case FSTSFS:
s = "swap";
j = 1;
break;
case FST:
default:
s = "fsys";
if (bzb_root_get(bp) != 0) {
j = 0;
} else if (bzb_usr_get(bp) != 0) {
j = 2;
}
break;
}
printf("%4s ", s);
printf("%c%c ",
(bzb_root_get(bp))?'R':' ',
(bzb_usr_get(bp))?'U':' ');
if (bzb_slice_get(bp) != 0) {
printf(" %2"PRIu32"", bzb_slice_get(bp)-1);
} else if (j >= 0) {
printf(" *%2d", j);
} else {
printf(" ");
}
if (bp->bzb_mount_point[0] != 0) {
printf(" %.64s", bp->bzb_mount_point);
}
}
printf("\n");
}
}
void
full_dump_partition_entry(partition_map_header *map, int ix)
{
partition_map * cur;
DPME *p;
int i;
uint32_t t;
cur = find_entry_by_disk_address(ix, map);
if (cur == NULL) {
printf("No such partition\n");
return;
}
p = cur->data;
printf(" signature: 0x%x\n", p->dpme_signature);
printf(" reserved1: 0x%x\n", p->dpme_reserved_1);
printf(" number of map entries: %"PRId32"\n", p->dpme_map_entries);
printf(" physical start: %10"PRIu32" length: %10"PRIu32"\n", p->dpme_pblock_start, p->dpme_pblocks);
printf(" logical start: %10"PRIu32" length: %10"PRIu32"\n", p->dpme_lblock_start, p->dpme_lblocks);
printf(" flags: 0x%"PRIx32"\n", (uint32_t)p->dpme_flags);
printf(" ");
if (dpme_valid_get(p)) printf("valid ");
if (dpme_allocated_get(p)) printf("alloc ");
if (dpme_in_use_get(p)) printf("in-use ");
if (dpme_bootable_get(p)) printf("boot ");
if (dpme_readable_get(p)) printf("read ");
if (dpme_writable_get(p)) printf("write ");
if (dpme_os_pic_code_get(p)) printf("pic ");
t = p->dpme_flags >> 7;
for (i = 7; i <= 31; i++) {
if (t & 0x1) {
printf("%d ", i);
}
t = t >> 1;
}
printf("\n");
printf(" name: '%.32s'\n", p->dpme_name);
printf(" type: '%.32s'\n", p->dpme_type);
printf(" boot start block: %10"PRIu32"\n", p->dpme_boot_block);
printf("boot length (in bytes): %10"PRIu32"\n", p->dpme_boot_bytes);
printf(" load address: 0x%08"PRIx32" 0x%08"PRIx32"\n",
(uint32_t)p->dpme_load_addr, (uint32_t)p->dpme_load_addr_2);
printf(" start address: 0x%08"PRIx32" 0x%08"PRIx32"\n",
(uint32_t)p->dpme_goto_addr, (uint32_t)p->dpme_goto_addr_2);
printf(" checksum: 0x%08"PRIx32"\n", p->dpme_checksum);
printf(" processor: '%.32s'\n", p->dpme_process_id);
printf("boot args field -");
dump_block((uint8_t *)p->dpme_boot_args, 32*4);
printf("dpme_reserved_3 -");
dump_block((uint8_t *)p->dpme_reserved_3, 62*4);
}
void
dump_block(uint8_t *addr, int len)
{
int i;
int j;
int limit1;
int limit;
#define LINE_LEN 16
#define UNIT_LEN 4
#define OTHER_LEN 8
for (i = 0; i < len; i = limit) {
limit1 = i + LINE_LEN;
if (limit1 > len) {
limit = len;
} else {
limit = limit1;
}
printf("\n%03x: ", i);
for (j = i; j < limit1; j++) {
if (j % UNIT_LEN == 0) {
printf(" ");
}
if (j < limit) {
printf("%02x", addr[j]);
} else {
printf(" ");
}
}
printf(" ");
for (j = i; j < limit; j++) {
if (j % OTHER_LEN == 0) {
printf(" ");
}
if (addr[j] < ' ') {
printf(".");
} else {
printf("%c", addr[j]);
}
}
}
printf("\n");
}
void
full_dump_block_zero(partition_map_header *map)
{
Block0 *zp;
DDMap *m;
int i;
if (map == NULL) {
printf("No partition map exists\n");
return;
}
if (map->misc == NULL) {
printf("No block zero\n");
return;
}
zp = map->misc;
printf(" signature: 0x%x\n", zp->sbSig);
printf(" size of a block: %d\n", zp->sbBlkSize);
printf(" number of blocks: %"PRId32"\n", zp->sbBlkCount);
printf(" device type: 0x%x\n", zp->sbDevType);
printf(" device id: 0x%x\n", zp->sbDevId);
printf(" data: 0x%"PRIx32"\n", zp->sbData);
printf(" driver count: %d\n", zp->sbDrvrCount);
m = (DDMap *) zp->sbMap;
for (i = 0; &m[i].ddType < &zp->sbMap[247]; i++) {
if (m[i].ddBlock == 0 && m[i].ddSize == 0 && m[i].ddType == 0) {
break;
}
printf(" driver %3u block: %"PRId32"\n", i+1, m[i].ddBlock);
printf(" size in blocks: %d\n", m[i].ddSize);
printf(" driver type: 0x%x\n", m[i].ddType);
}
printf("remainder of block -");
dump_block((uint8_t *)(void *)&m[i].ddBlock, (&zp->sbMap[247]-((uint16_t *)(void *)&m[i].ddBlock))*2);
}
void
display_patches(partition_map *entry)
{
long long offset;
MEDIA m;
static uint8_t *patch_block;
PatchListPtr p;
PatchDescriptorPtr q;
uint8_t *next;
uint8_t *s;
int i;
offset = entry->data->dpme_pblock_start;
m = entry->the_map->m;
offset = ((long long) entry->data->dpme_pblock_start) * entry->the_map->logical_block;
if (patch_block == NULL) {
patch_block = (uint8_t *) malloc(PBLOCK_SIZE);
if (patch_block == NULL) {
error(errno, "can't allocate memory for patch block buffer");
return;
}
}
if (read_media(m, (long long)offset, PBLOCK_SIZE, (char *)patch_block) == 0) {
error(errno, "Can't read patch block");
return;
}
p = (PatchListPtr) patch_block;
if (p->numPatchBlocks != 1) {
i = p->numPatchBlocks;
free(patch_block);
patch_block = (uint8_t *) 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%"PRIx32"\n", q->flags);
printf(" offset: %"PRId32"\n", q->patchOffset);
printf(" size: %"PRId32"\n", q->patchSize);
printf(" CRC: 0x%"PRIx32"\n", q->patchCRC);
printf(" name: '%.*s'\n", q->patchName[0], &q->patchName[1]);
printf(" vendor: '%.*s'\n", q->patchVendor[0], &q->patchVendor[1]);
next = ((uint8_t *)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
get_max_type_string_length(partition_map_header *map)
{
partition_map * entry;
int max;
int length;
if (map == NULL) {
return 0;
}
max = 0;
for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
length = strnlen(entry->data->dpme_type, DPISTRLEN);
if (length > max) {
max = length;
}
}
return max;
}
int
get_max_name_string_length(partition_map_header *map)
{
partition_map * entry;
int max;
int length;
if (map == NULL) {
return 0;
}
max = 0;
for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
length = strnlen(entry->data->dpme_name, DPISTRLEN);
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;
}
int
get_max_base_or_length(partition_map_header *map)
{
partition_map * entry;
uint32_t max;
if (map == NULL) {
return 0;
}
max = 0;
for (entry = map->disk_order; entry != NULL; entry = entry->next_on_disk) {
if (entry->data->dpme_pblock_start > max) {
max = entry->data->dpme_pblock_start;
}
if (entry->data->dpme_pblocks > max) {
max = entry->data->dpme_pblocks;
}
if (entry->data->dpme_lblock_start > max) {
max = entry->data->dpme_lblock_start;
}
if (entry->data->dpme_lblocks > max) {
max = entry->data->dpme_lblocks;
}
}
return max;
}
void
adjust_value_and_compute_prefix(double *value, int *prefix)
{
double bytes;
int multiplier;
bytes = *value;
if (bytes < 1024.0) {
multiplier = ' ';
} else {
bytes = bytes / 1024.0;
if (bytes < 1024.0) {
multiplier = 'K';
} else {
bytes = bytes / 1024.0;
if (bytes < 1024.0) {
multiplier = 'M';
} else {
bytes = bytes / 1024.0;
if (bytes < 1024.0) {
multiplier = 'G';
} else {
bytes = bytes / 1024.0;
multiplier = 'T';
}
}
}
}
*value = bytes;
*prefix = multiplier;
}

72
dist/pdisk/dump.h vendored
View File

@ -1,72 +0,0 @@
//
// dump.h - dumping partition maps
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __dump__
#define __dump__
#include "partition_map.h"
//
// Defines
//
#define AFLAG_DEFAULT 0
#define PFLAG_DEFAULT 1
#define FFLAG_DEFAULT 0
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
extern int aflag;
extern int pflag;
extern int fflag;
//
// Forward declarations
//
void display_patches(partition_map *entry);
int dump(char *name);
void dump_block(uint8_t *addr, int len);
void dump_partition_map(partition_map_header *map, int disk_order);
void full_dump_partition_entry(partition_map_header *, int);
void full_dump_block_zero(partition_map_header *map);
void list_all_disks(void);
void show_data_structures(partition_map_header *map);
#endif /* __dump__ */

178
dist/pdisk/errors.c vendored
View File

@ -1,178 +0,0 @@
//
// errors.c - error & help routines
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for *printf()
#include <stdio.h>
#include <errno.h>
// for exit()
#ifndef __linux__
#include <stdlib.h>
#endif
// for strrchr
#include <string.h>
// for va_start(), etc.
#include <stdarg.h>
#include "errors.h"
//
// Defines
//
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
char *program_name;
#ifdef NeXT
extern int errno;
extern int sys_nerr;
extern const char * const sys_errlist[];
#endif
//
// Forward declarations
//
//
// Routines
//
void
init_program_name(char **argv)
{
#if defined(__linux__) || defined(__unix__)
if ((program_name = strrchr(argv[0], '/')) != (char *)NULL) {
program_name++;
} else {
program_name = argv[0];
}
#else
program_name = "pdisk";
#endif
}
void
do_help(void)
{
printf("\t%s [-h|--help]\n", program_name);
printf("\t%s [-v|--version]\n", program_name);
#ifdef __linux__
printf("\t%s [-l|--list [name]] [...]\n", program_name);
#else
printf("\t%s [-l|--list] name [...]\n", program_name);
#endif
printf("\t%s [-r|--readonly] name ...\n", program_name);
printf("\t%s [-i|--interactive]\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(const char *kind)
{
error(-1, "bad usage - %s\n", kind);
hflag = 1;
}
//
// Print a message on standard error and exit with value.
// Values in the range of system error numbers will add
// the perror(3) message.
//
void
fatal(int value, const char *fmt, ...)
{
va_list ap;
fprintf(stderr, "%s: ", program_name);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
#if defined(__linux__) || defined(NeXT) || defined(__unix__)
if (value > 0 && value < sys_nerr) {
fprintf(stderr, " (%s)\n", sys_errlist[value]);
} else {
fprintf(stderr, "\n");
}
#else
fprintf(stderr, "\n");
printf("Processing stopped: Choose 'Quit' from the file menu to quit.\n\n");
#endif
exit(value);
}
//
// Print a message on standard error.
// Values in the range of system error numbers will add
// the perror(3) message.
//
void
error(int value, const char *fmt, ...)
{
va_list ap;
fprintf(stderr, "%s: ", program_name);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
#if defined(__linux__) || defined(NeXT) || defined(__unix__)
if (value > 0 && value < sys_nerr) {
fprintf(stderr, " (%s)\n", sys_errlist[value]);
} else {
fprintf(stderr, "\n");
}
#else
fprintf(stderr, "\n");
#endif
}

62
dist/pdisk/errors.h vendored
View File

@ -1,62 +0,0 @@
//
// errors.h - error & help routines
//
// Written by Eryk Vershen
//
/*
* Copyright 1996 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __errors__
#define __errors__
//
// Defines
//
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
extern int hflag;
//
// Forward declarations
//
void do_help(void);
void init_program_name(char **argv);
void error(int value, const char *fmt, ...) __printflike(2, 3);
void fatal(int value, const char *fmt, ...) __dead __printflike(2, 3);
void usage(const char *kind);
#endif /* __errors__ */

View File

@ -1,578 +0,0 @@
/*
* file_media.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for printf()
#include <stdio.h>
// for malloc() & free()
#include <stdlib.h>
// for lseek(), read(), write(), close()
#include <unistd.h>
// for open()
#include <fcntl.h>
// for LONG_MAX
#include <limits.h>
// for errno
#include <errno.h>
#ifdef __linux__
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/hdreg.h>
#include <sys/stat.h>
#else
#ifdef __unix__
#include <sys/ioctl.h>
#include <sys/stat.h>
#endif
#endif
#include "file_media.h"
#include "errors.h"
/*
* Defines
*/
#ifdef __linux__
#define LOFF_MAX 9223372036854775807LL
extern __loff_t llseek __P ((int __fd, __loff_t __offset, int __whence));
#elif defined(__NetBSD__) || defined(__APPLE__)
#define loff_t off_t
#define llseek lseek
#define LOFF_MAX LLONG_MAX
#else
#define loff_t long
#define llseek lseek
#define LOFF_MAX LONG_MAX
#endif
/*
* Types
*/
typedef struct file_media *FILE_MEDIA;
struct file_media {
struct media m;
int fd;
int regular_file;
};
struct file_media_globals {
long exists;
long kind;
};
typedef struct file_media_iterator *FILE_MEDIA_ITERATOR;
struct file_media_iterator {
struct media_iterator m;
long style;
long index;
};
/*
* Global Constants
*/
int potential_block_sizes[] = {
1, 512, 1024, 2048, 4096, 8192, 16834,
0
};
enum {
kSCSI_Disks = 0,
kATA_Devices = 1,
kSCSI_CDs = 2,
kMaxStyle = 2
};
/*
* Global Variables
*/
static long file_inited = 0;
static struct file_media_globals file_info;
/*
* Forward declarations
*/
int compute_block_size(int fd);
void file_init(void);
FILE_MEDIA new_file_media(void);
long read_file_media(MEDIA m, long long offset, uint32_t count, void *address);
long write_file_media(MEDIA m, long long offset, uint32_t count, void *address);
long close_file_media(MEDIA m);
long os_reload_file_media(MEDIA m);
FILE_MEDIA_ITERATOR new_file_iterator(void);
void reset_file_iterator(MEDIA_ITERATOR m);
char *step_file_iterator(MEDIA_ITERATOR m);
void delete_file_iterator(MEDIA_ITERATOR m);
/*
* Routines
*/
void
file_init(void)
{
if (file_inited != 0) {
return;
}
file_inited = 1;
file_info.kind = allocate_media_kind();
}
FILE_MEDIA
new_file_media(void)
{
return (FILE_MEDIA) new_media(sizeof(struct file_media));
}
int
compute_block_size(int fd)
{
int size;
int max_size;
loff_t x;
long t;
int i;
char *buffer;
max_size = 0;
for (i = 0; ; i++) {
size = potential_block_sizes[i];
if (size == 0) {
break;
}
if (max_size < size) {
max_size = size;
}
}
buffer = malloc(max_size);
if (buffer != 0) {
for (i = 0; ; i++) {
size = potential_block_sizes[i];
if (size == 0) {
break;
}
if ((x = llseek(fd, (loff_t)0, 0)) < 0) {
error(errno, "Can't seek on file");
break;
}
if ((t = read(fd, buffer, size)) == size) {
free(buffer);
return size;
}
}
}
return 0;
}
MEDIA
open_file_as_media(char *file, int oflag)
{
FILE_MEDIA a;
int fd;
loff_t off;
#if defined(__linux__) || defined(__unix__)
struct stat info;
#endif
if (file_inited == 0) {
file_init();
}
a = 0;
fd = open(file, oflag);
if (fd >= 0) {
a = new_file_media();
if (a != 0) {
a->m.kind = file_info.kind;
a->m.grain = compute_block_size(fd);
off = llseek(fd, (loff_t)0, 2); /* seek to end of media */
#if !defined(__linux__) && !defined(__unix__)
if (off <= 0) {
off = 1; /* XXX not right? */
}
#endif
//printf("file size = %Ld\n", off);
a->m.size_in_bytes = (long long) off;
a->m.do_read = read_file_media;
a->m.do_write = write_file_media;
a->m.do_close = close_file_media;
a->m.do_os_reload = os_reload_file_media;
a->fd = fd;
a->regular_file = 0;
#if defined(__linux__) || defined(__unix__)
if (fstat(fd, &info) < 0) {
error(errno, "can't stat file '%s'", file);
} else {
a->regular_file = S_ISREG(info.st_mode);
}
#endif
} else {
close(fd);
}
}
return (MEDIA) a;
}
long
read_file_media(MEDIA m, long long offset, uint32_t count, void *address)
{
FILE_MEDIA a;
long rtn_value;
loff_t off;
int t;
a = (FILE_MEDIA) m;
rtn_value = 0;
if (a == 0) {
/* no media */
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 */
fprintf(stderr,"wrong kind\n");
} else if (count <= 0 || count % a->m.grain != 0) {
/* can't handle size */
fprintf(stderr,"bad size\n");
} else if (offset < 0 || offset % a->m.grain != 0) {
/* can't handle offset */
fprintf(stderr,"bad offset\n");
} else if (offset + (long long) count > a->m.size_in_bytes && a->m.size_in_bytes != (long long) 0) {
/* check for offset (and offset+count) too large */
fprintf(stderr,"offset+count too large\n");
} else if (offset + count > (long long) LOFF_MAX) {
/* check for offset (and offset+count) too large */
fprintf(stderr,"offset+count too large 2\n");
} else {
/* do the read */
off = offset;
if ((off = llseek(a->fd, off, 0)) >= 0) {
if ((t = read(a->fd, address, count)) == (ssize_t)count) {
rtn_value = 1;
} else {
fprintf(stderr,"read failed\n");
}
} else {
fprintf(stderr,"lseek failed\n");
}
}
return rtn_value;
}
long
write_file_media(MEDIA m, long long offset, uint32_t count, void *address)
{
FILE_MEDIA a;
long rtn_value;
loff_t off;
int t;
a = (FILE_MEDIA) m;
rtn_value = 0;
if (a == 0) {
/* no media */
} else if (a->m.kind != file_info.kind) {
/* wrong kind - XXX need to error here - this is an internal problem */
} else if (count <= 0 || count % a->m.grain != 0) {
/* can't handle size */
} else if (offset < 0 || offset % a->m.grain != 0) {
/* can't handle offset */
} else if (offset + count > (long long) LOFF_MAX) {
/* check for offset (and offset+count) too large */
} else {
/* do the write */
off = offset;
if ((off = llseek(a->fd, off, 0)) >= 0) {
if ((t = write(a->fd, address, count)) == (ssize_t)count) {
if (off + (long long) count > a->m.size_in_bytes) {
a->m.size_in_bytes = off + count;
}
rtn_value = 1;
}
}
}
return rtn_value;
}
long
close_file_media(MEDIA m)
{
FILE_MEDIA a;
a = (FILE_MEDIA) m;
if (a == 0) {
return 0;
} else if (a->m.kind != file_info.kind) {
/* XXX need to error here - this is an internal problem */
return 0;
}
close(a->fd);
return 1;
}
long
os_reload_file_media(MEDIA m)
{
FILE_MEDIA a;
long rtn_value;
#if defined(__linux__)
int i;
int saved_errno;
#endif
a = (FILE_MEDIA) m;
rtn_value = 0;
if (a == 0) {
/* no media */
} else if (a->m.kind != file_info.kind) {
/* wrong kind - XXX need to error here - this is an internal problem */
} else if (a->regular_file) {
/* okay - nothing to do */
rtn_value = 1;
} else {
#ifdef __linux__
sync();
sleep(2);
if ((i = ioctl(a->fd, BLKRRPART)) != 0) {
saved_errno = errno;
} else {
// some kernel versions (1.2.x) seem to have trouble
// rereading the partition table, but if asked to do it
// twice, the second time works. - biro@yggdrasil.com */
sync();
sleep(2);
if ((i = ioctl(a->fd, BLKRRPART)) != 0) {
saved_errno = errno;
}
}
// printf("Syncing disks.\n");
sync();
sleep(4); /* for sync() */
if (i < 0) {
error(saved_errno, "Re-read of partition table failed");
printf("Reboot your system to ensure the "
"partition table is updated.\n");
}
#endif
rtn_value = 1;
}
return rtn_value;
}
#if !defined(__linux__) && !defined(__unix__)
#pragma mark -
#endif
FILE_MEDIA_ITERATOR
new_file_iterator(void)
{
return (FILE_MEDIA_ITERATOR) new_media_iterator(sizeof(struct file_media_iterator));
}
MEDIA_ITERATOR
create_file_iterator(void)
{
FILE_MEDIA_ITERATOR a;
if (file_inited == 0) {
file_init();
}
a = new_file_iterator();
if (a != 0) {
a->m.kind = file_info.kind;
a->m.state = kInit;
a->m.do_reset = reset_file_iterator;
a->m.do_step = step_file_iterator;
a->m.do_delete = delete_file_iterator;
a->style = 0;
a->index = 0;
}
return (MEDIA_ITERATOR) a;
}
void
reset_file_iterator(MEDIA_ITERATOR m)
{
FILE_MEDIA_ITERATOR a;
a = (FILE_MEDIA_ITERATOR) m;
if (a == 0) {
/* no media */
} else if (a->m.kind != file_info.kind) {
/* wrong kind - XXX need to error here - this is an internal problem */
} else if (a->m.state != kInit) {
a->m.state = kReset;
}
}
char *
step_file_iterator(MEDIA_ITERATOR m)
{
FILE_MEDIA_ITERATOR a;
char *result;
struct stat info;
int fd;
int bump;
int value;
a = (FILE_MEDIA_ITERATOR) m;
if (a == 0) {
/* no media */
} else if (a->m.kind != file_info.kind) {
/* wrong kind - XXX need to error here - this is an internal problem */
} else {
switch (a->m.state) {
case kInit:
a->m.state = kReset;
/* fall through to reset */
case kReset:
a->style = 0 /* first style */;
a->index = 0 /* first index */;
a->m.state = kIterating;
/* fall through to iterate */
case kIterating:
while (1) {
if (a->style > kMaxStyle) {
break;
}
#ifndef notdef
/* if old version of mklinux then skip CD drive */
if (a->style == kSCSI_Disks && a->index == 3) {
a->index += 1;
}
#endif
/* generate result */
result = (char *) malloc(20);
if (result != NULL) {
/*
* for DR3 we should actually iterate through:
*
* /dev/sd[a...] # first missing is end of list
* /dev/hd[a...] # may be holes in sequence
* /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 for
* particular reasons.
*/
bump = 0;
value = (int) a->index;
switch (a->style) {
case kSCSI_Disks:
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:
if (value < 26) {
snprintf(result, 20, "/dev/hd%c", 'a'+value);
} else {
bump = -1;
}
break;
case kSCSI_CDs:
if (value < 10) {
snprintf(result, 20, "/dev/scd%c", '0'+value);
} else {
bump = -1;
}
break;
}
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;
}
}
a->index += 1; /* next index */
return result;
}
a->m.state = kEnd;
/* fall through to end */
case kEnd:
default:
break;
}
}
return 0 /* no entry */;
}
void
delete_file_iterator(MEDIA_ITERATOR m)
{
return;
}

View File

@ -1,60 +0,0 @@
/*
* file_media.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __file_media__
#define __file_media__
#include "media.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
MEDIA open_file_as_media(char *file, int oflag);
MEDIA_ITERATOR create_file_iterator(void);
#endif /* __file_media__ */

255
dist/pdisk/hfs_misc.c vendored
View File

@ -1,255 +0,0 @@
//
// 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 <inttypes.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) (*(uint32_t*)(x))
//
// Types
//
typedef long long u64;
typedef struct ExtDescriptor { // extent descriptor
uint16_t xdrStABN; // first allocation block
uint16_t xdrNumABlks; // number of allocation blocks
} ext_descriptor;
typedef struct ExtDataRec {
ext_descriptor ed[3]; // extent data record
} ext_data_rec;
/*
* The crazy "uint16_t 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
uint16_t drSigWord; // volume signature
uint16_t drCrDate[2]; // date and time of volume creation
uint16_t drLsMod[2]; // date and time of last modification
uint16_t drAtrb; // volume attributes
uint16_t drNmFls; // number of files in root directory
uint16_t drVBMSt; // first block of volume bitmap
uint16_t drAllocPtr; // start of next allocation search
uint16_t drNmAlBlks; // number of allocation blocks in volume
uint32_t drAlBlkSiz; // size (in bytes) of allocation blocks
uint32_t drClpSiz; // default clump size
uint16_t drAlBlSt; // first allocation block in volume
uint16_t drNxtCNID[2]; // next unused catalog node ID
uint16_t drFreeBks; // number of unused allocation blocks
char drVN[28]; // volume name
uint16_t drVolBkUp[2]; // date and time of last backup
uint16_t drVSeqNum; // volume backup sequence number
uint16_t drWrCnt[2]; // volume write count
uint16_t drXTClpSiz[2]; // clump size for extents overflow file
uint16_t drCTClpSiz[2]; // clump size for catalog file
uint16_t drNmRtDirs; // number of directories in root directory
uint32_t drFilCnt; // number of files in volume
uint32_t drDirCnt; // number of directories in volume
uint32_t drFndrInfo[8]; // information used by the Finder
#ifdef notdef
uint16_t drVCSize; // size (in blocks) of volume cache
uint16_t drVBMCSize; // size (in blocks) of volume bitmap cache
uint16_t drCtlCSize; // size (in blocks) of common volume cache
#else
uint16_t drEmbedSigWord; // type of embedded volume
ext_descriptor drEmbedExtent; // embedded volume extent
#endif
uint16_t drXTFlSize[2]; // size of extents overflow file
ext_data_rec drXTExtRec; // extent record for extents overflow file
uint16_t drCTFlSize[2]; // size of catalog file
ext_data_rec drCTExtRec; // extent record for catalog file
};
typedef uint32_t HFSCatalogNodeID;
typedef struct HFSPlusExtentDescriptor {
uint32_t startBlock;
uint32_t blockCount;
} HFSPlusExtentDescriptor;
typedef HFSPlusExtentDescriptor HFSPlusExtentRecord[ 8];
typedef struct HFSPlusForkData {
u64 logicalSize;
uint32_t clumpSize;
uint32_t totalBlocks;
HFSPlusExtentRecord extents;
} HFSPlusForkData;
struct HFSPlusVolumeHeader {
uint16_t signature;
uint16_t version;
uint32_t attributes;
uint32_t lastMountedVersion;
uint32_t reserved;
uint32_t createDate;
uint32_t modifyDate;
uint32_t backupDate;
uint32_t checkedDate;
uint32_t fileCount;
uint32_t folderCount;
uint32_t blockSize;
uint32_t totalBlocks;
uint32_t freeBlocks;
uint32_t nextAllocation;
uint32_t rsrcClumpSize;
uint32_t dataClumpSize;
HFSCatalogNodeID nextCatalogID;
uint32_t writeCount;
u64 encodingsBitmap;
uint8_t finderInfo[ 32];
HFSPlusForkData allocationFile;
HFSPlusForkData extentsFile;
HFSPlusForkData catalogFile;
HFSPlusForkData attributesFile;
HFSPlusForkData startupFile;
} HFSPlusVolumeHeader;
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
uint32_t embeded_offset(struct mdb_record *mdb, uint32_t sector);
int read_partition_block(partition_map *entry, uint32_t num, char *buf);
//
// Routines
//
uint32_t
embeded_offset(struct mdb_record *mdb, uint32_t sector)
{
uint32_t 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("%"PRIu32" 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, uint32_t num, char *buf)
{
DPME *data;
partition_map_header * map;
uint32_t 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);
}

41
dist/pdisk/hfs_misc.h vendored
View File

@ -1,41 +0,0 @@
//
// 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__ */

462
dist/pdisk/io.c vendored
View File

@ -1,462 +0,0 @@
//
// io.c - simple io and input parsing routines
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for *printf()
#include <stdio.h>
// for malloc() & free()
#if !defined(__linux__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif
// for strncpy()
#include <string.h>
// for va_start(), etc.
#include <stdarg.h>
// for errno
#include <errno.h>
#include "io.h"
#include "errors.h"
//
// Defines
//
#define BAD_DIGIT 17 /* must be greater than any base */
#define STRING_CHUNK 16
#define UNGET_MAX_COUNT 10
#ifndef __linux__
#ifndef __unix__
#define SCSI_FD 8
#endif
#ifdef NeXT
#define loff_t off_t
#define llseek lseek
#else
#define loff_t long
#define llseek lseek
#endif
#endif
//
// Types
//
//
// Global Constants
//
const long kDefault = -1;
//
// Global Variables
//
short unget_buf[UNGET_MAX_COUNT+1];
int unget_count;
char io_buffer[MAXIOSIZE];
//
// Forward declarations
//
long get_number(int first_char);
char* get_string(int eos);
int my_getch(void);
void my_ungetch(int c);
//
// Routines
//
int
my_getch(void)
{
if (unget_count > 0) {
return (unget_buf[--unget_count]);
} else {
return (getc(stdin));
}
}
void
my_ungetch(int c)
{
// In practice there is never more than one character in
// the unget_buf, but what's a little overkill among friends?
if (unget_count < UNGET_MAX_COUNT) {
unget_buf[unget_count++] = c;
} else {
fatal(-1, "Programmer error in my_ungetch().");
}
}
void
flush_to_newline(int keep_newline)
{
int c;
for (;;) {
c = my_getch();
if (c <= 0) {
break;
} else if (c == '\n') {
if (keep_newline) {
my_ungetch(c);
}
break;
} else {
// skip
}
}
return;
}
int
get_okay(const char *prompt, int default_value)
{
int c;
flush_to_newline(0);
printf("%s", prompt);
for (;;) {
c = my_getch();
if (c <= 0) {
break;
} else if (c == ' ' || c == '\t') {
// skip blanks and tabs
} else if (c == '\n') {
my_ungetch(c);
return default_value;
} else if (c == 'y' || c == 'Y') {
return 1;
} else if (c == 'n' || c == 'N') {
return 0;
} else {
flush_to_newline(0);
printf("%s", prompt);
}
}
return -1;
}
int
get_command(const char *prompt, int promptBeforeGet, int *command)
{
int c;
if (promptBeforeGet) {
printf("%s", prompt);
}
for (;;) {
c = my_getch();
if (c <= 0) {
break;
} else if (c == ' ' || c == '\t') {
// skip blanks and tabs
} else if (c == '\n') {
printf("%s", prompt);
} else {
*command = c;
return 1;
}
}
return 0;
}
int
get_number_argument(const char *prompt, long *number, long default_value)
{
int c;
int result = 0;
for (;;) {
c = my_getch();
if (c <= 0) {
break;
} else if (c == ' ' || c == '\t') {
// skip blanks and tabs
} else if (c == '\n') {
if (default_value == kDefault) {
printf("%s", prompt);
} else {
my_ungetch(c);
*number = default_value;
result = 1;
break;
}
} else if ('0' <= c && c <= '9') {
*number = get_number(c);
result = 1;
break;
} else {
my_ungetch(c);
*number = 0;
break;
}
}
return result;
}
long
get_number(int first_char)
{
register int c;
int base;
int digit;
int ret_value;
if (first_char != '0') {
c = first_char;
base = 10;
digit = BAD_DIGIT;
} else if ((c=my_getch()) == 'x' || c == 'X') {
c = my_getch();
base = 16;
digit = BAD_DIGIT;
} else {
my_ungetch(c);
c = first_char;
base = 8;
digit = 0;
}
ret_value = 0;
for (ret_value = 0; ; c = my_getch()) {
if (c >= '0' && c <= '9') {
digit = c - '0';
} else if (c >='A' && c <= 'F') {
digit = 10 + (c - 'A');
} else if (c >='a' && c <= 'f') {
digit = 10 + (c - 'a');
} else {
digit = BAD_DIGIT;
}
if (digit >= base) {
break;
}
ret_value = ret_value * base + digit;
}
my_ungetch(c);
return(ret_value);
}
int
get_string_argument(const char *prompt, char **string, int reprompt)
{
int c;
int result = 0;
for (;;) {
c = my_getch();
if (c <= 0) {
break;
} else if (c == ' ' || c == '\t') {
// skip blanks and tabs
} else if (c == '\n') {
if (reprompt) {
printf("%s", prompt);
} else {
my_ungetch(c);
*string = NULL;
break;
}
} else if (c == '"' || c == '\'') {
*string = get_string(c);
result = 1;
break;
} else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
|| (c == '-' || c == '/' || c == '.' || c == ':')) {
my_ungetch(c);
*string = get_string(' ');
result = 1;
break;
} else {
my_ungetch(c);
*string = NULL;
break;
}
}
return result;
}
char *
get_string(int eos)
{
int c;
char *s;
char *ret_value;
char *limit;
int length;
ret_value = (char *) malloc(STRING_CHUNK);
if (ret_value == NULL) {
error(errno, "can't allocate memory for string buffer");
return NULL;
}
length = STRING_CHUNK;
limit = ret_value + length;
c = my_getch();
for (s = ret_value; ; c = my_getch()) {
if (s >= limit) {
// expand string
limit = (char *) malloc(length+STRING_CHUNK);
if (limit == NULL) {
error(errno, "can't allocate memory for string buffer");
ret_value[length-1] = 0;
break;
}
strncpy(limit, ret_value, length);
free(ret_value);
s = limit + (s - ret_value);
ret_value = limit;
length += STRING_CHUNK;
limit = ret_value + length;
}
if (c <= 0 || c == eos || (eos == ' ' && c == '\t')) {
*s++ = 0;
break;
} else if (c == '\n') {
*s++ = 0;
my_ungetch(c);
break;
} else {
*s++ = c;
}
}
return(ret_value);
}
uint32_t
get_multiplier(long divisor)
{
int c;
uint32_t result;
uint32_t extra;
c = my_getch();
extra = 1;
if (c <= 0 || divisor <= 0) {
result = 0;
} else if (c == 't' || c == 'T') {
result = 1024*1024;
extra = 1024*1024;
} else if (c == 'g' || c == 'G') {
result = 1024*1024*1024;
} else if (c == 'm' || c == 'M') {
result = 1024*1024;
} else if (c == 'k' || c == 'K') {
result = 1024;
} else {
my_ungetch(c);
result = 1;
}
if (result > 1) {
if (extra > 1) {
result /= divisor;
if (result >= 4096) {
/* overflow -> 20bits + >12bits */
result = 0;
} else {
result *= extra;
}
} else if ((long long)result >= divisor) {
result /= divisor;
} else {
result = 1;
}
}
return result;
}
int
get_partition_modifier(void)
{
int c;
int result;
result = 0;
c = my_getch();
if (c == 'p' || c == 'P') {
result = 1;
} else if (c > 0) {
my_ungetch(c);
}
return result;
}
int
number_of_digits(uint32_t value)
{
int j;
j = 1;
while (value > 9) {
j++;
value = value / 10;
}
return j;
}
//
// Print a message on standard error & flush the input.
//
void
bad_input(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
flush_to_newline(1);
}

67
dist/pdisk/io.h vendored
View File

@ -1,67 +0,0 @@
//
// io.h - simple io and input parsing routines
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __io__
#define __io__
//
// Defines
//
#define MAXIOSIZE 2048
//
// Types
//
//
// Global Constants
//
extern const long kDefault;
//
// Global Variables
//
//
// Forward declarations
//
void bad_input(const char *fmt, ...) __printflike(1, 2);
void flush_to_newline(int keep_newline);
int get_command(const char *prompt, int promptBeforeGet, int *command);
uint32_t get_multiplier(long divisor);
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(const char *prompt, char **string, int reprompt);
int number_of_digits(uint32_t value);
#endif /* __io__ */

View File

@ -1,181 +0,0 @@
/*
* layout_dump.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1996,1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for printf()
#include <stdio.h>
// for strlen()
#include <string.h>
#include <inttypes.h>
#include "layout_dump.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
uint8_t bitmasks[] = {
0x01, 0x03, 0x07, 0x0F,
0x1F, 0x3F, 0x7F, 0xFF
};
/*
* Global Variables
*/
/*
* Forward declarations
*/
/*
* Routines
*/
void
dump_using_layout(void *buffer, layout *desc)
{
layout *entry;
int byte_length;
long value;
int max_name;
int i;
max_name = 0;
for (entry = desc; entry->format != kEnd; entry++) {
value = strlen(entry->name);
if (value > max_name) {
max_name = value;
}
}
for (entry = desc; entry->format != kEnd; entry++) {
if (entry->format != kBit) {
printf("%*s: ", max_name, entry->name);
byte_length = entry->bit_length / 8;
if (entry->bit_offset != 0 || (entry->bit_length % 8) != 0) {
printf("entry %d, can't handle bitfields yet.\n", (int)(entry - desc));
continue;
}
value = 0;
for (i = entry->byte_offset; byte_length > 0;i++) {
value = value << 8;
value |= ((uint8_t *)buffer)[i];
byte_length--;
}
} else {
if (entry->bit_offset < 0 || entry->bit_offset > 8) {
printf("entry %d, bad bit offset (%d).\n", (int)(entry - desc), entry->bit_offset);
continue;
} else if (entry->bit_length <= 0
|| entry->bit_length > (entry->bit_offset + 1)) {
printf("entry %d, bad bit length (%d,%d).\n", (int)(entry - desc),
entry->bit_offset, entry->bit_length);
continue;
}
value = (((uint8_t *)buffer)[entry->byte_offset]
& bitmasks[entry->bit_offset])
>> ((entry->bit_offset + 1) - entry->bit_length);
}
switch (entry->format) {
case kHex:
printf("0x%x\n", (uint32_t) value);
break;
case kDec:
byte_length = entry->bit_length / 8;
switch (byte_length) {
case 4: printf("%"PRId32"\n", (int32_t)value); break;
case 2: printf("%"PRId16"\n", (int16_t)value); break;
case 1: printf("%"PRId8"\n", (int8_t)value); break;
}
break;
case kUns:
byte_length = entry->bit_length / 8;
switch (byte_length) {
case 4: printf("%"PRIu32"\n", (uint32_t)value); break;
case 2: printf("%"PRIu16"\n", (uint16_t)value); break;
case 1: printf("%"PRIu8"\n", (uint8_t)value); break;
}
break;
case kBit:
if (value) {
printf("%*s %s\n", max_name, "", entry->name);
}
break;
default:
printf("entry %d, unknown format (%d).\n", (int)(entry - desc), entry->format);
break;
}
}
}
void
DumpRawBuffer(uint8_t *bufferPtr, int length )
{
register int i;
int lineStart;
int lineLength;
short c;
#define kLineSize 16
for (lineStart = 0; lineStart < length; lineStart += lineLength) {
lineLength = kLineSize;
if (lineStart + lineLength > length)
lineLength = length - lineStart;
printf("%03x %3d:", lineStart, lineStart);
for (i = 0; i < lineLength; i++)
printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
for (; i < kLineSize; i++)
printf(" ");
printf(" ");
for (i = 0; i < lineLength; i++) {
c = bufferPtr[lineStart + i] & 0xFF;
if (c > ' ' && c < '~')
printf("%c", c);
else {
printf(".");
}
}
printf("\n");
}
}

View File

@ -1,78 +0,0 @@
/*
* layout_dump.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __layout_dump__
#define __layout_dump__
/*
* Defines
*/
/*
* Types
*/
enum {
kEnd,
kHex,
kDec,
kUns,
kBit
};
typedef struct {
short byte_offset;
short bit_offset;
short bit_length;
short format;
char *name;
} layout;
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
/*
* Routines
*/
void dump_using_layout(void *buffer, layout *desc);
void DumpRawBuffer(uint8_t *bufferPtr, int length);
#endif /* __layout_dump__ */

212
dist/pdisk/makefile vendored
View File

@ -1,212 +0,0 @@
#
# Makefile for pdisk
#
MAN_PAGE= \
pdisk.8
MAC_DOC= \
pdisk.html
DOCS= \
HISTORY \
README \
$(MAN_PAGE) \
$(MAC_DOC)
SERVER_README = \
dist.README
SERVER_MESSAGE = \
dist.message
DOCS_INTERNAL= \
HISTORY.ALL \
HOWTO.DISTRIBUTE \
To_do_list \
command-language
SUPPORT= \
make_filename \
make_depend \
make_tags \
checkin_files \
MPWcompare \
name_latest \
next_release
MAC_SOURCE= \
ATA_media.c \
ATA_media.h \
DoSCSICommand.c \
DoSCSICommand.h \
MacSCSICommand.h \
SCSI_media.c \
SCSI_media.h \
pdisk.r
UNIX_SOURCE= \
bitfield.c \
bitfield.h \
convert.c \
convert.h \
cvt_pt.c \
deblock_media.c \
deblock_media.h \
dpme.h \
dump.c \
dump.h \
errors.c \
errors.h \
file_media.c \
file_media.h \
hfs_misc.c \
hfs_misc.h \
io.c \
io.h \
layout_dump.c \
layout_dump.h \
makefile \
media.c \
media.h \
partition_map.c \
partition_map.h \
pathname.c \
pathname.h \
pdisk.c \
pdisk.h \
util.c \
util.h \
validate.c \
validate.h \
version.h
COMMON_OBJECTS = \
partition_map.o \
bitfield.o \
convert.o \
deblock_media.o \
file_media.o \
errors.o \
hfs_misc.o \
io.o \
media.o \
pathname.o \
util.o
UNIX_OBJECTS = \
pdisk.o \
dump.o \
$(COMMON_OBJECTS) \
validate.o
CVT_OBJECTS = \
cvt_pt.o \
$(COMMON_OBJECTS)
ALL_FILES= $(DOCS) $(DOCS_INTERNAL) $(SUPPORT) $(MAC_SOURCE) $(UNIX_SOURCE)
UNIX_BINARIES= \
pdisk \
cvt_pt
#
# these names have '__' in place of ' ' to avoid quoting nightmares
#
MAC_PROJECT= \
pdisk.mac.bin \
pdisk.mac__Data/CW__Settings.stm.bin \
pdisk.mac__Data/pdisk.tdm.bin \
pdisk.mac__Data/pdisk__68k.tdm.bin
# Constructed under MacOS using CodeWarrior from MAC_PROJECT & sources
MAC_BINARY= \
pdisk.hqx
MAC_68KBINARY= \
pdisk_68k.hqx
CFLAGS = -Wall -D__unix__ -g
DIST_TAR_FLAGS = cvf
all: $(UNIX_BINARIES)
pdisk: $(UNIX_OBJECTS)
cc -o pdisk $(UNIX_OBJECTS)
cvt_pt: $(CVT_OBJECTS)
cc -o cvt_pt $(CVT_OBJECTS)
tags: $(MAC_SOURCE) $(UNIX_SOURCE)
ctags $(MAC_SOURCE) $(UNIX_SOURCE)
clean:
rm -f *.o $(UNIX_BINARIES) list.src
clobber: clean
rm -f $(ALL_FILES) $(MAC_BINARY) $(MAC_68KBINARY) tags
# note the sed to reinsert the spaces in the Mac names
list.src: $(MAC_SOURCE) $(DOCS) $(UNIX_SOURCE) $(MAC_PROJECT)
echo $(MAC_SOURCE) $(DOCS) $(UNIX_SOURCE) $(MAC_PROJECT) |\
tr ' ' '\n' | sed -e 's/__/ /g' -e 's,^,pdisk/,' >list.src
#
# this depends on this source directory being named 'pdisk'
#
distribution: list.src
cd ..; tar $(DIST_TAR_FLAGS) pdisk/dist/pdisk.src.tar.`date +%Y%m%d` --files-from pdisk/list.src
tar $(DIST_TAR_FLAGS) dist/pdisk.bin.tar.`date +%Y%m%d` $(UNIX_BINARIES) $(MAN_PAGE)
cp -f $(MAC_DOC) dist/$(MAC_DOC).`date +%Y%m%d`
cp -f $(MAC_BINARY) dist/$(MAC_BINARY).`date +%Y%m%d`
cp -f $(MAC_68KBINARY) dist/$(MAC_68KBINARY).`date +%Y%m%d`
checkin:
./checkin_files $(ALL_FILES)
checkout: $(ALL_FILES)
diff:
rcsdiff $(ALL_FILES) 2>&1
name:
./name_latest $(ALL_FILES)
#
# in lieu of a real dependency generator
#
convert.h: dpme.h
deblock_media.h: media.h
dpme.h: bitfield.h
dump.h: partition_map.h hfs_misc.h
file_media.h: media.h
partition_map.h: dpme.h media.h
pathname.h: media.h
validate.h: partition_map.h
bitfield.o: bitfield.c bitfield.h
convert.o: convert.c convert.h
deblock_media.o: deblock_media.c deblock_media.h
dump.o: dump.c dump.h pathname.h io.h errors.h
errors.o: errors.c errors.h
file_media.o: file_media.c file_media.h errors.h
io.o: io.c io.h errors.h
layout_dump.o: layout_dump.c layout_dump.h
media.o: media.c media.h
partition_map.o: partition_map.c partition_map.h pathname.h deblock_media.h io.h convert.h util.h errors.h
pathname.o: pathname.c pathname.h file_media.h
pdisk.o: pdisk.c pdisk.h io.h partition_map.h pathname.h errors.h dump.h validate.h version.h util.h
util.o: util.c version.h util.h
validate.o: validate.c validate.h deblock_media.h pathname.h convert.h io.h errors.h
#
# fake dependencies used only by list.src {for $(MAC_PROJECT)}
#
pdisk.mac__Data/CW__Settings.stm.bin:
pdisk.mac__Data/pdisk.tdm.bin:
pdisk.mac__Data/pdisk__68k.tdm.bin:

228
dist/pdisk/media.c vendored
View File

@ -1,228 +0,0 @@
/*
* media.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for printf()
#include <stdio.h>
// for malloc() & free()
#include <stdlib.h>
#include "media.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
static long media_kind = 0;
/*
* Forward declarations
*/
/*
* Routines
*/
long
allocate_media_kind(void)
{
media_kind++;
return media_kind;
}
MEDIA
new_media(long size)
{
return (MEDIA) malloc(size);
}
void
delete_media(MEDIA m)
{
if (m == 0) {
return;
}
free(m);
}
uint32_t
media_granularity(MEDIA m)
{
if (m == 0) {
return 0;
} else {
return m->grain;
}
}
long long
media_total_size(MEDIA m)
{
if (m == 0) {
return 0;
} else {
return m->size_in_bytes;
}
}
long
read_media(MEDIA m, long long offset, uint32_t count, void *address)
{
long result;
if (m != 0 && m->do_read != 0) {
//printf("media: read type %d, offset %Ld, count %d\n\t", m->kind, offset, count);
result = (*m->do_read)(m, offset, count, address);
//printf(" - returns %d\n", result);
return result;
} else {
return 0;
}
}
long
write_media(MEDIA m, long long offset, uint32_t count, void *address)
{
long result;
if (m != 0 && m->do_write != 0) {
//printf("media: write type %d, offset %Ld, count %d\n\t", m->kind, offset, count);
result = (*m->do_write)(m, offset, count, address);
//printf(" - returns %d\n", result);
return result;
} else {
return 0;
}
}
void
close_media(MEDIA m)
{
if (m == 0) {
return;
}
if (m->kind != 0) {
if (m->do_close != 0) {
(*m->do_close)(m);
}
m->kind = 0;
delete_media(m);
}
}
void
os_reload_media(MEDIA m)
{
if (m != 0 && m->do_os_reload != 0) {
(*m->do_os_reload)(m);
}
}
#if !defined(__linux__) && !defined(__unix__)
#pragma mark -
#endif
MEDIA_ITERATOR
new_media_iterator(long size)
{
return (MEDIA_ITERATOR) malloc(size);
}
void
private_delete_media_iterator(MEDIA_ITERATOR m)
{
if (m == 0) {
return;
}
free(m);
}
void
reset_media_iterator(MEDIA_ITERATOR m)
{
if (m != 0 && m->do_reset != 0) {
(*m->do_reset)(m);
}
}
char *
step_media_iterator(MEDIA_ITERATOR m)
{
char *result;
if (m != 0 && m->do_step != 0) {
result = (*m->do_step)(m);
} else {
result = 0;
}
return result;
}
void
delete_media_iterator(MEDIA_ITERATOR m)
{
if (m == 0) {
return;
}
if (m->kind != 0) {
if (m->do_delete != 0) {
(*m->do_delete)(m);
}
m->kind = 0;
private_delete_media_iterator(m);
}
}

139
dist/pdisk/media.h vendored
View File

@ -1,139 +0,0 @@
/*
* media.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __media__
#define __media__
/*
* Media is an abstraction of a disk device.
*
* A media object has the following visible attributes:
*
* a granularity (e.g. 512, 1024, 1, etc.)
* a total size in bytes
*
* And the following operations are available:
*
* open
* read @ byte offset for size in bytes
* write @ byte offset for size in bytes
* close
*
* XXX Should really split public media interface from "protected" interface.
*/
/*
* Defines
*/
/*
* Types
*/
/* those whose use media objects need just the pointer type */
typedef struct media *MEDIA;
/* those who define media objects need the struct and internal routine types */
typedef long (*media_read)(MEDIA m, long long offset, uint32_t count, void *address);
typedef long (*media_write)(MEDIA m, long long offset, uint32_t count, void *address);
typedef long (*media_close)(MEDIA m);
typedef long (*media_os_reload)(MEDIA m);
struct media {
long kind; /* kind of media - SCSI, IDE, etc. */
uint32_t grain; /* granularity (offset & size) */
long long size_in_bytes; /* offset granularity */
media_read do_read; /* device specific routines */
media_write do_write;
media_close do_close;
media_os_reload do_os_reload;
/* specific media kinds will add extra info */
};
/* those whose use media object iterators need just the pointer type */
typedef struct media_iterator *MEDIA_ITERATOR;
/* those who define media object iterators need the struct and internal routine types */
typedef void (*media_iterator_reset)(MEDIA_ITERATOR m);
typedef char* (*media_iterator_step)(MEDIA_ITERATOR m);
typedef void (*media_iterator_delete)(MEDIA_ITERATOR m);
typedef enum {
kInit,
kReset,
kIterating,
kEnd
} media_iterator_state;
struct media_iterator {
long kind; /* kind of media - SCSI, IDE, etc. */
media_iterator_state state; /* init, reset, iterating, at_end */
media_iterator_reset do_reset; /* device specific routines */
media_iterator_step do_step;
media_iterator_delete do_delete;
/* specific media kinds will add extra info */
};
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
/* those whose use media objects need these routines */
uint32_t media_granularity(MEDIA m);
long long media_total_size(MEDIA m);
long read_media(MEDIA m, long long offset, uint32_t count, void *address);
long write_media(MEDIA m, long long offset, uint32_t count, void *address);
void close_media(MEDIA m);
void os_reload_media(MEDIA m);
/* those who define media objects need these routines also */
long allocate_media_kind(void);
MEDIA new_media(long size);
void delete_media(MEDIA m);
/* those whose use media object iterators need these routines */
void reset_media_iterator(MEDIA_ITERATOR m);
char *step_media_iterator(MEDIA_ITERATOR m);
void delete_media_iterator(MEDIA_ITERATOR m);
/* those who define media object iterators need these routines also */
MEDIA_ITERATOR new_media_iterator(long size);
void private_delete_media_iterator(MEDIA_ITERATOR m);
#endif /* __media__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
//
// partition_map.h - partition map routines
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __partition_map__
#define __partition_map__
#include "dpme.h"
#include "media.h"
//
// Defines
//
#define PBLOCK_SIZE 512
#define MAX_LINUX_MAP 15
//
// Types
//
struct partition_map_header {
MEDIA m;
char *name;
struct partition_map * disk_order;
struct partition_map * base_order;
Block0 *misc;
int writable;
int changed;
int written;
int physical_block; // must be == sbBlockSize
int logical_block; // must be <= physical_block
int blocks_in_map;
int maximum_in_map;
uint32_t media_size; // in logical_blocks
};
typedef struct partition_map_header partition_map_header;
struct partition_map {
struct partition_map * next_on_disk;
struct partition_map * prev_on_disk;
struct partition_map * next_by_base;
struct partition_map * prev_by_base;
int32_t disk_address;
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
//
extern const char * kFreeType;
extern const char * kMapType;
extern const char * kUnixType;
extern const char * kHFSType;
extern const char * kFreeName;
extern const char * kPatchType;
//
// Global Variables
//
extern int rflag;
extern int interactive;
extern int dflag;
//
// Forward declarations
//
int add_partition_to_map(const char *name, const char *dptype, uint32_t base, uint32_t length, partition_map_header *map);
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(int32_t, partition_map_header *);
partition_map* find_entry_by_type(const char *type_name, partition_map_header *map);
partition_map* find_entry_by_base(uint32_t base, partition_map_header *map);
partition_map_header* init_partition_map(char *name, partition_map_header* oldmap);
void move_entry_in_map(int32_t, int32_t, partition_map_header *);
partition_map_header* open_partition_map(char *name, int *valid_file, int ask_logical_size);
void resize_map(uint32_t 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__ */

248
dist/pdisk/pathname.c vendored
View File

@ -1,248 +0,0 @@
/*
* pathname.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for strncmp()
#include <string.h>
#include <stdint.h>
#include "pathname.h"
#include "file_media.h"
#if !defined(__linux__) && !defined(__unix__)
#include "SCSI_media.h"
#include "ATA_media.h"
#endif
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
/*
* Routines
*/
/*
* Note that open_pathname_as_media() and get_linux_name() have almost
* identical structures. If one changes the other must also!
*/
MEDIA
open_pathname_as_media(char *path, int oflag)
{
MEDIA m = 0;
#if !defined(__linux__) && !defined(__unix__)
long id;
long bus;
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);
}
} 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_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_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_linux_ata_as_media(id);
}
}
} else
#endif
{
m = open_file_as_media(path, oflag);
}
return m;
}
char *
get_linux_name(char *path)
{
char *result = 0;
#if !defined(__linux__) && !defined(__unix__)
long id;
long bus;
if (strncmp("/dev/", path, 5) == 0) {
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 = 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 = 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 = 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 = linux_ata_name(bus, id);
}
}
}
#endif
return result;
}
MEDIA_ITERATOR
first_media_kind(long *state)
{
*state = 0;
return next_media_kind(state);
}
MEDIA_ITERATOR
next_media_kind(long *state)
{
MEDIA_ITERATOR result;
long ix;
result = 0;
ix = *state;
switch (ix) {
case 0:
#if defined(__linux__) || defined(__unix__)
result = create_file_iterator();
#endif
ix = 1;
if (result != 0) {
break;
}
/* fall through to next interface */
case 1:
#if !defined(__linux__) && !defined(__unix__)
result = create_ata_iterator();
#endif
ix = 2;
if (result != 0) {
break;
}
/* fall through to next interface */
case 2:
#if !defined(__linux__) && !defined(__unix__)
result = create_scsi_iterator();
#endif
ix = 3;
if (result != 0) {
break;
}
/* fall through to next interface */
case 3:
default:
break;
}
*state = ix;
return result;
}

62
dist/pdisk/pathname.h vendored
View File

@ -1,62 +0,0 @@
/*
* pathname.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __pathname__
#define __pathname__
#include "media.h"
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
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_linux_name(char *name);
#endif /* __pathname__ */

240
dist/pdisk/pdisk.8 vendored
View File

@ -1,240 +0,0 @@
.\" $NetBSD: pdisk.8,v 1.17 2009/03/09 19:24:26 joerg Exp $
.Dd April 24, 2003
.Dt PDISK 8
.Os
.Sh NAME
.Nm pdisk
.Nd Apple partition table editor
.Sh SYNOPSIS
.Nm
.Op Fl acdfhilLrv
.Op Fl -abbr
.Op Fl -compute_size
.Op Fl -debug
.Op Fl -fname
.Op Fl -help
.Op Fl -interactive
.Op Fl -list Ar device
.Op Fl -logical
.Op Fl -readonly
.Op Fl -version
.Op Ar device ...
.Sh DESCRIPTION
.Nm
is a menu driven program which partitions disks using the standard Apple
disk partitioning scheme described in "Inside Macintosh: Devices".
It does not support the Intel/DOS partitioning scheme supported by
.Xr fdisk 8 .
.Pp
Supported options are:
.Bl -tag -width "--compute_sizeXX" -compact
.It Fl a
.It Fl -abbr
Abbreviate the partition types shown in the partition list.
.It Fl c
.It Fl -compute_size
Causes
.Nm
to always ignore the device size listed in the partition table
and compute the device size by other means.
.It Fl d
.It Fl -debug
Turns on debugging.
Doesn't add that much output, but does add a new command
.Sq x
to the editing commands that accesses an eclectic bunch of
undocumented functionality.
.It Fl f
.It Fl -fname
Show HFS volume names instead of partition name when available.
.It Fl h
.It Fl -help
Prints a short help message.
.It Fl i
.It Fl -interactive
Causes
.Nm
to go into an interactive mode similar to the MacOS version of the program.
.It Fl l
.It Fl -list Ar device
.\"If no
.\".Ar device
.\"argument is given,
.\".Nm
.\"tries to list partition tables for all available hard drives.
.\"Otherwise,
.\".Nm
.\"lists
List
the partition tables for the specified
.Ar devices .
.It Fl L
.It Fl -logical
Show partition limits in logical blocks.
Default is physical blocks.
.It Fl r
.It Fl -readonly
Prevents
.Nm
from writing to the device.
.It Fl v
.It Fl -version
Prints the version number of
.Nm .
.El
.Ss Editing Partition Tables
An argument which is simply the name of a
.Ar device
indicates that
.Nm
should edit the partition table of that device.
.Pp
The current top level editing commands are:
.Bd -unfilled -offset indent
C (create with type also specified)
c create new partition
d delete a partition
h command help
i initialize partition map
n (re)name a partition
P (print ordered by base address)
p print the partition table
q quit editing (don't save changes)
r reorder partition entry in map
s change size of partition map
t change the type of an existing partition
w write the partition table
.Ed
.Pp
Commands which take arguments prompt for each argument in turn.
You can also type any number of the arguments separated by spaces
and those prompts will be skipped.
The only exception to typeahead are the confirmation prompts on the
.Ic i
and
.Ic w
commands,
since if we expect you to confirm the decision, we shouldn't undermine
that by allowing you to be precipitate about it.
.Pp
Partitions are always specified by their number,
which is the index of the partition entry in the partition map.
Most of the commands will change the index numbers of all partitions
after the affected partition.
You are advised to print the table as frequently as necessary.
.Pp
.\"Creating more than fifteen partitions is not advised.
.\"There may be a bug in old linux kernels which causes
.\"access to the whole disk fail if more than fifteen partitions are in the map.
.\".Pp
The
.Ic c
(create new partition) command is the only one with complicated arguments.
The first argument is the base address (in blocks) of the partition.
Besides a raw number, you can also specify a partition number followed
by the letter
.Sq p
to indicate that the first block of the new partition should be the same
as the first block of that existing free space partition.
The second argument is the length of the partition in blocks.
This can be a raw number or can be a partition number followed by the
letter
.Sq p
to use the size of that partition or can be a number followed
by
.Sq k ,
.Sq m ,
or
.Sq g
to indicate the size in kilobytes, megabytes, or gigabytes respectively.
(These are powers of 1024, of course, not powers of 1000.)
The third argument is the name of the partition.
This can be a single word without quotes, or a string surrounded by
single or double quotes.
The type of the created partition will be Apple_UNIX_SVR2, which is
the correct type for use with
.Nx .
This command will prompt for the unix filesystem slice to set
in the Block Zero Block bits.
.Pp
The
.Ic C
command is similar to the
.Ic c
command, with the addition of a partition type argument after the
other arguments.
Choosing a type of Apple_UNIX_SVR2 will prompt for
the unix filesystem slice to set in the Block Zero Block bits.
.Pp
The
.Ic i
(initalize) command prompts for the size of the device.
.\"This was done to get around a bug in the kernel where it reports the wrong
.\"size for the device.
.Pp
The
.Ic n
(name) command allows the name of a partition to be changed.
Note that the various "Apple_Driver" partitions depend
on the name field for proper functioning.
We are not aware of any other partition types with this limitation.
.Pp
The
.Ic r
(reorder) command allows the index number of partitions to be changed.
The index numbers are constrained to be a contiguous sequence.
.Pp
The
.Ic t
(change partition type) command allows the type of a partition to be
changed.
Changing the type to Apple_UNIX_SVR2 will prompt for the
unix filesystem slice to set in the Block Zero Block bits.
.Pp
The
.Ic w
(write) command writes the partition map out.
.\"but there is currently a bug in the interaction between MkLinux and Mach
.\"which causes the partition map not to be reinterpreted.
In order to use the new partition map you must reboot.
.Sh SEE ALSO
.Xr fdisk 8 ,
.Xr newfs 8
.Sh HISTORY
The
.Nm
utility was originally developed for MkLinux.
.Sh AUTHORS
.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
The
.Fl -logical
option has not been heavily tested.
.Pp
.Nm
will first try to use
.Xr lseek 2
with
.Dv SEEK_END
to compute the size of the device.
If this fails, it will try a binary search using
.Xr lseek 2
and
.Xr read 2
to find the end of the device.
This has been observed to fail on some raw disk devices.
As a workaround, try using the block device instead.
.Nm
should probably read the disklabel using the
.Dv DIOCGDINFO
.Xr ioctl 2
to get the device size instead.

1167
dist/pdisk/pdisk.c vendored

File diff suppressed because it is too large Load Diff

57
dist/pdisk/pdisk.h vendored
View File

@ -1,57 +0,0 @@
//
// pdisk.h - general header for pdisk program
//
// Written by Eryk Vershen
//
/*
* Copyright 1996,1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __pdisk__
#define __pdisk__
//
// Defines
//
#define BOOT_PARTITION_PROCESS_ID "powerpc"
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
#endif /* __pdisk__ */

406
dist/pdisk/pdisk.html vendored
View File

@ -1,406 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN//2.0">
<HTML>
<HEAD>
<TITLE>pdisk for the Mac OS</TITLE>
<X-SAS-WINDOW TOP=42 BOTTOM=477 LEFT=4 RIGHT=556>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<H2>Overview</H2>
<H3>What is pdisk?</H3>
<P>A simple editor for Apple disk partition format. There are two
main versions of pdisk: one for Linux and one for the Mac OS. This
document describes the Mac OS version of pdisk. Much of this document
is also relevant to the Linux version, but check the manual page
(pdisk.8) also.</P>
<H3>What is the Apple disk partition format?</H3>
<P>Most operating systems have ways to divide disks into several
pieces - so that an entire disk does not have to be devoted to one
filesystem, or even to one operating system. This division of the
disk is usually called partitioning. In some systems the partitioning
information is built into the operating system code, but that tends to
be restrictive. In the Mac OS the partitioning information is stored
on the first few blocks of the disk.</P>
<P>The Apple disk partition scheme was developed in 1986 by the A/UX
team with input from the Mac OS and Apple II teams. There was an
earlier partition scheme used in the first SCSI drives on the
MacPlus, but that was replaced by the current scheme in the Macintosh
II and subsequent machines and in subsequent operating system
releases. The current scheme is supported by Mac OS, A/UX, ProDos,
MkLinux, LinuxPPC, and MacOS X.</P>
<H3>What are LinuxPPC and MkLinux?</H3>
<P>Just in case you got pdisk other than as part of a LinuxPPC or
MkLinux release:</P>
<P>LinuxPPC is a port of the true Linux operating system that runs
on most of the Power Macintosh systems from Apple Computer. It also
runs on several non-Apple PowerPC machines.</P>
<P>MkLinux is a portion of the Linux operating system, converted to run
as a server process on top of the Mach microkernel. As with Linux,
all of the operating system source code is available for
<A HREF="http://www.mklinux.org">download</A>, including the
Mach source. MkLinux runs on some of PowerPC based Macintosh
machines.</P>
<H3>Which Macintosh machines does pdisk run on?</H3>
<P>The Mac OS binary should run on any PowerPC based Macintosh. It
has been tested under System 7.6.1 and System 8, but should run on
older versions of the Mac OS as well. A Mac OS 68000 binary is also
distributed for those who may find it useful. </P>
<H3>Why would I want to use pdisk on the Mac OS?</H3>
<P>The main clients for the Mac OS version of pdisk are Linux
users. pdisk was originally developed for Linux. The command syntax
was originally identical to that for the 'fdisk' program. (fdisk is a
Linux program which edits the DOS/Windows disk partition format.) The
Mac OS version is a simple, crude port of the Linux version.</P>
<P>The advantages of pdisk over the various Mac OS disk partitioning
programs (such as SilverLining, the FWB toolkit, Apple HD SC Setup,
DriveSetup, etc) are:</P>
<UL>
<LI>unlike the Apple partitioners, it does not restrict the set of
drives it can operate on
<LI>it allows partitions to be reordered (helpful, as Linux
depends on the order)
<LI>it creates Linux partitions by default
<LI>it allows the size of the partition map to be changed
<LI>it allows the name of a partition to be changed
<LI>it allows you to edit the partition map of your boot disk
</UL>
<P>The disadvantages of pdisk are:</P>
<UL>
<LI>it doesn't automatically initialize HFS partitions
<LI>it can't install disk drivers
<LI>it allows you to edit the partition map of your boot disk
</UL>
<H3>Where can I get the source?</H3>
<P>The main site for LinuxPPC is
&lt;<A HREF="http://www.linuxppc.org">http://www.linuxppc.org</A>&gt;.
The main site for MkLinux is
&lt;<A HREF="http://www.mklinux.org">http://www.mklinux.org</A>&gt;.
</P>
<H2>Description of the program (as of version 0.8)</H2>
<P>Though pdisk is a Macintosh program its interface is very
un-Macintosh. pdisk is what is called a line-oriented program. In a
line-oriented program you do things by typing on the keyboard and the
program does not pay attention to the typing until the return key has
been typed.</P>
<P>When you start up pdisk it brings up a window with some text in
it. The last line of this text should be something like " Top level
command (? for help): ". This is the prompt. If you type "?" followed
by a return character you should get a list like this:</P>
<PRE>Notes:
Disk have fake names of the form /dev/scsi&lt;bus&gt;.&lt;id&gt;
For example, /dev/scsi0.1, /dev/scsi1.3, and so on.
Linux style names are also allowed (i.e /dev/sda or /dev/hda).
Due to some technical problems these names may not match
the 'real' linux names.
&nbsp;
Commands are:
h print help
v print the version number and release date
l list device's map
L list all devices' maps
e edit device's map
E (edit map with specified block size)
r toggle readonly flag
f toggle show filesystem name flag
q quit the program</PRE>
<P>Some of these commands need what are called arguments - for
example <B>l</B> (list) and <B>e</B> (edit) need a single argument,
the name of the device to list or edit. Commands which take arguments
prompt for each argument in turn. You can also type any number of the
arguments separated by spaces and those prompts will be skipped.
Commands are case insensitive (e.g. <B>h</B> and <B>H</B>) except
when the upper case letter does a variant form of the operation.</P>
<DL>
<DT><B>h</B>
<DD>Prints just the command help. The difference between <B>h</B>
and <B>?</B> is the latter prints some helpful notes as well.
<DT><B>v</B>
<DD>Prints a version number and release date. Matches the
version in the GetInfo window for the application.
<DT><B>l</B>
<DD>Prompts for the name of the device and then lists the
partition map on that device.
<DT><B>L</B>
<DD>Lists all the devices.
<DT><B>e</B>
<DD>Prompts for the name of the device and then opens the partition
map for editing.
<DT><B>E</B>
<DD>Same as <B>e</B>, except also prompts for block size.
<DT><B>r</B>
<DD>Toggles read-only setting. When read-only is on pdisk will not
write a partition map.
<DT><B>f</B>
<DD>Toggles show filesystem name flag between 'show fileystem name' and
'show partition name'. The default is to show the filesystem name. Showing
the filesystem name is helpful when you have several equal sized Macintosh
partitions on the disk.
<DT><B>q</B>
<DD>Quit pdisk.
</DL>
<H3>The form of the listing</H3>
<P>This is a good point to show what the partition map listing looks
like.</P>
<PRE>Partition map (with 512 byte blocks) on '/dev/scsi0.2' (/dev/sda)
#: type name length base ( size )
1: Apple_partition_map Apple 63 @ 1
2: Apple_Driver43*Macintosh 54 @ 64
3: Apple_Driver43*Macintosh 74 @ 118
4: Apple_Patches Patch Partition 512 @ 192
5: Apple_HFS untitled 2117430 @ 704 ( 1.0G)
6: Apple_Free Extra 10 @ 2118134
&nbsp;
Device block size=512, Number of Blocks=2118143
DeviceType=0x0, DeviceId=0x0
Drivers-
1: @ 64 for 20, type=0x1
2: @ 118 for 32, type=0xffff</PRE>
<P>The first line indicates what device this is and what size blocks
the partition map is using. Most partition maps will use 512-byte
blocks, but partition maps can use 1024-byte (1K) or 2048-byte (2K)
blocks instead. If we are able to deduce an Linux name different
from the name then the Linux name is given in parentheses.</P>
<P>Next is the partition list. Each partition (or piece) of the disk
takes one line of the list. The data describing the partition is
called the partition map entry. The entries are listed in order by
index. For each entry, the following information is displayed:</P>
<UL>
<LI>index - where the partition entry is in the map. This does not
correspond the relative order of the partition contents and can
change when the partition map is edited.
<LI>type - the sort of data expected to be in the partition. pdisk
doesn't put data into the contents of any partition except the
partition map partition. The type is a case-insensitive string.
<LI>name - the name is for the user's information. If the name
is in quotes then it is the Mac volume name rather than actual
partition name.
<LI>length - the number of partition blocks the partition takes.
<LI>base - the first block of the partition, measured in partition
blocks, starting from zero.
<LI>size - this is the length in bytes. Only shown if the size is
at least one megabyte.
</UL>
<P>Following the partition list is information from block zero of the
device which describes the location of drivers.</P>
<H3>Editing Partition Tables</H3>
<P>The <B>e</B> command at the top level menu opens a partition map
for editing. The prompt is then changed to "Command (? for help):".
If you type "?" followed by a return character you should get a list
like this:</P>
<PRE>Notes:
Base and length fields are blocks, which vary in size between media.
The name of a partition is descriptive text.
&nbsp;
Commands are:
h help
p print the partition table
P (print ordered by base address)
i initialize partition map
s change size of partition map
c create new partition (standard Linux type)
C (create with type also specified)
n (re)name a partition
d delete a partition
r reorder partition entry in map
w write the partition table
q quit editing (don't save changes)</PRE>
<P>Commands which take arguments prompt for each argument in turn.
You can also type any number of the arguments separated by spaces and
those prompts will be skipped. The only exception to typeahead are
the confirmation prompts on the <B>i</B> and <B>w</B> commands.
Commands can are case insensitive (e.g. <B>h</B> and <B>H</B>) except
when the upper case letter does a variant form of the operation.</P>
<P>Partitions are always specified by their number, which the index
of the partition entry in the partition map. Many of the commands
will change the index numbers of other partitions besides the
affected partition. You are advised to print the table as frequently
as necessary.</P>
<P>Creating more than fifteen partitions is not advised. There is
currently a bug in the some (all?) of the kernels which causes access
to the whole disk fail if more than fifteen partitions are in the
map.</P>
<DL>
<DT><B>h</B>
<DD>Prints just the command help. The difference between <B>h</B>
and <B>?</B> is the latter prints some helpful notes as well.
<DT><B>p</B>
<DD>Prints the partition table. The form is identical to the
listing described above.
<DT><B>P</B>
<DD>Identical to <B>p</B>, except the entries are listed in the
order of the partitions on the disk (i.e. by the increasing base
value) rather than in index order.
<DT><B>i</B>
<DD>Initializes the partition map (rarely used). This command
prompts for the size of the device. WARNING - if you write the map
after initializing it you will delete all the drivers on the device.
That makes the device invisible to the Mac OS. pdisk is not able
to install drivers.
<DT><B>s</B>
<DD>Change the size of the partition map partition. The partition
map's size must be less than or equal to the size of the partition
it is contained in. This is mostly useful when you want to do
tricky things like making a disk with multiple partitioning
schemes on it.
<DT><B>c</B>
<DD>Create a new partition takes three arguments.<BR>
The first argument is the base address (in partition blocks) of
the partition. Besides a raw number, you can also specify a
partition number followed by the letter 'p' to indicate that the
first block of the new partition should be the same as the first
block of that existing free space partition.<BR>
The second argument is the length of the partition in partition
blocks. This can be a raw number or can be a partition number
followed by the letter 'p' to use the size of that partition or
can be a number followed by 'k', 'm', or 'g' to indicate the size
in kilobytes, megabytes, or gigabytes respectively. (These are
powers of 1024, of course, not powers of 1000.)<BR>
The last argument is the name of the partition. This can be a
single word without quotes, or a string surrounded by single or
double quotes.<BR>
The type of the created partition is set to the correct type for
Linux ("Apple_UNIX_SVR2").
<DT><B>C</B>
<DD>Identical to the <B>c</B> command, with the addition of a
prompt for the partition type after the other arguments. The type
can be a single word without quotes, or a string surrounded by
single or double quotes.
<DT><B>n</B>
<DD>Rename a partition. Do not change the name of any partition
whose type starts with "Apple_Driver". The MacOS looks at the
names of those partitions. All other partitions should be okay
to change.
<DT><B>d</B>
<DD>Delete a partition. When a partition is deleted it's type is
changed to free ("Apple_Free") and then it is combined with any
adjacent free space.
<DT><B>r</B>
<DD>Reorder takes the current index and the desired new index. If
you give a new index which is greater than the last index the
entry will be moved to the last index.
<DT><B>w</B>
<DD>Write does write the partition map out, but pdisk does not yet
flush the appropriate caches and unmount volumes so the partition
map is not reinterpreted. In order to use the new partition map
you must reboot your machine. Sorry.
<DT><B>q</B>
<DD>Quit out of editing. Returns to the top level prompt. If you
have modified the partition map you are NOT asked if you want to
save the changes, instead the changes are quietly thrown away.
</DL>
<H3>Known problems</H3>
<DL>
<DD>This is an awful Mac OS application, it should be rewritten
to look the way a Mac OS app should look.
<DD>The code assumes a better understanding of the partitioning
scheme than most people care to acquire.
<DD>&nbsp;
<DD>Even more help should be available during user input.
</DL>
<P>
<HR>
</P>
<ADDRESS><A HREF="mailto:eryk@cfcl.com">eryk@cfcl.com</A>
</ADDRESS>
</BODY>
</HTML>

234
dist/pdisk/pdisk.r vendored
View File

@ -1,234 +0,0 @@
/*
* pdisk.r
*/
/*
* Copyright 1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef SystemSevenOrLater
#define SystemSevenOrLater 1
#endif
#include "Types.r"
#include "SysTypes.r"
#include "version.h"
resource 'vers' (1) {
kVersionMajor,
kVersionMinor*0x10 + kVersionBugFix,
kVersionStage,
kVersionDelta,
verUS,
VERSION,
$$format(
"%s - %4d%02d%02d "
"© 1992-1998 Apple Computer Inc. All Rights Reserved. Modifications © %4d Eryk Vershen",
VERSION, $$year, $$month, $$day,
$$year
),
};
type 'PDSK' as 'STR ';
resource 'PDSK' (0, "Owner Resource", purgeable) {
$$format(
"pdisk\n© 1992-1998 Apple Computer Inc. All Rights Reserved. Modifications © %4d Eryk Vershen",
$$year
)
};
resource 'BNDL' (128) {
'PDSK',
0,
{
'FREF', { 0, 128 },
'ICN#', { 0, 128 }
}
};
resource 'FREF' (128) {
'APPL',
0,
""
};
resource 'icl8' (128) {
$"FFFF FFFF FFFF FFFF FFFF FFFF 0000 0000"
$"0000 FFFF FFFF FFFF 0000 0000 0000 0000"
$"FF2B 2B2B 2B2B 2B2B 2B2B 2BFF 0000 0000"
$"00FF 0808 0808 0808 FF00 0000 0000 0000"
$"FF2B 2B2B 2B2B 2B2B 2B2B FF00 0000 0000"
$"FF08 0808 0808 0808 08FF 0000 0000 0000"
$"FFFC FCFC FCFC FCFC FCFC FF00 0000 00FF"
$"0808 FFFF 0808 0808 0808 FF00 0000 0000"
$"FF00 0000 0000 0000 0000 FF00 0000 00FF"
$"FFFF 0000 FF08 0808 0808 08FF 0000 0000"
$"FF2B 2B2B 2B2B 2B2B 2B2B FF00 FFFF FF08"
$"08FF FFFF FFFF FFFF FF08 0808 FFFF FFFF"
$"FF2B 2B2B 2B2B 2B2B 2B2B FF00 0000 FF08"
$"0808 FFFF 0808 0808 0808 0808 08FF FFFF"
$"FFFF FFFF FFFF FFFF FFFF FF00 0000 00FF"
$"0808 0808 0808 0808 0808 0808 08FF FFFF"
$"00FF F7FC F7FC F7FC F7FF 0000 0000 0000"
$"FF08 0808 0808 0808 0808 0808 08FF FFFF"
$"00FF FFFF FBFB FBFF FFFF 0000 0000 0000"
$"00FF FF08 0808 0808 0808 0808 08FF FFFF"
$"0000 0000 FFFF FF00 0000 0000 0000 0000"
$"0000 00FF FFFF FFFF FFFF FF08 08FF FFFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 0000 0000 00FF FFFF FFFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 0000 0000 0000 00FF FFFF"
$"0000 0000 0000 0000 FFFF FFFF FFFF FFFF"
$"FFFF FFFF FFFF FF00 0000 0000 0000 0000"
$"0000 0000 0000 0000 FF2B 2B2B 2B2B 2B2B"
$"2B2B 2B2B 2B2B FF00 0000 0000 0000 0000"
$"0000 0000 0000 00FF 2B2B 2B2B 2B2B 2B2B"
$"2B2B 2B2B 2B2B FF00 0000 0000 0000 0000"
$"0000 0000 0000 00FF FCFC FCFC FCFC FCFC"
$"FCFC FCFC FCFC FF00 0000 0000 0000 0000"
$"0000 0000 0000 00FF 0000 0000 0000 0000"
$"0000 0000 0000 FF00 0000 0000 0000 0000"
$"0000 0000 0000 00FF 2B2B 2B2B 2B2B 2B2B"
$"2B2B 2B2B 2BFF 0000 0000 0000 0000 0000"
$"0000 0000 0000 00FF 2B2B 2B2B 2B2B 2B2B"
$"2B2B 2B2B FF00 0000 0000 0000 0000 0000"
$"0000 0000 0000 00FF FFFF FFFF FFFF FFFF"
$"FFFF FFFF FF00 0000 0000 0000 0000 0000"
$"0000 0000 0000 FFFC F7FC F7FC F7FC F7FC"
$"F7FC F7FC FF00 00FF FFFF FFFF FFFF FFFF"
$"0000 0000 0000 FFFF FFFF FFFF FFFF FFFF"
$"FFFF FFFF FF00 00FF 2B2B 2B2B 2B2B 2BFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 00FF 2B2B 2B2B 2B2B 2BFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 00FF FCFC E3E3 E3FC FCFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 00FF 0000 0000 0000 00FF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 FF2B 2B2B 2B2B 2B2B 2BFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 00FF 2B2B 2B2B 2B2B 2B2B 2BFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 00FF FFFF FFFF FFFF FFFF FFFF"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 00FF F7FC F7FC F7FC F7FC FF00"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 00FF FFFF FFFB FBFB FFFF FF00"
$"0000 0000 0000 0000 0000 0000 0000 0000"
$"0000 0000 0000 0000 00FF FFFF"
};
resource 'icl4' (128) {
$"FFFF FFFF FFFF 0000 00FF FFFF 0000 0000"
$"FCCC CCCC CCCF 0000 0F02 0202 F000 0000"
$"FCCC CCCC CCF0 0000 F020 2020 2F00 0000"
$"FEEE EEEE EEF0 000F 02FF 0202 02F0 0000"
$"F000 0000 00F0 000F FF00 F020 202F 0000"
$"FCCC CCCC CCF0 FFF2 0FFF FFFF F202 FFFF"
$"FCCC CCCC CCF0 00F0 20FF 2020 2020 2FFF"
$"FFFF FFFF FFF0 000F 0202 0202 0202 0FFF"
$"0FCE CECE CF00 0000 F020 2020 2020 2FFF"
$"0FFF EEEF FF00 0000 0FF2 0202 0202 0FFF"
$"0000 FFF0 0000 0000 000F FFFF FFF0 2FFF"
$"0000 0000 0000 0000 0000 0000 000F FFFF"
$"0000 0000 0000 0000 0000 0000 0000 0FFF"
$"0000 0000 FFFF FFFF FFFF FFF0 0000 0000"
$"0000 0000 FCCC CCCC CCCC CCF0 0000 0000"
$"0000 000F CCCC CCCC CCCC CCF0 0000 0000"
$"0000 000F EEEE EEEE EEEE EEF0 0000 0000"
$"0000 000F 0000 0000 0000 00F0 0000 0000"
$"0000 000F CCCC CCCC CCCC CF00 0000 0000"
$"0000 000F CCCC CCCC CCCC F000 0000 0000"
$"0000 000F FFFF FFFF FFFF F000 0000 0000"
$"0000 00FE CECE CECE CECE F00F FFFF FFFF"
$"0000 00FF FFFF FFFF FFFF F00F CCCC CCCF"
$"0000 0000 0000 0000 0000 000F CCCC CCCF"
$"0000 0000 0000 0000 0000 000F EE88 8EEF"
$"0000 0000 0000 0000 0000 000F 0000 000F"
$"0000 0000 0000 0000 0000 00FC CCCC CCCF"
$"0000 0000 0000 0000 0000 0FCC CCCC CCCF"
$"0000 0000 0000 0000 0000 0FFF FFFF FFFF"
$"0000 0000 0000 0000 0000 0FCE CECE CEF0"
$"0000 0000 0000 0000 0000 0FFF FEEE FFF0"
$"0000 0000 0000 0000 0000 0000 0FFF"
};
resource 'ICN#' (128) {
{
/* 1 */ $"FFF0 3F00 8010 4080 8020 8040 FFE1 3020"
$"8021 C810 802E 7F8F 8022 3007 FFE1 0007"
$"5540 8007 7FC0 6007 0E00 1FE7 0000 001F"
$"0000 0007 00FF FE00 0080 0200 0100 0200"
$"01FF FE00 0100 0200 0100 0400 0100 0800"
$"01FF F800 0355 59FF 03FF F901 0000 0101"
$"0000 01FF 0000 0101 0000 0201 0000 0401"
$"0000 07FF 0000 0556 0000 07FE 0000 0070",
/* 2 */ $"FFF0 3F00 FFF0 7F80 FFE0 FFC0 FFE1 FFE0"
$"FFE1 FFF0 FFEF FFFF FFE3 FFFF FFE1 FFFF"
$"7FC0 FFFF 7FC0 7FFF 0E00 1FFF 0000 001F"
$"0000 0007 00FF FE00 00FF FE00 01FF FE00"
$"01FF FE00 01FF FE00 01FF FC00 01FF F800"
$"01FF F800 03FF F9FF 03FF F9FF 0000 01FF"
$"0000 01FF 0000 01FF 0000 03FF 0000 07FF"
$"0000 07FF 0000 07FE 0000 07FE 0000 0070"
}
};
resource 'ics#' (128) {
{
/* 1 */ $"FC30 8448 B4A7 8B7B 7083 007F 0003 1FF0"
$"1010 1010 2020 3FDF 0011 0011 0021 003E",
/* 2 */ $"FC30 FC78 FCFF FBFF 70FF 007F 0003 1FF0"
$"1FF0 1FF0 3FE0 3FDF 001F 001F 003F 003E"
}
};
resource 'ics4' (128) {
$"FFFF FF00 00FF 0000 FCCC CF00 0F02 F000"
$"FC38 CF00 F0F0 2FFF FDDD F0FF 2FFF F2FF"
$"0FFF 0000 F020 20FF 0000 0000 0FFF FFFF"
$"0000 0000 0000 00FF 000F FFFF FFFF 0000"
$"000F CCCC CCCF 0000 000F CCCC CCCF 0000"
$"00FD DDDD DDF0 0000 00FF FFFF FF0F FFFF"
$"0000 0000 000F CCCF 0000 0000 000F CCCF"
$"0000 0000 00FD DDDF 0000 0000 00FF FFF0"
};
resource 'ics8' (128) {
$"FFFF FFFF FFFF 0000 0000 FFFF 0000 0000"
$"FF2B 2B2B 2BFF 0000 00FF 0808 FF00 0000"
$"FF2B D8E3 2BFF 0000 FF08 FF08 08FF FFFF"
$"FFF9 F9F9 FF00 FFFF 08FF FFFF FF08 FFFF"
$"00FF FFFF 0000 0000 FF08 0808 0808 FFFF"
$"0000 0000 0000 0000 00FF FFFF FFFF FFFF"
$"0000 0000 0000 0000 0000 0000 0000 FFFF"
$"0000 00FF FFFF FFFF FFFF FFFF 0000 0000"
$"0000 00FF 2B2B 2B2B 2B2B 2BFF 0000 0000"
$"0000 00FF 2B2B 2B2B 2B2B 2BFF 0000 0000"
$"0000 FFF9 F9F9 F9F9 F9F9 FF00 0000 0000"
$"0000 FFFF FFFF FFFF FFFF 00FF FFFF FFFF"
$"0000 0000 0000 0000 0000 00FF 2B2B 2BFF"
$"0000 0000 0000 0000 0000 00FF 2B2B 2BFF"
$"0000 0000 0000 0000 0000 FFF9 F9F9 F9FF"
$"0000 0000 0000 0000 0000 FFFF FFFF FF"
};

165
dist/pdisk/util.c vendored
View File

@ -1,165 +0,0 @@
/*
* util.c -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for sprintf()
#include <stdio.h>
// for tolower()
#include <ctype.h>
#include <stdint.h>
#include "version.h"
#include "util.h"
/*
* Defines
*/
#define NumToolboxTraps() ( \
(NGetTrapAddress(_InitGraf, ToolTrap) \
== NGetTrapAddress(0xAA6E, ToolTrap)) \
? 0x200 : 0x400 \
)
#define GetTrapType(theTrap) ( \
(((theTrap) & 0x800) != 0) ? ToolTrap : OSTrap \
)
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
static char dynamic_version[10];
/*
* Forward declarations
*/
/*
* Routines
*/
void
clear_memory(void *dataPtr, uint32_t size)
{
char *ptr;
ptr = (char *) dataPtr;
while (size > 0) {
*ptr++ = 0;
--size;
}
}
#if !defined(__linux__) && !defined(__unix__)
/* (see Inside Mac VI 3-8) */
int
TrapAvailable(short theTrap)
{
TrapType trapType;
trapType = GetTrapType(theTrap);
if (trapType == ToolTrap) {
theTrap &= 0x07FF;
if (theTrap >= NumToolboxTraps())
theTrap = _Unimplemented;
}
return (
NGetTrapAddress(theTrap, trapType)
!= NGetTrapAddress(_Unimplemented, ToolTrap)
);
}
#endif
/* Ascii case-insensitive string comparison */
int
istrncmp(const char *x, const char *y, long len)
{
const uint8_t *p = (const uint8_t *)x;
const uint8_t *q = (const uint8_t *)y;
while (len > 0) {
if (tolower(*p) != tolower(*q)) {
return (*p - *q);
} else if (*p == 0) {
break;
}
p++;
q++;
len--;
}
return (0);
}
const char *
get_version_string(void)
{
int stage;
/* "copy" of stuff from SysTypes.r, since we can't include that*/
enum {development = 0x20, alpha = 0x40, beta = 0x60, final = 0x80, /* or */ release = 0x80};
switch (kVersionStage) {
case development: stage = 'd'; break;
case alpha: stage = 'a'; break;
case beta: stage = 'b'; break;
case final: stage = 'f'; break;
default: stage = '?'; break;
}
if (kVersionBugFix != 0) {
if (kVersionStage == final) {
snprintf(dynamic_version, sizeof(dynamic_version), "%d.%d.%d",
kVersionMajor, kVersionMinor, kVersionBugFix);
} else {
snprintf(dynamic_version, sizeof(dynamic_version), "%d.%d.%d%c%d",
kVersionMajor, kVersionMinor, kVersionBugFix, stage, kVersionDelta);
}
} else {
if (kVersionStage == final) {
snprintf(dynamic_version, sizeof(dynamic_version), "%d.%d",
kVersionMajor, kVersionMinor);
} else {
snprintf(dynamic_version, sizeof(dynamic_version), "%d.%d%c%d",
kVersionMajor, kVersionMinor, stage, kVersionDelta);
}
}
return dynamic_version;
}

62
dist/pdisk/util.h vendored
View File

@ -1,62 +0,0 @@
/*
* util.h -
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __util__
#define __util__
/*
* Defines
*/
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
void clear_memory(void *dataPtr, uint32_t size);
#if !defined(__linux__) && !defined(__unix__)
int TrapAvailable(short theTrap);
#endif
int istrncmp(const char *x, const char *y, long len);
const char *get_version_string(void);
#endif /* __util__ */

508
dist/pdisk/validate.c vendored
View File

@ -1,508 +0,0 @@
//
// validate.c -
//
// Written by Eryk Vershen
//
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// for *printf()
#include <stdio.h>
// for malloc(), free()
#ifndef __linux__
#include <stdlib.h>
#else
#include <malloc.h>
#endif
// for O_RDONLY
#include <fcntl.h>
// for errno
#include <errno.h>
#include <inttypes.h>
#include "validate.h"
#include "deblock_media.h"
#include "pathname.h"
#include "convert.h"
#include "io.h"
#include "errors.h"
//
// Defines
//
//
// Types
//
enum range_state {
kUnallocated,
kAllocated,
kMultiplyAllocated
};
struct range_list {
struct range_list *next;
struct range_list *prev;
enum range_state state;
int valid;
uint32_t start;
uint32_t end;
};
typedef struct range_list range_list;
//
// Global Constants
//
//
// Global Variables
//
static char *buffer;
static Block0 *b0;
static DPME *mb;
static partition_map_header *the_map;
static MEDIA the_media;
static int g;
//
// Forward declarations
//
int get_block_zero(void);
int get_block_n(int n);
range_list *new_range_list_item(enum range_state state, int valid, uint32_t low, uint32_t high);
void initialize_list(range_list **list);
void add_range(range_list **list, uint32_t base, uint32_t len, int allocate);
void print_range_list(range_list *list);
void delete_list(range_list *list);
void coalesce_list(range_list *list);
//
// Routines
//
int
get_block_zero(void)
{
int rtn_value;
if (the_map != NULL) {
b0 = the_map->misc;
rtn_value = 1;
} else {
if (read_media(the_media, (long long) 0, PBLOCK_SIZE, buffer) == 0) {
rtn_value = 0;
} else {
b0 = (Block0 *) buffer;
convert_block0(b0, 1);
rtn_value = 1;
}
}
return rtn_value;
}
int
get_block_n(int n)
{
partition_map * entry;
int rtn_value;
if (the_map != NULL) {
entry = find_entry_by_disk_address(n, the_map);
if (entry != 0) {
mb = entry->data;
rtn_value = 1;
} else {
rtn_value = 0;
}
} else {
if (read_media(the_media, ((long long) n) * g, PBLOCK_SIZE, (void *)buffer) == 0) {
rtn_value = 0;
} else {
mb = (DPME *) buffer;
convert_dpme(mb, 1);
rtn_value = 1;
}
}
return rtn_value;
}
range_list *
new_range_list_item(enum range_state state, int valid, uint32_t low, uint32_t high)
{
range_list *item;
item = (range_list *) malloc(sizeof(struct range_list));
item->next = 0;
item->prev = 0;
item->state = state;
item->valid = valid;
item->start = low;
item->end = high;
return item;
}
void
initialize_list(range_list **list)
{
range_list *item;
item = new_range_list_item(kUnallocated, 0, 0, 0xFFFFFFFF);
*list = item;
}
void
delete_list(range_list *list)
{
range_list *item;
range_list *cur;
for (cur = list; cur != 0; ) {
item = cur;
cur = cur->next;
free(item);
}
}
void
add_range(range_list **list, uint32_t base, uint32_t len, int allocate)
{
range_list *item;
range_list *cur;
uint32_t low;
uint32_t high;
if (list == 0 || *list == 0) {
/* XXX initialized list will always have one element */
return;
}
low = base;
high = base + len - 1;
if (len == 0 || high < len - 1) {
/* XXX wrapped around */
return;
}
cur = *list;
while (low <= high) {
if (cur == 0) {
/* XXX should never occur */
break;
}
if (low <= cur->end) {
if (cur->start < low) {
item = new_range_list_item(cur->state, cur->valid, cur->start, low-1);
/* insert before here */
if (cur->prev == 0) {
item->prev = 0;
*list = item;
} else {
item->prev = cur->prev;
item->prev->next = item;
}
cur->prev = item;
item->next = cur;
cur->start = low;
}
if (high < cur->end) {
item = new_range_list_item(cur->state, cur->valid, high+1, cur->end);
/* insert after here */
if (cur->next == 0) {
item->next = 0;
} else {
item->next = cur->next;
item->next->prev = item;
}
cur->next = item;
item->prev = cur;
cur->end = high;
}
if (allocate) {
switch (cur->state) {
case kUnallocated:
cur->state = kAllocated;
break;
case kAllocated:
case kMultiplyAllocated:
cur->state = kMultiplyAllocated;
break;
}
} else {
cur->valid = 1;
}
low = cur->end + 1;
}
cur = cur->next;
}
}
void
coalesce_list(range_list *list)
{
range_list *cur;
range_list *item;
for (cur = list; cur != 0; ) {
item = cur->next;
if (item == 0) {
break;
}
if (cur->valid == item->valid
&& cur->state == item->state) {
cur->end = item->end;
cur->next = item->next;
if (item->next != 0) {
item->next->prev = cur;
}
free(item);
} else {
cur = cur->next;
}
}
}
void
print_range_list(range_list *list)
{
range_list *cur;
int printed;
const char *s;
s = NULL; /* XXXGCC -Wuninitialized [powerpc] */
if (list == 0) {
printf("Empty range list\n");
return;
}
printf("Range list:\n");
printed = 0;
for (cur = list; cur != 0; cur = cur->next) {
if (cur->valid) {
switch (cur->state) {
case kUnallocated:
s = "unallocated";
break;
case kAllocated:
continue;
//s = "allocated";
//break;
case kMultiplyAllocated:
s = "multiply allocated";
break;
}
printed = 1;
printf("\t%"PRIu32":%"PRIu32" %s\n", cur->start, cur->end, s);
} else {
switch (cur->state) {
case kUnallocated:
continue;
//s = "unallocated";
//break;
case kAllocated:
s = "allocated";
break;
case kMultiplyAllocated:
s = "multiply allocated";
break;
}
printed = 1;
printf("\t%"PRIu32":%"PRIu32" out of range, but %s\n", cur->start, cur->end, s);
}
}
if (printed == 0) {
printf("\tokay\n");
}
}
void
validate_map(partition_map_header *map)
{
range_list *list;
char *name;
uint32_t i;
uint32_t limit;
int printed;
//printf("Validation not implemented yet.\n");
if (map == NULL) {
the_map = 0;
if (get_string_argument("Name of device: ", &name, 1) == 0) {
bad_input("Bad name");
return;
}
the_media = open_pathname_as_media(name, O_RDONLY);
if (the_media == 0) {
error(errno, "can't open file '%s'", name);
free(name);
return;
}
g = media_granularity(the_media);
if (g < PBLOCK_SIZE) {
g = PBLOCK_SIZE;
}
the_media = open_deblock_media(PBLOCK_SIZE, the_media);
buffer = malloc(PBLOCK_SIZE);
if (buffer == NULL) {
error(errno, "can't allocate memory for disk buffer");
goto done;
}
} else {
name = 0;
the_map = map;
g = map->logical_block;
}
initialize_list(&list);
// get block 0
if (get_block_zero() == 0) {
printf("unable to read block 0\n");
goto check_map;
}
// XXX signature valid
// XXX size & count match DeviceCapacity
// XXX number of descriptors matches array size
// XXX each descriptor wholly contained in a partition
// XXX the range below here is in physical blocks but the map is in logical blocks!!!
add_range(&list, 1, b0->sbBlkCount-1, 0); /* subtract one since args are base & len */
check_map:
// compute size of map
if (map != NULL) {
limit = the_map->blocks_in_map;
} else {
if (get_block_n(1) == 0) {
printf("unable to get first block\n");
goto done;
} else {
if (mb->dpme_signature != DPME_SIGNATURE) {
limit = -1;
} else {
limit = mb->dpme_map_entries;
}
}
}
// for each entry
for (i = 1; ; i++) {
#if 0
if (limit < 0) {
/* XXX what to use for end of list? */
if (i > 5) {
break;
}
} else
#endif
if (i > limit) {
break;
}
printf("block %d:\n", i);
// get entry
if (get_block_n(i) == 0) {
printf("\tunable to get\n");
goto post_processing;
}
printed = 0;
// signature matches
if (mb->dpme_signature != DPME_SIGNATURE) {
printed = 1;
printf("\tsignature is 0x%x, should be 0x%x\n", mb->dpme_signature, DPME_SIGNATURE);
}
// reserved1 == 0
if (mb->dpme_reserved_1 != 0) {
printed = 1;
printf("\treserved word is 0x%x, should be 0\n", mb->dpme_reserved_1);
}
// entry count matches
#if 0
if (limit < 0) {
printed = 1;
printf("\tentry count is 0x%"PRIx32", real value unknown\n", mb->dpme_map_entries);
} else
#endif
if (mb->dpme_map_entries != limit) {
printed = 1;
printf("\tentry count is 0x%"PRIx32", should be %"PRId32"\n", mb->dpme_map_entries, limit);
}
// lblocks contained within physical
if (mb->dpme_lblock_start >= mb->dpme_pblocks
|| mb->dpme_lblocks > mb->dpme_pblocks - mb->dpme_lblock_start) {
printed = 1;
printf("\tlogical blocks (%"PRId32" for %"PRId32") not within physical size (%"PRId32")\n",
mb->dpme_lblock_start, mb->dpme_lblocks, mb->dpme_pblocks);
}
// remember stuff for post processing
add_range(&list, mb->dpme_pblock_start, mb->dpme_pblocks, 1);
// XXX type is known type?
// XXX no unknown flags?
// XXX boot blocks either within or outside of logical
// XXX checksum matches contents
// XXX other fields zero if boot_bytes is zero
// XXX processor id is known value?
// XXX no data in reserved3
if (printed == 0) {
printf("\tokay\n");
}
}
post_processing:
// properties of whole map
// every block on disk in one & only one partition
coalesce_list(list);
print_range_list(list);
// there is a partition for the map
// map fits within partition that contains it
// try to detect 512/2048 mixed partition map?
done:
if (map == NULL) {
close_media(the_media);
free(buffer);
free(name);
}
}

59
dist/pdisk/validate.h vendored
View File

@ -1,59 +0,0 @@
//
// validate.h -
//
// Written by Eryk Vershen
//
/*
* Copyright 1997,1998 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __validate__
#define __validate__
#include "partition_map.h"
//
// Defines
//
//
// Types
//
//
// Global Constants
//
//
// Global Variables
//
//
// Forward declarations
//
void validate_map(partition_map_header *map);
#endif /* __validate__ */

82
dist/pdisk/version.h vendored
View File

@ -1,82 +0,0 @@
/*
* version.h - version number for pdisk program
*
* Written by Eryk Vershen
*/
/*
* Copyright 1997 by Apple Computer, Inc.
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation.
*
* APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
* NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __version__
#define __version__
/*
* Defines
*/
/*
* TO ADJUST THE VERSION - change the following six macros.
*
* A version is of the form: N.M{.X}{yZ}
*
* N is two digits indicating the major version
* M is a single digit indicating relative revision
* X is a single digit indicating a bug fix revision
* y is a character from the set [dab] indicating stage (dev,alpha,beta)
* Z is two digits indicating the delta within the stage
*
* Note that within the 'vers' resource all these fields end up
* comprising a four byte uint32_teger with the property that any later
* version will be be represented by a larger number.
*/
#define VERSION "0.8a2"
#define RELEASE_DATE "16 May 2000"
#define kVersionMajor 0x00 /* ie. N has two BCD digits */
#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 0x02 /* ie. Z has two BCD digits */
/*
* Types
*/
/*
* Global Constants
*/
/*
* Global Variables
*/
/*
* Forward declarations
*/
#endif /* __version__ */