mirror of
https://github.com/fadden/ciderpress.git
synced 2025-01-25 15:30:06 +00:00
Change tabs to spaces, use Linux EOL
No substantative changes (unless the tabs-to-spaces messed something up).
This commit is contained in:
parent
683eb05a82
commit
090797a76f
@ -1,491 +1,491 @@
|
||||
/*
|
||||
* CiderPress
|
||||
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
||||
* See the file LICENSE for distribution terms.
|
||||
*/
|
||||
/*
|
||||
* Convert from one image format to another.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include "../diskimg/DiskImg.h"
|
||||
#include "../nufxlib/NufxLib.h"
|
||||
|
||||
using namespace DiskImgLib;
|
||||
|
||||
#define nil NULL
|
||||
#define ASSERT assert
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
FILE* gLog = nil;
|
||||
pid_t gPid = getpid();
|
||||
|
||||
|
||||
/*
|
||||
* Handle a debug message from the DiskImg library.
|
||||
*/
|
||||
/*static*/ void
|
||||
MsgHandler(const char* file, int line, const char* msg)
|
||||
{
|
||||
ASSERT(file != nil);
|
||||
ASSERT(msg != nil);
|
||||
|
||||
fprintf(gLog, "%05u %s", gPid, msg);
|
||||
}
|
||||
/*
|
||||
* Handle a global error message from the NufxLib library by shoving it
|
||||
* through the DiskImgLib message function.
|
||||
*/
|
||||
NuResult
|
||||
NufxErrorMsgHandler(NuArchive* /*pArchive*/, void* vErrorMessage)
|
||||
{
|
||||
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
|
||||
|
||||
if (pErrorMessage->isDebug) {
|
||||
Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line,
|
||||
"<nufxlib> [D] %s\n", pErrorMessage->message);
|
||||
} else {
|
||||
Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line,
|
||||
"<nufxlib> %s\n", pErrorMessage->message);
|
||||
}
|
||||
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert one disk image to another.
|
||||
*/
|
||||
DIError
|
||||
Convert(const char* infile, const char* outfile)
|
||||
{
|
||||
DIError dierr = kDIErrNone;
|
||||
DiskImg srcImg, dstImg;
|
||||
const char* storageName = nil;
|
||||
|
||||
printf("Converting in='%s' out='%s'\n", infile, outfile);
|
||||
|
||||
/*
|
||||
* Prepare the source image.
|
||||
*/
|
||||
dierr = srcImg.OpenImage(infile, '/', true);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Unable to open disk image: %s.\n",
|
||||
DiskImgLib::DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dierr = srcImg.AnalyzeImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Unable to determine source image format.\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (!srcImg.GetHasBlocks() && !srcImg.GetHasSectors()) {
|
||||
/* add nibble tracks someday */
|
||||
fprintf(stderr,
|
||||
"Sorry, only block- or sector-addressable images allowed.\n");
|
||||
dierr = kDIErrUnsupportedPhysicalFmt;
|
||||
goto bail;
|
||||
}
|
||||
if (srcImg.GetHasBlocks()) {
|
||||
assert(srcImg.GetNumBlocks() > 0);
|
||||
} else {
|
||||
assert(srcImg.GetNumTracks() > 0);
|
||||
}
|
||||
|
||||
if (srcImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) {
|
||||
fprintf(stderr, "(QUERY) don't know sector order\n");
|
||||
dierr = kDIErrFilesystemNotFound;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
storageName = "MyHappyDisk";
|
||||
|
||||
/* force the access to be ProDOS-ordered */
|
||||
dierr = srcImg.OverrideFormat(srcImg.GetPhysicalFormat(),
|
||||
DiskImg::kFormatGenericProDOSOrd, srcImg.GetSectorOrder());
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Couldn't switch to generic ProDOS: %s.\n",
|
||||
DiskImgLib::DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* transfer the DOS volume num, if one was set */
|
||||
printf("DOS volume number set to %d\n", srcImg.GetDOSVolumeNum());
|
||||
dstImg.SetDOSVolumeNum(srcImg.GetDOSVolumeNum());
|
||||
|
||||
const DiskImg::NibbleDescr* pNibbleDescr;
|
||||
pNibbleDescr = nil;
|
||||
|
||||
/*
|
||||
* Prepare the destination image.
|
||||
*
|
||||
* We *always* use DiskImg::kFormatGenericProDOSOrd here, because it
|
||||
* must match up with what we selected above.
|
||||
*
|
||||
* We could enable "skipFormat" on all of these but the nibble images,
|
||||
* but we go ahead and set it to "false" on all of them just for fun.
|
||||
*/
|
||||
switch (18) {
|
||||
case 0:
|
||||
/* 16-sector nibble image, by blocks */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 1:
|
||||
/* 16-sector nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 2:
|
||||
/* 16-sector NB2 nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6384,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 3:
|
||||
/* 13-sector nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS32Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 13,
|
||||
false);
|
||||
break;
|
||||
case 4:
|
||||
/* 16-sector nb2 image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6384,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 5:
|
||||
/* sector image, by blocks, ProDOS order */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 6:
|
||||
/* sector image, by blocks, DOS order */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 7:
|
||||
/* sector image, by blocks, ProDOS order, Sim2e */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatSim2eHDV,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 8:
|
||||
/* odd-length HUGE sector image, by blocks */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
65535,
|
||||
false);
|
||||
break;
|
||||
case 9:
|
||||
/* sector image, by blocks, physical order, with gzip */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatGzip,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 10:
|
||||
/* sector image, by blocks, ProDOS order, with gzip */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatGzip,
|
||||
DiskImg::kFileFormatSim2eHDV,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 11:
|
||||
/* sector image, by blocks, ProDOS order, 2MG */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormat2MG,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 12:
|
||||
/* 16-sector nibble image, by tracks/sectors, 2MG */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormat2MG,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 13:
|
||||
/* 16-sector nibble image, by tracks/sectors, 2MG, gzip */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatGzip,
|
||||
DiskImg::kFileFormat2MG,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 14:
|
||||
/* sector image, by blocks, for DC42 (800K only) */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatDiskCopy42,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 15:
|
||||
/* sector image, by blocks, for NuFX */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatNuFX,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 16:
|
||||
/* sector image, by blocks, for DDD */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatDDD,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 17:
|
||||
/* sector image, by blocks, ProDOS order, stored in ZIP (.po.zip) */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatZip,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 18:
|
||||
/* 13-sector nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 13,
|
||||
false);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "UNEXPECTED NUMBER\n");
|
||||
abort();
|
||||
}
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Couldn't create new image file '%s': %s.\n",
|
||||
outfile, DiskImgLib::DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy blocks or sectors from source to destination.
|
||||
*/
|
||||
if (srcImg.GetHasBlocks()) {
|
||||
int numBlocks;
|
||||
numBlocks = srcImg.GetNumBlocks();
|
||||
if (dstImg.GetNumBlocks() < srcImg.GetNumBlocks())
|
||||
numBlocks = dstImg.GetNumBlocks();
|
||||
printf("Copying %d blocks\n", numBlocks);
|
||||
|
||||
unsigned char blkBuf[512];
|
||||
for (int block = 0; block < numBlocks; block++) {
|
||||
dierr = srcImg.ReadBlock(block, blkBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: ReadBlock failed (err=%d)\n", dierr);
|
||||
goto bail;
|
||||
}
|
||||
dierr = dstImg.WriteBlock(block, blkBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: WriteBlock failed (err=%d)\n", dierr);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int numTracks, numSectPerTrack;
|
||||
numTracks = srcImg.GetNumTracks();
|
||||
numSectPerTrack = srcImg.GetNumSectPerTrack();
|
||||
if (dstImg.GetNumTracks() < srcImg.GetNumTracks())
|
||||
numTracks = dstImg.GetNumTracks();
|
||||
if (dstImg.GetNumSectPerTrack() < srcImg.GetNumSectPerTrack())
|
||||
numSectPerTrack = dstImg.GetNumSectPerTrack();
|
||||
printf("Copying %d tracks of %d sectors\n", numTracks, numSectPerTrack);
|
||||
|
||||
unsigned char sctBuf[256];
|
||||
for (int track = 0; track < numTracks; track++) {
|
||||
for (int sector = 0; sector < numSectPerTrack; sector++) {
|
||||
dierr = srcImg.ReadTrackSector(track, sector, sctBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr,
|
||||
"WARNING: ReadTrackSector failed on T=%d S=%d (err=%d)\n",
|
||||
track, sector, dierr);
|
||||
dierr = kDIErrNone; // allow bad blocks
|
||||
memset(sctBuf, 0, sizeof(sctBuf));
|
||||
}
|
||||
dierr = dstImg.WriteTrackSector(track, sector, sctBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: WriteBlock failed on T=%d S=%d (err=%d)\n",
|
||||
track, sector, dierr);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dierr = srcImg.CloseImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: srcImg close failed?!\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dierr = dstImg.CloseImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: dstImg close failed (err=%d)\n", dierr);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
assert(dierr == kDIErrNone);
|
||||
bail:
|
||||
return dierr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process every argument.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
const char* kLogFile = "iconv-log.txt";
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "%s: infile outfile\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
gLog = fopen(kLogFile, "w");
|
||||
if (gLog == nil) {
|
||||
fprintf(stderr, "ERROR: unable to open log file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Image Converter for Linux v1.0\n");
|
||||
printf("Copyright (C) 2014 by faddenSoft. All rights reserved.\n");
|
||||
int32_t major, minor, bug;
|
||||
Global::GetVersion(&major, &minor, &bug);
|
||||
printf("Linked against DiskImg library v%d.%d.%d\n",
|
||||
major, minor, bug);
|
||||
printf("Log file is '%s'\n", kLogFile);
|
||||
printf("\n");
|
||||
|
||||
Global::SetDebugMsgHandler(MsgHandler);
|
||||
Global::AppInit();
|
||||
|
||||
NuSetGlobalErrorMessageHandler(NufxErrorMsgHandler);
|
||||
|
||||
Convert(argv[1], argv[2]);
|
||||
|
||||
Global::AppCleanup();
|
||||
fclose(gLog);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* CiderPress
|
||||
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
||||
* See the file LICENSE for distribution terms.
|
||||
*/
|
||||
/*
|
||||
* Convert from one image format to another.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include "../diskimg/DiskImg.h"
|
||||
#include "../nufxlib/NufxLib.h"
|
||||
|
||||
using namespace DiskImgLib;
|
||||
|
||||
#define nil NULL
|
||||
#define ASSERT assert
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
FILE* gLog = nil;
|
||||
pid_t gPid = getpid();
|
||||
|
||||
|
||||
/*
|
||||
* Handle a debug message from the DiskImg library.
|
||||
*/
|
||||
/*static*/ void
|
||||
MsgHandler(const char* file, int line, const char* msg)
|
||||
{
|
||||
ASSERT(file != nil);
|
||||
ASSERT(msg != nil);
|
||||
|
||||
fprintf(gLog, "%05u %s", gPid, msg);
|
||||
}
|
||||
/*
|
||||
* Handle a global error message from the NufxLib library by shoving it
|
||||
* through the DiskImgLib message function.
|
||||
*/
|
||||
NuResult
|
||||
NufxErrorMsgHandler(NuArchive* /*pArchive*/, void* vErrorMessage)
|
||||
{
|
||||
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
|
||||
|
||||
if (pErrorMessage->isDebug) {
|
||||
Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line,
|
||||
"<nufxlib> [D] %s\n", pErrorMessage->message);
|
||||
} else {
|
||||
Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line,
|
||||
"<nufxlib> %s\n", pErrorMessage->message);
|
||||
}
|
||||
|
||||
return kNuOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert one disk image to another.
|
||||
*/
|
||||
DIError
|
||||
Convert(const char* infile, const char* outfile)
|
||||
{
|
||||
DIError dierr = kDIErrNone;
|
||||
DiskImg srcImg, dstImg;
|
||||
const char* storageName = nil;
|
||||
|
||||
printf("Converting in='%s' out='%s'\n", infile, outfile);
|
||||
|
||||
/*
|
||||
* Prepare the source image.
|
||||
*/
|
||||
dierr = srcImg.OpenImage(infile, '/', true);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Unable to open disk image: %s.\n",
|
||||
DiskImgLib::DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dierr = srcImg.AnalyzeImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Unable to determine source image format.\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (!srcImg.GetHasBlocks() && !srcImg.GetHasSectors()) {
|
||||
/* add nibble tracks someday */
|
||||
fprintf(stderr,
|
||||
"Sorry, only block- or sector-addressable images allowed.\n");
|
||||
dierr = kDIErrUnsupportedPhysicalFmt;
|
||||
goto bail;
|
||||
}
|
||||
if (srcImg.GetHasBlocks()) {
|
||||
assert(srcImg.GetNumBlocks() > 0);
|
||||
} else {
|
||||
assert(srcImg.GetNumTracks() > 0);
|
||||
}
|
||||
|
||||
if (srcImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) {
|
||||
fprintf(stderr, "(QUERY) don't know sector order\n");
|
||||
dierr = kDIErrFilesystemNotFound;
|
||||
goto bail;
|
||||
}
|
||||
|
||||
storageName = "MyHappyDisk";
|
||||
|
||||
/* force the access to be ProDOS-ordered */
|
||||
dierr = srcImg.OverrideFormat(srcImg.GetPhysicalFormat(),
|
||||
DiskImg::kFormatGenericProDOSOrd, srcImg.GetSectorOrder());
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Couldn't switch to generic ProDOS: %s.\n",
|
||||
DiskImgLib::DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* transfer the DOS volume num, if one was set */
|
||||
printf("DOS volume number set to %d\n", srcImg.GetDOSVolumeNum());
|
||||
dstImg.SetDOSVolumeNum(srcImg.GetDOSVolumeNum());
|
||||
|
||||
const DiskImg::NibbleDescr* pNibbleDescr;
|
||||
pNibbleDescr = nil;
|
||||
|
||||
/*
|
||||
* Prepare the destination image.
|
||||
*
|
||||
* We *always* use DiskImg::kFormatGenericProDOSOrd here, because it
|
||||
* must match up with what we selected above.
|
||||
*
|
||||
* We could enable "skipFormat" on all of these but the nibble images,
|
||||
* but we go ahead and set it to "false" on all of them just for fun.
|
||||
*/
|
||||
switch (18) {
|
||||
case 0:
|
||||
/* 16-sector nibble image, by blocks */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 1:
|
||||
/* 16-sector nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 2:
|
||||
/* 16-sector NB2 nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6384,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 3:
|
||||
/* 13-sector nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS32Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 13,
|
||||
false);
|
||||
break;
|
||||
case 4:
|
||||
/* 16-sector nb2 image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatNib525_6384,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 5:
|
||||
/* sector image, by blocks, ProDOS order */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 6:
|
||||
/* sector image, by blocks, DOS order */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 7:
|
||||
/* sector image, by blocks, ProDOS order, Sim2e */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatSim2eHDV,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 8:
|
||||
/* odd-length HUGE sector image, by blocks */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
65535,
|
||||
false);
|
||||
break;
|
||||
case 9:
|
||||
/* sector image, by blocks, physical order, with gzip */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatGzip,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 10:
|
||||
/* sector image, by blocks, ProDOS order, with gzip */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatGzip,
|
||||
DiskImg::kFileFormatSim2eHDV,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 11:
|
||||
/* sector image, by blocks, ProDOS order, 2MG */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormat2MG,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 12:
|
||||
/* 16-sector nibble image, by tracks/sectors, 2MG */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormat2MG,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 13:
|
||||
/* 16-sector nibble image, by tracks/sectors, 2MG, gzip */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatGzip,
|
||||
DiskImg::kFileFormat2MG,
|
||||
DiskImg::kPhysicalFormatNib525_6656,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderPhysical,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 16,
|
||||
false);
|
||||
break;
|
||||
case 14:
|
||||
/* sector image, by blocks, for DC42 (800K only) */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatDiskCopy42,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 15:
|
||||
/* sector image, by blocks, for NuFX */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatNuFX,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 16:
|
||||
/* sector image, by blocks, for DDD */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatDDD,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 17:
|
||||
/* sector image, by blocks, ProDOS order, stored in ZIP (.po.zip) */
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatZip,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
srcImg.GetNumBlocks(),
|
||||
false);
|
||||
break;
|
||||
case 18:
|
||||
/* 13-sector nibble image, by tracks/sectors */
|
||||
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
|
||||
dierr = dstImg.CreateImage(outfile, storageName,
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
pNibbleDescr,
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
35, 13,
|
||||
false);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "UNEXPECTED NUMBER\n");
|
||||
abort();
|
||||
}
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Couldn't create new image file '%s': %s.\n",
|
||||
outfile, DiskImgLib::DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy blocks or sectors from source to destination.
|
||||
*/
|
||||
if (srcImg.GetHasBlocks()) {
|
||||
int numBlocks;
|
||||
numBlocks = srcImg.GetNumBlocks();
|
||||
if (dstImg.GetNumBlocks() < srcImg.GetNumBlocks())
|
||||
numBlocks = dstImg.GetNumBlocks();
|
||||
printf("Copying %d blocks\n", numBlocks);
|
||||
|
||||
unsigned char blkBuf[512];
|
||||
for (int block = 0; block < numBlocks; block++) {
|
||||
dierr = srcImg.ReadBlock(block, blkBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: ReadBlock failed (err=%d)\n", dierr);
|
||||
goto bail;
|
||||
}
|
||||
dierr = dstImg.WriteBlock(block, blkBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: WriteBlock failed (err=%d)\n", dierr);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int numTracks, numSectPerTrack;
|
||||
numTracks = srcImg.GetNumTracks();
|
||||
numSectPerTrack = srcImg.GetNumSectPerTrack();
|
||||
if (dstImg.GetNumTracks() < srcImg.GetNumTracks())
|
||||
numTracks = dstImg.GetNumTracks();
|
||||
if (dstImg.GetNumSectPerTrack() < srcImg.GetNumSectPerTrack())
|
||||
numSectPerTrack = dstImg.GetNumSectPerTrack();
|
||||
printf("Copying %d tracks of %d sectors\n", numTracks, numSectPerTrack);
|
||||
|
||||
unsigned char sctBuf[256];
|
||||
for (int track = 0; track < numTracks; track++) {
|
||||
for (int sector = 0; sector < numSectPerTrack; sector++) {
|
||||
dierr = srcImg.ReadTrackSector(track, sector, sctBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr,
|
||||
"WARNING: ReadTrackSector failed on T=%d S=%d (err=%d)\n",
|
||||
track, sector, dierr);
|
||||
dierr = kDIErrNone; // allow bad blocks
|
||||
memset(sctBuf, 0, sizeof(sctBuf));
|
||||
}
|
||||
dierr = dstImg.WriteTrackSector(track, sector, sctBuf);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr,
|
||||
"ERROR: WriteBlock failed on T=%d S=%d (err=%d)\n",
|
||||
track, sector, dierr);
|
||||
goto bail;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dierr = srcImg.CloseImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: srcImg close failed?!\n");
|
||||
goto bail;
|
||||
}
|
||||
|
||||
dierr = dstImg.CloseImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: dstImg close failed (err=%d)\n", dierr);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
assert(dierr == kDIErrNone);
|
||||
bail:
|
||||
return dierr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process every argument.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
const char* kLogFile = "iconv-log.txt";
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "%s: infile outfile\n", argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
gLog = fopen(kLogFile, "w");
|
||||
if (gLog == nil) {
|
||||
fprintf(stderr, "ERROR: unable to open log file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Image Converter for Linux v1.0\n");
|
||||
printf("Copyright (C) 2014 by faddenSoft. All rights reserved.\n");
|
||||
int32_t major, minor, bug;
|
||||
Global::GetVersion(&major, &minor, &bug);
|
||||
printf("Linked against DiskImg library v%d.%d.%d\n",
|
||||
major, minor, bug);
|
||||
printf("Log file is '%s'\n", kLogFile);
|
||||
printf("\n");
|
||||
|
||||
Global::SetDebugMsgHandler(MsgHandler);
|
||||
Global::AppInit();
|
||||
|
||||
NuSetGlobalErrorMessageHandler(NufxErrorMsgHandler);
|
||||
|
||||
Convert(argv[1], argv[2]);
|
||||
|
||||
Global::AppCleanup();
|
||||
fclose(gLog);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
@ -1,220 +1,220 @@
|
||||
/*
|
||||
* CiderPress
|
||||
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
||||
* See the file LICENSE for distribution terms.
|
||||
*/
|
||||
/*
|
||||
* Get a file from a disk image.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "../diskimg/DiskImg.h"
|
||||
|
||||
using namespace DiskImgLib;
|
||||
|
||||
#define nil NULL
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
*/
|
||||
FILE* gLog = nil;
|
||||
pid_t gPid = getpid();
|
||||
|
||||
/*
|
||||
* Show usage info.
|
||||
*/
|
||||
void
|
||||
Usage(const char* argv0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s image-filename file\n", argv0);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "The file will be written to stdout.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a file from "src" to "dst".
|
||||
*/
|
||||
int
|
||||
CopyFile(A2FileDescr* src, FILE* dst)
|
||||
{
|
||||
DIError dierr;
|
||||
size_t actual;
|
||||
char buf[4096];
|
||||
|
||||
while (1) {
|
||||
dierr = src->Read(buf, sizeof(buf), &actual);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Error: read failed: %s\n", DIStrError(dierr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actual == 0) // EOF hit
|
||||
break;
|
||||
|
||||
fwrite(buf, 1, actual, dst);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the named file from the specified image.
|
||||
*/
|
||||
int
|
||||
Process(const char* imageName, const char* wantedFileName)
|
||||
{
|
||||
DIError dierr;
|
||||
DiskImg diskImg;
|
||||
DiskFS* pDiskFS = nil;
|
||||
A2File* pFile = nil;
|
||||
A2FileDescr* pDescr = nil;
|
||||
int result = -1;
|
||||
|
||||
/* open read-only */
|
||||
dierr = diskImg.OpenImage(imageName, '/', true);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Unable to open '%s': %s\n", imageName,
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* figure out the format */
|
||||
dierr = diskImg.AnalyzeImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Analysis of '%s' failed: %s\n", imageName,
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* recognized? */
|
||||
if (diskImg.GetFSFormat() == DiskImg::kFormatUnknown ||
|
||||
diskImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown)
|
||||
{
|
||||
fprintf(stderr, "Unable to identify filesystem on '%s'\n", imageName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* create an appropriate DiskFS object */
|
||||
pDiskFS = diskImg.OpenAppropriateDiskFS();
|
||||
if (pDiskFS == nil) {
|
||||
/* unknown FS should've been caught above! */
|
||||
assert(false);
|
||||
fprintf(stderr, "Format of '%s' not recognized.\n", imageName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* go ahead and load up volumes mounted inside volumes */
|
||||
pDiskFS->SetScanForSubVolumes(DiskFS::kScanSubEnabled);
|
||||
|
||||
/* do a full scan */
|
||||
dierr = pDiskFS->Initialize(&diskImg, DiskFS::kInitFull);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Error reading list of files from disk: %s\n",
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the file. This comes out of a list of entries, so don't
|
||||
* delete "pFile" when we're done.
|
||||
*/
|
||||
pFile = pDiskFS->GetFileByName(wantedFileName);
|
||||
if (pFile == nil) {
|
||||
fprintf(stderr, "File '%s' not found in '%s'\n", wantedFileName,
|
||||
imageName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the file read-only.
|
||||
*/
|
||||
dierr = pFile->Open(&pDescr, true);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Error opening '%s': %s\n", wantedFileName,
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the file to stdout.
|
||||
*/
|
||||
result = CopyFile(pDescr, stdout);
|
||||
|
||||
bail:
|
||||
if (pDescr != nil) {
|
||||
pDescr->Close();
|
||||
//delete pDescr; -- don't do this (double free)
|
||||
}
|
||||
delete pDiskFS;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a debug message from the DiskImg library.
|
||||
*/
|
||||
/*static*/ void
|
||||
MsgHandler(const char* file, int line, const char* msg)
|
||||
{
|
||||
assert(file != nil);
|
||||
assert(msg != nil);
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(gLog, "%05u %s", gPid, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Process args.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
const char* kLogFile = "makedisk-log.txt";
|
||||
gLog = fopen(kLogFile, "w");
|
||||
if (gLog == nil) {
|
||||
fprintf(stderr, "ERROR: unable to open log file\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(stderr, "Log file is '%s'\n", kLogFile);
|
||||
#endif
|
||||
|
||||
Global::SetDebugMsgHandler(MsgHandler);
|
||||
Global::AppInit();
|
||||
|
||||
if (argc != 3) {
|
||||
Usage(argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
const char* imageName;
|
||||
const char* getFileName;
|
||||
|
||||
argv++;
|
||||
imageName = *argv++;
|
||||
getFileName = *argv++;
|
||||
argc -= 2;
|
||||
|
||||
if (Process(imageName, getFileName) == 0)
|
||||
fprintf(stderr, "Success!\n");
|
||||
else
|
||||
fprintf(stderr, "Failed.\n");
|
||||
|
||||
Global::AppCleanup();
|
||||
#ifdef _DEBUG
|
||||
fclose(gLog);
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* CiderPress
|
||||
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
||||
* See the file LICENSE for distribution terms.
|
||||
*/
|
||||
/*
|
||||
* Get a file from a disk image.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "../diskimg/DiskImg.h"
|
||||
|
||||
using namespace DiskImgLib;
|
||||
|
||||
#define nil NULL
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
*/
|
||||
FILE* gLog = nil;
|
||||
pid_t gPid = getpid();
|
||||
|
||||
/*
|
||||
* Show usage info.
|
||||
*/
|
||||
void
|
||||
Usage(const char* argv0)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s image-filename file\n", argv0);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "The file will be written to stdout.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a file from "src" to "dst".
|
||||
*/
|
||||
int
|
||||
CopyFile(A2FileDescr* src, FILE* dst)
|
||||
{
|
||||
DIError dierr;
|
||||
size_t actual;
|
||||
char buf[4096];
|
||||
|
||||
while (1) {
|
||||
dierr = src->Read(buf, sizeof(buf), &actual);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Error: read failed: %s\n", DIStrError(dierr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actual == 0) // EOF hit
|
||||
break;
|
||||
|
||||
fwrite(buf, 1, actual, dst);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the named file from the specified image.
|
||||
*/
|
||||
int
|
||||
Process(const char* imageName, const char* wantedFileName)
|
||||
{
|
||||
DIError dierr;
|
||||
DiskImg diskImg;
|
||||
DiskFS* pDiskFS = nil;
|
||||
A2File* pFile = nil;
|
||||
A2FileDescr* pDescr = nil;
|
||||
int result = -1;
|
||||
|
||||
/* open read-only */
|
||||
dierr = diskImg.OpenImage(imageName, '/', true);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Unable to open '%s': %s\n", imageName,
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* figure out the format */
|
||||
dierr = diskImg.AnalyzeImage();
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Analysis of '%s' failed: %s\n", imageName,
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* recognized? */
|
||||
if (diskImg.GetFSFormat() == DiskImg::kFormatUnknown ||
|
||||
diskImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown)
|
||||
{
|
||||
fprintf(stderr, "Unable to identify filesystem on '%s'\n", imageName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* create an appropriate DiskFS object */
|
||||
pDiskFS = diskImg.OpenAppropriateDiskFS();
|
||||
if (pDiskFS == nil) {
|
||||
/* unknown FS should've been caught above! */
|
||||
assert(false);
|
||||
fprintf(stderr, "Format of '%s' not recognized.\n", imageName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* go ahead and load up volumes mounted inside volumes */
|
||||
pDiskFS->SetScanForSubVolumes(DiskFS::kScanSubEnabled);
|
||||
|
||||
/* do a full scan */
|
||||
dierr = pDiskFS->Initialize(&diskImg, DiskFS::kInitFull);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Error reading list of files from disk: %s\n",
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the file. This comes out of a list of entries, so don't
|
||||
* delete "pFile" when we're done.
|
||||
*/
|
||||
pFile = pDiskFS->GetFileByName(wantedFileName);
|
||||
if (pFile == nil) {
|
||||
fprintf(stderr, "File '%s' not found in '%s'\n", wantedFileName,
|
||||
imageName);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the file read-only.
|
||||
*/
|
||||
dierr = pFile->Open(&pDescr, true);
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "Error opening '%s': %s\n", wantedFileName,
|
||||
DIStrError(dierr));
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy the file to stdout.
|
||||
*/
|
||||
result = CopyFile(pDescr, stdout);
|
||||
|
||||
bail:
|
||||
if (pDescr != nil) {
|
||||
pDescr->Close();
|
||||
//delete pDescr; -- don't do this (double free)
|
||||
}
|
||||
delete pDiskFS;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a debug message from the DiskImg library.
|
||||
*/
|
||||
/*static*/ void
|
||||
MsgHandler(const char* file, int line, const char* msg)
|
||||
{
|
||||
assert(file != nil);
|
||||
assert(msg != nil);
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(gLog, "%05u %s", gPid, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Process args.
|
||||
*/
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
const char* kLogFile = "makedisk-log.txt";
|
||||
gLog = fopen(kLogFile, "w");
|
||||
if (gLog == nil) {
|
||||
fprintf(stderr, "ERROR: unable to open log file\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
fprintf(stderr, "Log file is '%s'\n", kLogFile);
|
||||
#endif
|
||||
|
||||
Global::SetDebugMsgHandler(MsgHandler);
|
||||
Global::AppInit();
|
||||
|
||||
if (argc != 3) {
|
||||
Usage(argv[0]);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
const char* imageName;
|
||||
const char* getFileName;
|
||||
|
||||
argv++;
|
||||
imageName = *argv++;
|
||||
getFileName = *argv++;
|
||||
argc -= 2;
|
||||
|
||||
if (Process(imageName, getFileName) == 0)
|
||||
fprintf(stderr, "Success!\n");
|
||||
else
|
||||
fprintf(stderr, "Failed.\n");
|
||||
|
||||
Global::AppCleanup();
|
||||
#ifdef _DEBUG
|
||||
fclose(gLog);
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
1780
linux/MDC.cpp
1780
linux/MDC.cpp
File diff suppressed because it is too large
Load Diff
@ -1,388 +1,388 @@
|
||||
/*
|
||||
* CiderPress
|
||||
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
||||
* See the file LICENSE for distribution terms.
|
||||
*/
|
||||
/*
|
||||
* Create a blank disk image, format it, and copy some files onto it.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "../diskimg/DiskImg.h"
|
||||
|
||||
using namespace DiskImgLib;
|
||||
|
||||
#define nil NULL
|
||||
#define NELEM(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
*/
|
||||
FILE* gLog = nil;
|
||||
pid_t gPid = getpid();
|
||||
|
||||
/*
|
||||
* Show usage info.
|
||||
*/
|
||||
void
|
||||
Usage(const char* argv0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: %s {dos|prodos|pascal} size image-filename.po input-file1 ...\n",
|
||||
argv0);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Example: makedisk prodos 800k foo.po file1.txt file2.txt\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a ProDOS-ordered disk image.
|
||||
*
|
||||
* Returns a DiskImg pointer on success, or nil on failure.
|
||||
*/
|
||||
DiskImg*
|
||||
CreateDisk(const char* fileName, long blockCount)
|
||||
{
|
||||
DIError dierr;
|
||||
DiskImg* pDiskImg = nil;
|
||||
|
||||
pDiskImg = new DiskImg;
|
||||
dierr = pDiskImg->CreateImage(
|
||||
fileName,
|
||||
nil, // storageName
|
||||
DiskImg::kOuterFormatNone,
|
||||
DiskImg::kFileFormatUnadorned,
|
||||
DiskImg::kPhysicalFormatSectors,
|
||||
nil, // pNibbleDescr
|
||||
DiskImg::kSectorOrderProDOS,
|
||||
DiskImg::kFormatGenericProDOSOrd,
|
||||
blockCount,
|
||||
true); // no need to format the image
|
||||
|
||||
if (dierr != kDIErrNone) {
|
||||
fprintf(stderr, "ERROR: CreateImage failed: %s\n",
|
||||
DIStrError(dierr));
|
||||
delete pDiskImg;
|
||||
pDiskImg = nil;
|
||||
}
|
||||
|
||||
return pDiskImg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy files to the disk.
|
||||
*/
|
||||
int
|
||||
CopyFiles(DiskFS* pDiskFS, int argc, char** argv)
|
||||
{
|
||||
DIError dierr;
|
||||
DiskFS::CreateParms parms;
|
||||
A2File* pNewFile;
|
||||
|
||||
struct CreateParms {
|
||||
const char* pathName; // full pathname
|
||||
char fssep;
|
||||
int storageType; // determines normal, subdir, or forked
|
||||
long fileType;
|
||||
long auxType;
|
||||
int access;
|
||||
time_t createWhen;
|
||||
time_t modWhen;
|
||||
};
|
||||
|
||||
|
||||
while (argc--) {
|
||||
printf("+++ Adding '%s'\n", *argv);
|
||||
|
||||