mirror of
https://github.com/ksherlock/profuse.git
synced 2024-05-28 22:41:39 +00:00
switch to BlockDevice, smart_ptr.
git-svn-id: https://profuse.googlecode.com/svn/branches/profuse_interim@342 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
4cdfc52c04
commit
3f8e7ad7ae
49
Disk.cpp
49
Disk.cpp
|
@ -24,6 +24,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
struct ucmp
|
struct ucmp
|
||||||
{
|
{
|
||||||
bool operator()(unsigned a, unsigned b) const
|
bool operator()(unsigned a, unsigned b) const
|
||||||
|
@ -39,20 +40,28 @@ typedef set<unsigned, ucmp> uset;
|
||||||
|
|
||||||
Disk::Disk()
|
Disk::Disk()
|
||||||
{
|
{
|
||||||
_data = (uint8_t *)-1;
|
|
||||||
_blocks = 0;
|
_blocks = 0;
|
||||||
_offset = 0;
|
|
||||||
_size = 0;
|
|
||||||
_flags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Disk::~Disk()
|
Disk::~Disk()
|
||||||
{
|
{
|
||||||
if (_data != (uint8_t *)-1)
|
|
||||||
munmap(_data, _size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Disk::Disk(Device::BlockDevicePointer device) :
|
||||||
|
_device(device)
|
||||||
|
{
|
||||||
|
_blocks = _device->blocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
DiskPointer Disk::OpenFile(Device::BlockDevicePointer device)
|
||||||
|
{
|
||||||
|
DiskPointer disk(new Disk(device));
|
||||||
|
|
||||||
|
return disk;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
Disk *Disk::OpenFile(const char *file, unsigned flags)
|
Disk *Disk::OpenFile(const char *file, unsigned flags)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -155,7 +164,7 @@ Disk *Disk::OpenFile(const char *file, unsigned flags)
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// load the mini entry into the regular entry.
|
// load the mini entry into the regular entry.
|
||||||
int Disk::Normalize(FileEntry &f, unsigned fork, ExtendedEntry *ee)
|
int Disk::Normalize(FileEntry &f, unsigned fork, ExtendedEntry *ee)
|
||||||
|
@ -200,31 +209,11 @@ int Disk::Normalize(FileEntry &f, unsigned fork, ExtendedEntry *ee)
|
||||||
|
|
||||||
int Disk::Read(unsigned block, void *buffer)
|
int Disk::Read(unsigned block, void *buffer)
|
||||||
{
|
{
|
||||||
if (block > _blocks) return -P8_INVALID_BLOCK;
|
|
||||||
|
|
||||||
|
|
||||||
if (_flags & P8_DOS_ORDER)
|
|
||||||
{
|
|
||||||
static unsigned do_map[] = {0x00, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0f };
|
|
||||||
|
|
||||||
unsigned track = (block & ~0x07) << 9;
|
|
||||||
unsigned sector = (block & 0x07) << 1;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
unsigned offset = track | (do_map[sector+i] << 8);
|
|
||||||
|
|
||||||
memcpy(buffer, _data + _offset + offset, 256);
|
|
||||||
|
|
||||||
buffer = (char *)buffer + 256;
|
|
||||||
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
if (block > _blocks) return -P8_INVALID_BLOCK;
|
||||||
|
|
||||||
|
_device->read(block, buffer);
|
||||||
|
|
||||||
memcpy(buffer, _data + _offset + (block << 9), BLOCK_SIZE);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
Disk.h
20
Disk.h
|
@ -13,7 +13,10 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "File.h"
|
#include <ProDOS/File.h>
|
||||||
|
#include <Device/BlockDevice.h>
|
||||||
|
|
||||||
|
#include <tr1/memory>
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -40,6 +43,8 @@ enum {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Disk;
|
||||||
|
typedef std::tr1::shared_ptr<Disk> DiskPointer;
|
||||||
|
|
||||||
class Disk {
|
class Disk {
|
||||||
|
|
||||||
|
@ -47,7 +52,7 @@ public:
|
||||||
~Disk();
|
~Disk();
|
||||||
|
|
||||||
//static Disk *Open2MG(const char *file);
|
//static Disk *Open2MG(const char *file);
|
||||||
static Disk *OpenFile(const char *file, unsigned flags);
|
static DiskPointer OpenFile(Device::BlockDevicePointer device);
|
||||||
|
|
||||||
|
|
||||||
int Normalize(FileEntry &f, unsigned fork, ExtendedEntry *ee = NULL);
|
int Normalize(FileEntry &f, unsigned fork, ExtendedEntry *ee = NULL);
|
||||||
|
@ -65,13 +70,14 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Disk();
|
Disk();
|
||||||
uint8_t *_data;
|
Disk(Device::BlockDevicePointer device);
|
||||||
unsigned _offset;
|
|
||||||
unsigned _blocks;
|
|
||||||
size_t _size;
|
|
||||||
|
|
||||||
unsigned _flags;
|
unsigned _blocks;
|
||||||
|
|
||||||
|
Device::BlockDevicePointer _device;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
190
main.cpp
190
main.cpp
|
@ -14,29 +14,39 @@
|
||||||
#define _POSIX_C_SOURCE 200112L
|
#define _POSIX_C_SOURCE 200112L
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <stdlib.h>
|
#include <cstdlib>
|
||||||
#include <string.h>
|
#include <cstring>
|
||||||
#include <ctype.h>
|
#include <cctype>
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include <tr1/memory>
|
||||||
|
|
||||||
|
#include <Device/BlockDevice.h>
|
||||||
|
|
||||||
|
|
||||||
#include "profuse.h"
|
#include "profuse.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
using std::tr1::shared_ptr;
|
||||||
|
|
||||||
Disk *disk = NULL;
|
|
||||||
char *dfile = NULL;
|
/*
|
||||||
|
* globals variables.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::string fDiskImage;
|
||||||
|
|
||||||
|
|
||||||
|
DiskPointer disk;
|
||||||
VolumeEntry volume;
|
VolumeEntry volume;
|
||||||
|
|
||||||
bool dos_order = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool validProdosName(const char *name)
|
bool validProdosName(const char *name)
|
||||||
{
|
{
|
||||||
// OS X looks for hidden files that don't exist (and aren't legal prodos names)
|
// OS X looks for hidden files that don't exist (and aren't legal prodos names)
|
||||||
|
@ -70,46 +80,81 @@ static struct fuse_lowlevel_ops prodos_oper;
|
||||||
enum {
|
enum {
|
||||||
PRODOS_OPT_HELP,
|
PRODOS_OPT_HELP,
|
||||||
PRODOS_OPT_VERSION,
|
PRODOS_OPT_VERSION,
|
||||||
PRODOS_OPT_DOS_ORDER
|
PRODOS_OPT_WRITE,
|
||||||
|
PRODOS_OPT_FORMAT,
|
||||||
|
PRODOS_OPT_VERBOSE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct options {
|
||||||
|
char *format;
|
||||||
|
int readOnly;
|
||||||
|
int readWrite;
|
||||||
|
int verbose;
|
||||||
|
int debug;
|
||||||
|
|
||||||
|
} options;
|
||||||
|
|
||||||
|
#define PRODOS_OPT_KEY(T, P, V) {T, offsetof(struct options, P), V}
|
||||||
|
|
||||||
|
|
||||||
static struct fuse_opt prodos_opts[] = {
|
static struct fuse_opt prodos_opts[] = {
|
||||||
FUSE_OPT_KEY("-h", PRODOS_OPT_HELP),
|
FUSE_OPT_KEY("-h", PRODOS_OPT_HELP),
|
||||||
FUSE_OPT_KEY("--help", PRODOS_OPT_HELP),
|
FUSE_OPT_KEY("--help", PRODOS_OPT_HELP),
|
||||||
|
|
||||||
FUSE_OPT_KEY("-V", PRODOS_OPT_VERSION),
|
FUSE_OPT_KEY("-V", PRODOS_OPT_VERSION),
|
||||||
FUSE_OPT_KEY("--version", PRODOS_OPT_VERSION),
|
FUSE_OPT_KEY("--version", PRODOS_OPT_VERSION),
|
||||||
FUSE_OPT_KEY("--dos-order", PRODOS_OPT_DOS_ORDER),
|
|
||||||
|
PRODOS_OPT_KEY("-v", verbose, 1),
|
||||||
|
|
||||||
|
PRODOS_OPT_KEY("-w", readWrite, 1),
|
||||||
|
PRODOS_OPT_KEY("rw", readWrite, 1),
|
||||||
|
|
||||||
|
PRODOS_OPT_KEY("-d", debug, 1),
|
||||||
|
|
||||||
|
PRODOS_OPT_KEY("--format=%s", format, 0),
|
||||||
|
PRODOS_OPT_KEY("format=%s", format, 0),
|
||||||
{0, 0, 0}
|
{0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usage()
|
static void usage()
|
||||||
{
|
{
|
||||||
fprintf(stderr, "profuse [options] disk_image mountpoint\n");
|
fprintf(stderr, "profuse [options] disk_image [mountpoint]\n"
|
||||||
|
|
||||||
|
"Options:\n"
|
||||||
|
" -d debug\n"
|
||||||
|
" -r readonly\n"
|
||||||
|
" -w mount writable [not yet]\n"
|
||||||
|
" -v verbose\n"
|
||||||
|
" --format=format specify the disk image format. Valid values are:\n"
|
||||||
|
" dc42 DiskCopy 4.2 Image\n"
|
||||||
|
" davex Davex Disk Image\n"
|
||||||
|
" 2img Universal Disk Image\n"
|
||||||
|
" do DOS Order Disk Image\n"
|
||||||
|
" po ProDOS Order Disk Image (default)\n"
|
||||||
|
" -o opt1,opt2... other mount parameters.\n"
|
||||||
|
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prodos_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
|
static int prodos_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
|
||||||
{
|
{
|
||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
case PRODOS_OPT_HELP:
|
case PRODOS_OPT_HELP:
|
||||||
usage();
|
usage();
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
case PRODOS_OPT_VERSION:
|
case PRODOS_OPT_VERSION:
|
||||||
// TODO
|
// TODO
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
case PRODOS_OPT_DOS_ORDER:
|
|
||||||
dos_order = true;
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FUSE_OPT_KEY_NONOPT:
|
case FUSE_OPT_KEY_NONOPT:
|
||||||
if (dfile == NULL)
|
// first arg is the disk image.
|
||||||
|
if (fDiskImage.empty())
|
||||||
{
|
{
|
||||||
dfile = strdup(arg);
|
fDiskImage = arg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -159,15 +204,25 @@ int main(int argc, char *argv[])
|
||||||
struct fuse_chan *ch;
|
struct fuse_chan *ch;
|
||||||
char *mountpoint = NULL;
|
char *mountpoint = NULL;
|
||||||
int err = -1;
|
int err = -1;
|
||||||
|
struct options options;
|
||||||
|
|
||||||
|
unsigned format = 0;
|
||||||
|
|
||||||
|
int foreground = false;
|
||||||
|
int multithread = false;
|
||||||
|
|
||||||
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
string mountpath;
|
string mountpath;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
disk = NULL;
|
|
||||||
|
|
||||||
bzero(&prodos_oper, sizeof(prodos_oper));
|
|
||||||
|
std::memset(&prodos_oper, 0, sizeof(prodos_oper));
|
||||||
|
|
||||||
|
std::memset(&options, 0, sizeof(options));
|
||||||
|
|
||||||
|
|
||||||
prodos_oper.listxattr = prodos_listxattr;
|
prodos_oper.listxattr = prodos_listxattr;
|
||||||
prodos_oper.getxattr = prodos_getxattr;
|
prodos_oper.getxattr = prodos_getxattr;
|
||||||
|
@ -185,23 +240,54 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
|
||||||
// scan the argument list, looking for the name of the disk image.
|
// scan the argument list, looking for the name of the disk image.
|
||||||
if (fuse_opt_parse(&args, NULL , prodos_opts, prodos_opt_proc) == -1)
|
if (fuse_opt_parse(&args, &options , prodos_opts, prodos_opt_proc) == -1)
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
if (dfile == NULL || *dfile == 0)
|
if (fDiskImage.empty())
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
exit(0);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
disk = Disk::OpenFile(dfile, dos_order);
|
// default prodos-order disk image.
|
||||||
|
if (options.format)
|
||||||
if (!disk)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to mount disk %s\n", dfile);
|
format = Device::BlockDevice::ImageType(options.format);
|
||||||
exit(1);
|
if (!format)
|
||||||
|
std::fprintf(stderr, "Warning: Unknown image type ``%s''\n", options.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Device::BlockDevicePointer device;
|
||||||
|
|
||||||
|
device.reset ( Device::BlockDevice::Open(fDiskImage.c_str(), File::ReadOnly, format) );
|
||||||
|
|
||||||
|
if (!device.get())
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "Error: Unknown or unsupported device type.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
disk = Disk::OpenFile(device);
|
||||||
|
|
||||||
|
if (!disk.get())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unable to mount disk %s\n", fDiskImage.c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ProFUSE::POSIXException &e)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "%s\n", e.what());
|
||||||
|
std::fprintf(stderr, "%s\n", e.errorString());
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
catch (ProFUSE::Exception &e)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "%s\n", e.what());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
disk->ReadVolume(&volume, NULL);
|
disk->ReadVolume(&volume, NULL);
|
||||||
|
@ -235,6 +321,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
foreground = options.debug;
|
||||||
|
|
||||||
|
|
||||||
if (mountpoint == NULL || *mountpoint == 0)
|
if (mountpoint == NULL || *mountpoint == 0)
|
||||||
|
@ -244,26 +331,32 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( (ch = fuse_mount(mountpoint, &args)) != NULL)
|
if ( (ch = fuse_mount(mountpoint, &args)) != NULL)
|
||||||
{
|
{
|
||||||
struct fuse_session *se;
|
struct fuse_session *se;
|
||||||
|
|
||||||
se = fuse_lowlevel_new(&args, &prodos_oper, sizeof(prodos_oper), NULL);
|
se = fuse_lowlevel_new(&args, &prodos_oper, sizeof(prodos_oper), NULL);
|
||||||
if (se != NULL)
|
if (se != NULL) do {
|
||||||
{
|
|
||||||
if (fuse_set_signal_handlers(se) != -1)
|
err = fuse_daemonize(foreground);
|
||||||
{
|
if (err < 0 ) break;
|
||||||
fuse_session_add_chan(se, ch);
|
|
||||||
err = fuse_session_loop(se);
|
|
||||||
fuse_remove_signal_handlers(se);
|
|
||||||
fuse_session_remove_chan(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
fuse_session_destroy(se);
|
err = fuse_set_signal_handlers(se);
|
||||||
}
|
if (err < 0) break;
|
||||||
|
|
||||||
|
|
||||||
|
fuse_session_add_chan(se, ch);
|
||||||
|
|
||||||
|
if (multithread) err = fuse_session_loop_mt(se);
|
||||||
|
else err = fuse_session_loop(se);
|
||||||
|
|
||||||
|
fuse_remove_signal_handlers(se);
|
||||||
|
fuse_session_remove_chan(ch);
|
||||||
|
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (se) fuse_session_destroy(se);
|
||||||
fuse_unmount(mountpoint, ch);
|
fuse_unmount(mountpoint, ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,9 +364,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
fuse_opt_free_args(&args);
|
fuse_opt_free_args(&args);
|
||||||
|
|
||||||
if (disk) delete disk;
|
disk.reset();
|
||||||
|
|
||||||
if (dfile) free(dfile);
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
if (mountpath.size()) rmdir(mountpath.c_str());
|
if (mountpath.size()) rmdir(mountpath.c_str());
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#ifndef __PROFUSE_H__
|
#ifndef __PROFUSE_H__
|
||||||
#define __PROFUSE_H__
|
#define __PROFUSE_H__
|
||||||
|
|
||||||
#include "File.h"
|
#include <ProDOS/File.h>
|
||||||
#include "Disk.h"
|
#include "Disk.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
#define ERROR(cond,errno) if ( (cond) ){ fuse_reply_err(req, errno); return; }
|
#define ERROR(cond,errno) if ( (cond) ){ fuse_reply_err(req, errno); return; }
|
||||||
|
|
||||||
|
|
||||||
extern Disk *disk;
|
extern DiskPointer disk;
|
||||||
|
|
||||||
bool validProdosName(const char *name);
|
bool validProdosName(const char *name);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user