mirror of
https://github.com/ksherlock/profuse.git
synced 2024-12-22 20:29:59 +00:00
git-svn-id: https://profuse.googlecode.com/svn/branches/v2@188 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
b18551dea9
commit
3a0871a158
@ -5,7 +5,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ProFUSE {
|
||||
namespace Device {
|
||||
class BlockDevice;
|
||||
class AbstractBlockCache;
|
||||
}
|
||||
|
9
ProFUSE/Makefile
Normal file
9
ProFUSE/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
CC = g++
|
||||
CPPFLAGS += -g -Wall -I../
|
||||
|
||||
|
||||
all : Exception.o Lock.o
|
||||
|
||||
Exception.o : Exception.cpp Exception.h
|
||||
|
||||
Lock.o : Lock.cpp Lock.h
|
149
apfm.cpp
149
apfm.cpp
@ -23,7 +23,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
const char *MonthName(unsigned m)
|
||||
{
|
||||
static const char *months[] = {
|
||||
@ -102,16 +101,35 @@ void printFileEntry(Pascal::FileEntry *e, bool extended)
|
||||
|
||||
}
|
||||
|
||||
int list(Pascal::VolumeEntry *volume, bool extended)
|
||||
int action_ls(int argc, char **argv, Pascal::VolumeEntry *volume)
|
||||
{
|
||||
//TODO -- check for -l flag.
|
||||
|
||||
bool extended = false;
|
||||
unsigned fileCount = volume->fileCount();
|
||||
unsigned used = volume->blocks();
|
||||
unsigned max = 0;
|
||||
unsigned volumeSize = volume->volumeBlocks();
|
||||
unsigned lastBlock = volume->lastBlock();
|
||||
int ch;
|
||||
|
||||
std::fprintf(stdout, "%s:\n", volume->name());
|
||||
|
||||
argv[0] = "afpm ls";
|
||||
|
||||
while ((ch = ::getopt(argc, argv, "l")) != -1)
|
||||
{
|
||||
switch(ch)
|
||||
{
|
||||
case 'l':
|
||||
extended = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
for (unsigned i = 0; i < fileCount; ++i)
|
||||
{
|
||||
Pascal::FileEntry *e = volume->fileAtIndex(i);
|
||||
@ -158,20 +176,95 @@ int list(Pascal::VolumeEntry *volume, bool extended)
|
||||
}
|
||||
|
||||
|
||||
int action_cat(unsigned argc, char **argv, Pascal::VolumeEntry *volume)
|
||||
{
|
||||
// cat file1, file2...
|
||||
argv[0] = "afpm cat";
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
std::fprintf(stderr, "apfm cat: Please specify one or more files.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < argc; ++i)
|
||||
{
|
||||
const char *fname = argv[i];
|
||||
unsigned fileSize;
|
||||
unsigned offset;
|
||||
uint8_t buffer[512];
|
||||
Pascal::FileEntry *e = NULL;
|
||||
// find it...
|
||||
|
||||
for (unsigned i = 0, l = volume->fileCount(); i < l; ++i)
|
||||
{
|
||||
e = volume->fileAtIndex(i);
|
||||
if (::strcasecmp(e->name(), fname) == 0) break;
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
if (!e)
|
||||
{
|
||||
std::fprintf(stderr, "apfm cat: %s: no such file.\n", fname);
|
||||
continue;
|
||||
}
|
||||
|
||||
fileSize = e->fileSize();
|
||||
offset = 0;
|
||||
while (offset < fileSize)
|
||||
{
|
||||
unsigned count = std::min(512u, fileSize - offset);
|
||||
e->read(buffer, count, offset);
|
||||
|
||||
std::fwrite(buffer, count, 1, stdout);
|
||||
offset += count;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int action_cp(int argc, char **argv, Pascal::VolumeEntry *volume)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int action_mv(int argc, char **argv, Pascal::VolumeEntry *volume)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int action_rm(int argc, char **argv, Pascal::VolumeEntry *volume)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int action_krunch(int argc, char **argv, Pascal::VolumeEntry *volume)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void usage()
|
||||
{
|
||||
std::printf(
|
||||
"Pascal File Manager v 0.0\n\n"
|
||||
"Usage: fileman [-h] [-f format] action diskimage\n"
|
||||
"Usage: fileman [-h] [-f format] diskimage action ...\n"
|
||||
"Options:\n"
|
||||
" -h Show usage information.\n"
|
||||
" -f format Specify disk format. Valid values are:\n"
|
||||
" po: ProDOS order disk image\n"
|
||||
" do: DOS Order disk image\n"
|
||||
" po: ProDOS order disk image\n"
|
||||
" do: DOS Order disk image\n"
|
||||
"\n"
|
||||
"Actions:\n"
|
||||
" L List files\n"
|
||||
" E List files (extended)\n"
|
||||
" cat\n"
|
||||
" cp\n"
|
||||
" krunch\n"
|
||||
" ls\n"
|
||||
" mv\n"
|
||||
" rm\n"
|
||||
);
|
||||
|
||||
}
|
||||
@ -179,14 +272,14 @@ void usage()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
std::auto_ptr<Pascal::VolumeEntry> volume;
|
||||
std::auto_ptr<ProFUSE::BlockDevice> device;
|
||||
std::auto_ptr<Device::BlockDevice> device;
|
||||
|
||||
unsigned fmt = 0;
|
||||
|
||||
int c;
|
||||
|
||||
|
||||
|
||||
|
||||
// getop stops at first non '-' arg so it will not affect action flags.
|
||||
while ((c = ::getopt(argc, argv, "f:h")) != -1)
|
||||
{
|
||||
std::printf("%c\n", c);
|
||||
@ -203,24 +296,27 @@ int main(int argc, char **argv)
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
case ':':
|
||||
usage();
|
||||
std::exit(0);
|
||||
return c == 'h' ? 0 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
optreset = 1;
|
||||
optind = 1;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
usage();
|
||||
std::exit(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char *file = argv[1];
|
||||
const char *action = argv[0];
|
||||
const char *file = argv[0];
|
||||
const char *action = argv[1];
|
||||
|
||||
if (!fmt) fmt = Device::DiskImage::ImageType(optarg, 'PO__');
|
||||
|
||||
@ -230,28 +326,35 @@ int main(int argc, char **argv)
|
||||
switch(fmt)
|
||||
{
|
||||
case 'DO__':
|
||||
device.reset( new ProFUSE::DOSOrderDiskImage(file, true) );
|
||||
device.reset( new Device::DOSOrderDiskImage(file, true) );
|
||||
break;
|
||||
case 'PO__':
|
||||
device.reset( new ProFUSE::ProDOSOrderDiskImage(file, true) );
|
||||
device.reset( new Device::ProDOSOrderDiskImage(file, true) );
|
||||
break;
|
||||
case 'DC42':
|
||||
device.reset( new ProFUSE::DiskCopy42Image(file, true) );
|
||||
device.reset( new Device::DiskCopy42Image(file, true) );
|
||||
break;
|
||||
|
||||
default:
|
||||
std::fprintf(stderr, "Unable to determine format. Please use -f flag.\n");
|
||||
exit(2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
volume.reset( new Pascal::VolumeEntry(device.get()));
|
||||
|
||||
device.release();
|
||||
|
||||
if (!::strcasecmp("E", action)) return list(volume.get(), true);
|
||||
if (!::strcasecmp("L", action)) return list(volume.get(), false);
|
||||
|
||||
|
||||
|
||||
if (!::strcasecmp("cat", action)) return action_cat(argc - 1, argv + 1, volume.get());
|
||||
if (!::strcasecmp("cp", action)) return action_cp(argc - 1, argv + 1, volume.get());
|
||||
if (!::strcasecmp("krunch", action)) return action_krunch(argc - 1, argv + 1, volume.get());
|
||||
if (!::strcasecmp("ls", action)) return action_ls(argc - 1, argv + 1, volume.get());
|
||||
if (!::strcasecmp("mv", action)) return action_mv(argc - 1, argv + 1, volume.get());
|
||||
if (!::strcasecmp("rm", action)) return action_rm(argc - 1, argv + 1, volume.get());
|
||||
|
||||
usage();
|
||||
return 3;
|
||||
}
|
||||
catch (ProFUSE::Exception& e)
|
||||
{
|
||||
@ -259,5 +362,5 @@ int main(int argc, char **argv)
|
||||
std::fprintf(stderr, "%s\n", strerror(e.error()));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
@ -18,11 +18,12 @@
|
||||
#include <fuse/fuse_lowlevel.h>
|
||||
|
||||
|
||||
#include "File.h"
|
||||
#include "../BlockDevice.h"
|
||||
#include "../Exception.h"
|
||||
#include "../MappedFile.h"
|
||||
#include "../DiskCopy42Image.h"
|
||||
#include <Pascal/File.h>
|
||||
#include <ProFUSE/Exception.h>
|
||||
|
||||
#include <Device/BlockDevice.h>
|
||||
#include <Device/MappedFile.h>
|
||||
#include <Device/DiskCopy42Image.h>
|
||||
|
||||
Pascal::VolumeEntry *fVolume = NULL;
|
||||
std::string fDiskImage;
|
||||
@ -102,6 +103,7 @@ static int pascal_option_proc(void *data, const char *arg, int key, struct fuse_
|
||||
|
||||
|
||||
case FUSE_OPT_KEY_NONOPT:
|
||||
// first arg is the disk image.
|
||||
if (fDiskImage.empty())
|
||||
{
|
||||
fDiskImage = arg;
|
||||
@ -120,9 +122,12 @@ bool make_mount_dir(std::string name, std::string &path)
|
||||
{
|
||||
path = "";
|
||||
|
||||
if (name.find('/') != std::string::npos) return false;
|
||||
if (name.find('\\') != std::string::npos) return false;
|
||||
if (name.find(':') != std::string::npos) return false;
|
||||
if (name.find('/') != std::string::npos
|
||||
|| name.find('\\') != std::string::npos
|
||||
|| name.find(':') != std::string::npos )
|
||||
{
|
||||
name = "Pascal Volume";
|
||||
}
|
||||
|
||||
path = "";
|
||||
path = "/Volumes/" + name;
|
||||
@ -134,10 +139,7 @@ bool make_mount_dir(std::string name, std::string &path)
|
||||
path = "/Volumes/" + name + " " + (char)('a' + i);
|
||||
|
||||
rmdir(path.c_str());
|
||||
if (mkdir(path.c_str(), 0777) == 0) return true;
|
||||
|
||||
|
||||
|
||||
if (mkdir(path.c_str(), 0777) == 0) return true;
|
||||
}
|
||||
|
||||
path = "";
|
||||
@ -178,31 +180,31 @@ int main(int argc, char **argv)
|
||||
// default prodos-order disk image.
|
||||
if (options.format)
|
||||
{
|
||||
format = ProFUSE::DiskImage::ImageType(options.format);
|
||||
format = Device::DiskImage::ImageType(options.format);
|
||||
if (!format)
|
||||
std::fprintf(stderr, "Warning: Unknown image type ``%s''\n", options.format);
|
||||
}
|
||||
if (!format)
|
||||
format = ProFUSE::DiskImage::ImageType(fDiskImage.c_str(), 'PO__');
|
||||
format = Device::DiskImage::ImageType(fDiskImage.c_str(), 'PO__');
|
||||
|
||||
|
||||
bool readOnly = true;
|
||||
|
||||
try {
|
||||
std::auto_ptr<ProFUSE::BlockDevice> device;
|
||||
std::auto_ptr<Device::BlockDevice> device;
|
||||
|
||||
switch(format)
|
||||
{
|
||||
case 'DC42':
|
||||
device.reset(new ProFUSE::DiskCopy42Image(fDiskImage.c_str(), readOnly));
|
||||
device.reset(new Device::DiskCopy42Image(fDiskImage.c_str(), readOnly));
|
||||
break;
|
||||
|
||||
case 'PO__':
|
||||
device.reset(new ProFUSE::ProDOSOrderDiskImage(fDiskImage.c_str(), readOnly));
|
||||
device.reset(new Device::ProDOSOrderDiskImage(fDiskImage.c_str(), readOnly));
|
||||
break;
|
||||
|
||||
case 'DO__':
|
||||
device.reset(new ProFUSE::DOSOrderDiskImage(fDiskImage.c_str(), readOnly));
|
||||
device.reset(new Device::DOSOrderDiskImage(fDiskImage.c_str(), readOnly));
|
||||
break;
|
||||
|
||||
|
||||
@ -278,8 +280,8 @@ int main(int argc, char **argv)
|
||||
se = fuse_lowlevel_new(&args, &pascal_ops, sizeof(pascal_ops), fVolume);
|
||||
|
||||
if (se) do {
|
||||
foreground = 1;
|
||||
multithread = 0;
|
||||
//foreground = 1;
|
||||
//multithread = 0;
|
||||
|
||||
err = fuse_daemonize(foreground); // todo
|
||||
if (err < 0 ) break;
|
||||
|
@ -8,11 +8,11 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
|
||||
#define __FreeBSD__ 10
|
||||
#define __DARWIN_64_BIT_INO_T 1
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
*/
|
||||
|
||||
#define FUSE_USE_VERSION 27
|
||||
|
||||
#include <fuse/fuse_opt.h>
|
||||
@ -20,10 +20,9 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "File.h"
|
||||
#include "../auto.h"
|
||||
#include "../Exception.h"
|
||||
#include <Pascal/File.h>
|
||||
#include <ProFUSE/auto.h>
|
||||
#include <ProFUSE/Exception.h>
|
||||
|
||||
#define NO_ATTR() \
|
||||
{ \
|
||||
@ -64,11 +63,21 @@ static void pascal_init(void *userdata, struct fuse_conn_info *conn)
|
||||
{
|
||||
std::printf("pascal_init\n");
|
||||
// nop
|
||||
|
||||
// text files have a non-thread safe index.
|
||||
// which is initialized via read() or fileSize()
|
||||
VolumeEntry *volume = (VolumeEntry *)userdata;
|
||||
for (unsigned i = 0, l = volume->fileCount(); i < l; ++i)
|
||||
{
|
||||
volume->fileAtIndex(i)->fileSize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void pascal_destroy(void *userdata)
|
||||
{
|
||||
std::printf("pascal_destroy\n");
|
||||
|
||||
// nop
|
||||
}
|
||||
|
||||
@ -199,7 +208,7 @@ static void pascal_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t of
|
||||
std::printf("pascal_readdir %u, %u, %u\n", (unsigned)ino, (unsigned)size, (unsigned)off);
|
||||
|
||||
VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req);
|
||||
auto_array<uint8_t> buffer(new uint8_t[size]);
|
||||
ProFUSE::auto_array<uint8_t> buffer(new uint8_t[size]);
|
||||
unsigned count = volume->fileCount();
|
||||
|
||||
|
||||
@ -208,7 +217,7 @@ static void pascal_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t of
|
||||
|
||||
std::memset(&st, 0, sizeof(st));
|
||||
|
||||
// . && .. entries.
|
||||
// . and .. need to be added in here but are handled by the fs elsewhere.
|
||||
|
||||
do {
|
||||
if (off == 0)
|
||||
@ -408,9 +417,11 @@ static void pascal_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
|
||||
//VolumeEntry *volume = (VolumeEntry *)fuse_req_userdata(req);
|
||||
FileEntry *file = (FileEntry *)fi->fh;
|
||||
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
auto_array<uint8_t> buffer(new uint8_t[size]);
|
||||
ProFUSE::auto_array<uint8_t> buffer(new uint8_t[size]);
|
||||
unsigned rsize = file->read(buffer.get(), size, off);
|
||||
|
||||
fuse_reply_buf(req, (char *)(buffer.get()), rsize);
|
||||
|
Loading…
Reference in New Issue
Block a user