mirror of
https://github.com/ksherlock/profuse.git
synced 2025-01-18 12:29:44 +00:00
splitting up functions
git-svn-id: https://profuse.googlecode.com/svn/trunk@23 aa027e90-d47c-11dd-86d7-074df07e0730
This commit is contained in:
parent
a83fc6df28
commit
e971546b2a
785
main.cpp
785
main.cpp
@ -13,31 +13,18 @@
|
||||
#define _REENTRANT
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
*/
|
||||
#define FUSE_USE_VERSION 26
|
||||
|
||||
|
||||
|
||||
#include <fuse_lowlevel.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "common.h"
|
||||
#include "Disk.h"
|
||||
#include "File.h"
|
||||
|
||||
#include "profuse.h"
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
@ -47,12 +34,8 @@ char *dfile = NULL;
|
||||
VolumeEntry volume;
|
||||
|
||||
|
||||
#undef ERROR
|
||||
#define ERROR(cond,errno) if ( (cond) ){ fuse_reply_err(req, errno); return; }
|
||||
|
||||
|
||||
|
||||
static 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)
|
||||
// most are not legal prodos names, so this filters them out easily.
|
||||
@ -75,770 +58,9 @@ static bool validProdosName(const char *name)
|
||||
}
|
||||
|
||||
|
||||
#pragma mark XAttribute Functions
|
||||
|
||||
|
||||
static void xattr_filetype(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
uint8_t attr = e.file_type;
|
||||
unsigned attr_size = 1;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
// consider position here?
|
||||
fuse_reply_buf(req, (char *)&attr, attr_size);
|
||||
}
|
||||
|
||||
|
||||
static void xattr_auxtype(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
uint8_t attr[2];
|
||||
unsigned attr_size = 2;
|
||||
|
||||
attr[0] = e.aux_type & 0xff;
|
||||
attr[1] = (e.aux_type >> 8) & 0xff;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
// consider position here?
|
||||
fuse_reply_buf(req, (char *)&attr, attr_size);
|
||||
}
|
||||
|
||||
static void xattr_textencoding(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
// TODO -- ascii text encoding for ascii files?
|
||||
const char attr[] = "MACINTOSH;0";
|
||||
unsigned attr_size = sizeof(attr) - 1;
|
||||
|
||||
// currently only valid for Teach Files, "ASCII" Text
|
||||
|
||||
if (e.file_type == 0x04 || (e.file_type == 0x50 && e.aux_type == 0x5445))
|
||||
/* do nothing */ ;
|
||||
else
|
||||
{
|
||||
ERROR(true, ENOENT)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
// consider position here?
|
||||
fuse_reply_buf(req, (char *)&attr, attr_size);
|
||||
}
|
||||
|
||||
static void xattr_rfork(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
int ok;
|
||||
unsigned level;
|
||||
|
||||
ERROR (e.storage_type != EXTENDED_FILE, ENOENT)
|
||||
|
||||
ok = disk->Normalize(e, 1);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
level = 0;
|
||||
break;
|
||||
case SAPLING_FILE:
|
||||
level = 1;
|
||||
break;
|
||||
case TREE_FILE:
|
||||
level = 2;
|
||||
break;
|
||||
default:
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, e.eof);
|
||||
return;
|
||||
}
|
||||
|
||||
size = std::min((uint32_t)(size + off), e.eof);
|
||||
|
||||
unsigned blocks = (size + (off & 0x1ff) + BLOCK_SIZE - 1) >> 9;
|
||||
uint8_t *buffer = new uint8_t[blocks << 9];
|
||||
|
||||
fprintf(stderr, "ReadIndex(%x, buffer, %x, %x, %x)\n", e.key_pointer, level, (int)off, (int)blocks);
|
||||
|
||||
ok = disk->ReadIndex(e.key_pointer, buffer, level, off, blocks);
|
||||
|
||||
if (ok < 0)
|
||||
{
|
||||
fuse_reply_err(req, EIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
fuse_reply_buf(req, (char *)buffer + (off & 0x1ff), size);
|
||||
}
|
||||
delete []buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Finder info.
|
||||
static void xattr_finfo(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
int ok;
|
||||
ExtendedEntry ee;
|
||||
|
||||
uint8_t attr[32];
|
||||
unsigned attr_size = 32;
|
||||
|
||||
ERROR (e.storage_type != EXTENDED_FILE, ENOENT)
|
||||
|
||||
ok = disk->Normalize(e, 1, &ee);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
// sanity check
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
break;
|
||||
default:
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
memcpy(attr, ee.FInfo, 16);
|
||||
memcpy(attr + 16, ee.xFInfo, 16);
|
||||
|
||||
fuse_reply_buf(req, (char *)attr, attr_size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void prodos_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
|
||||
{
|
||||
// list of supported attributes.
|
||||
//
|
||||
#define NO_ATTR() \
|
||||
{ \
|
||||
if (size) fuse_reply_buf(req, NULL, 0); \
|
||||
else fuse_reply_xattr(req, 0); \
|
||||
return; \
|
||||
}
|
||||
|
||||
fprintf(stderr, "listxattr %u\n", ino);
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
int ok;
|
||||
unsigned attr_size;
|
||||
string attr;
|
||||
|
||||
|
||||
|
||||
if(ino == 1)
|
||||
NO_ATTR()
|
||||
|
||||
ok = disk->Read(ino >> 9, buffer);
|
||||
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
|
||||
|
||||
attr += "prodos.FileType";
|
||||
attr.append(1, 0);
|
||||
|
||||
attr += "prodos.AuxType";
|
||||
attr.append(1, 0);
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case EXTENDED_FILE:
|
||||
{
|
||||
// TODO -- pretend there's no resource fork if resource fork eof == 0 ?
|
||||
//
|
||||
//ok = disk->Normalize(e, 1);
|
||||
//ERROR(ok < 0, EIO)
|
||||
|
||||
attr += "prodos.ResourceFork";
|
||||
attr.append(1, 0);
|
||||
|
||||
attr += "com.apple.FinderInfo";
|
||||
attr.append(1, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
break;
|
||||
|
||||
case DIRECTORY_FILE:
|
||||
NO_ATTR()
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
NO_ATTR()
|
||||
break;
|
||||
}
|
||||
|
||||
if (
|
||||
e.file_type == 0x04
|
||||
|| (e.file_type == 0x50 && e.aux_type == 0x5445)) // teach text
|
||||
{
|
||||
attr += "com.apple.TextEncoding";
|
||||
attr.append(1, 0);
|
||||
}
|
||||
|
||||
attr_size = attr.length();
|
||||
|
||||
fprintf(stderr, "%d %s\n", attr_size, attr.c_str());
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < attr_size)
|
||||
{
|
||||
fuse_reply_err(req, ERANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
fuse_reply_buf(req, attr.data(), attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO -- more consistent position support.
|
||||
static void prodos_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size, uint32_t off)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
#define NO_ATTRIBUTE ENOENT
|
||||
#else
|
||||
#define NO_ATTRIBUTE EOPNOTSUPP
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "getxattr: %u %s %u %u \n", ino, name, (int)size, (int)off);
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
|
||||
|
||||
ERROR(ino == 1, NO_ATTRIBUTE) // finder can't handle EISDIR.
|
||||
|
||||
|
||||
int ok = disk->Read(ino >> 9, buffer);
|
||||
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
case EXTENDED_FILE:
|
||||
break;
|
||||
case DIRECTORY_FILE:
|
||||
ERROR(true, NO_ATTRIBUTE) // Finder can't handle EISDIR.
|
||||
default:
|
||||
ERROR(true, NO_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (strcmp("prodos.FileType", name) == 0)
|
||||
{
|
||||
xattr_filetype(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp("prodos.AuxType", name) == 0)
|
||||
{
|
||||
xattr_auxtype(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp("com.apple.TextEncoding", name) == 0)
|
||||
{
|
||||
xattr_textencoding(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (e.storage_type == EXTENDED_FILE) && (strcmp("prodos.ResourceFork", name) == 0))
|
||||
{
|
||||
xattr_rfork(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (e.storage_type == EXTENDED_FILE) && (strcmp("com.apple.FinderInfo", name) == 0))
|
||||
{
|
||||
xattr_finfo(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fuse_reply_err(req, NO_ATTRIBUTE);
|
||||
|
||||
}
|
||||
/*
|
||||
* Linux, et alia do not have an offset parameter.
|
||||
*/
|
||||
static void prodos_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
|
||||
{
|
||||
prodos_getxattr(req, ino, name, size, 0);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Directory Functions
|
||||
|
||||
/*
|
||||
* when the directory is opened, we load the volume/directory and store the FileEntry vector into
|
||||
* fi->fh.
|
||||
*
|
||||
*/
|
||||
static void prodos_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "opendir: %u\n", ino);
|
||||
// verify it's a directory/volume here?
|
||||
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
vector<FileEntry> files;
|
||||
bool ok;
|
||||
|
||||
|
||||
ok = disk->Read(ino == 1 ? 2 : ino >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
if (ino == 1)
|
||||
{
|
||||
VolumeEntry v(buffer + 0x04);
|
||||
|
||||
ok = disk->ReadVolume(&v, &files);
|
||||
|
||||
ERROR(ok < 0, EIO)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
|
||||
ERROR(e.storage_type != DIRECTORY_FILE, ENOTDIR)
|
||||
|
||||
ok = disk->ReadDirectory(e.key_pointer, NULL, &files);
|
||||
|
||||
ERROR(ok < 0, EIO);
|
||||
}
|
||||
|
||||
// copy the vector contents to a vector *.
|
||||
vector<FileEntry> *fp = new vector<FileEntry>();
|
||||
files.swap(*fp);
|
||||
|
||||
fi->fh = (uint64_t)fp;
|
||||
fuse_reply_open(req, fi);
|
||||
}
|
||||
|
||||
static void prodos_releasedir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr,"releasedir: %d\n", ino);
|
||||
vector<FileEntry> *files = (vector<FileEntry> *)fi->fh;
|
||||
|
||||
if (files) delete files;
|
||||
|
||||
fuse_reply_err(req, 0);
|
||||
}
|
||||
static void prodos_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi)
|
||||
{
|
||||
vector<FileEntry> *files = (vector<FileEntry> *)fi->fh;
|
||||
struct stat st;
|
||||
|
||||
fprintf(stderr, "readdir %u %u %u\n", ino, size, off);
|
||||
|
||||
// TODO -- add "." and ".." entries...
|
||||
|
||||
|
||||
// if the offset >= number of entries, get out.
|
||||
if (!files || files->size() <= off)
|
||||
{
|
||||
fprintf(stderr, "fuse_reply_buf(req, NULL, 0)\n");
|
||||
fuse_reply_buf(req, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// now some dirent info...
|
||||
|
||||
bzero(&st, sizeof(st));
|
||||
// only mode and ino are used.
|
||||
|
||||
char *buffer = new char[size];
|
||||
|
||||
unsigned count = files->size();
|
||||
unsigned current_size = 0;
|
||||
for (unsigned i = off; i < count; ++i)
|
||||
{
|
||||
FileEntry &f = (*files)[i];
|
||||
|
||||
st.st_mode = f.storage_type == DIRECTORY_FILE ? S_IFDIR | 0555 : S_IFREG | 0444;
|
||||
st.st_ino = f.address;
|
||||
|
||||
unsigned entry_size = fuse_add_direntry(req, NULL, 0, f.file_name, NULL, 0);
|
||||
if (entry_size + current_size >= size) break;
|
||||
|
||||
|
||||
fuse_add_direntry(req, (char *)buffer + current_size, size, f.file_name, &st, i + 1);
|
||||
current_size += entry_size;
|
||||
|
||||
}
|
||||
|
||||
fuse_reply_buf(req, buffer, current_size);
|
||||
delete []buffer;
|
||||
}
|
||||
|
||||
#pragma mark Stat Functions
|
||||
|
||||
int prodos_stat(FileEntry& e, struct stat *st)
|
||||
{
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
int ok;
|
||||
|
||||
|
||||
if (e.storage_type == EXTENDED_FILE)
|
||||
{
|
||||
ok = disk->Normalize(e, 0);
|
||||
if (ok < 0) return ok;
|
||||
}
|
||||
|
||||
st->st_blksize = BLOCK_SIZE;
|
||||
|
||||
st->st_ctime = e.creation;
|
||||
#ifdef HAVE_STAT_BIRTHTIME
|
||||
st->st_birthtime = e.creation;
|
||||
#endif
|
||||
|
||||
st->st_mtime = e.last_mod;
|
||||
st->st_atime = e.last_mod;
|
||||
|
||||
|
||||
st->st_nlink = 1;
|
||||
st->st_mode = 0444 | S_IFREG;
|
||||
st->st_size = e.eof;
|
||||
|
||||
|
||||
if (e.storage_type == DIRECTORY_FILE)
|
||||
{
|
||||
ok = disk->Read(e.key_pointer, buffer);
|
||||
if (ok < 0) return -1;
|
||||
|
||||
SubdirEntry se(buffer + 0x04);
|
||||
|
||||
if (se.storage_type != SUBDIR_HEADER) return -1;
|
||||
|
||||
st->st_mode = S_IFDIR | 0555;
|
||||
st->st_size = BLOCK_SIZE;
|
||||
st->st_nlink = se.file_count + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
//case PASCAL_FILE:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prodos_stat(const VolumeEntry &v, struct stat *st)
|
||||
{
|
||||
|
||||
if (v.storage_type != VOLUME_HEADER) return -1;
|
||||
|
||||
st->st_mode = S_IFDIR | 0555;
|
||||
st->st_ctime = v.creation;
|
||||
|
||||
#ifdef HAVE_STAT_BIRTHTIME
|
||||
st->st_birthtime = v.creation;
|
||||
#endif
|
||||
st->st_mtime = v.creation;
|
||||
st->st_atime = v.creation;
|
||||
|
||||
st->st_nlink = v.file_count + 1;
|
||||
st->st_size = BLOCK_SIZE;
|
||||
st->st_blksize = BLOCK_SIZE;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void prodos_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
struct stat st;
|
||||
int ok;
|
||||
|
||||
fprintf(stderr, "get_attr %u\n", ino);
|
||||
|
||||
bzero(&st, sizeof(st));
|
||||
|
||||
/*
|
||||
* ino 1 is the volume header. Others are pointers.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
ok = disk->Read(ino == 1 ? 2 : ino >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
// ino 1 is the volume header.
|
||||
if (ino == 1)
|
||||
{
|
||||
VolumeEntry v(buffer + 0x04);
|
||||
ok = prodos_stat(v, &st);
|
||||
ERROR(ok < 0, EIO);
|
||||
|
||||
st.st_ino = ino;
|
||||
|
||||
fuse_reply_attr(req, &st, 0.0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
ok = prodos_stat(e, &st);
|
||||
|
||||
ERROR(ok < 0, EIO);
|
||||
|
||||
st.st_ino = ino;
|
||||
|
||||
fuse_reply_attr(req, &st, 0.0); //
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO -- add Disk::Lookup support so we don't have to parse the entire dir header.
|
||||
static void prodos_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
|
||||
{
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
struct fuse_entry_param entry;
|
||||
int ok;
|
||||
vector<FileEntry> files;
|
||||
|
||||
|
||||
fprintf(stderr, "lookup: %d %s\n", parent, name);
|
||||
|
||||
ERROR(!validProdosName(name), ENOENT)
|
||||
|
||||
ok = disk->Read(parent == 1 ? 2 : parent >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
bzero(&entry, sizeof(entry));
|
||||
|
||||
entry.attr_timeout = 0.0;
|
||||
entry.entry_timeout = 0.0;
|
||||
|
||||
// get the file list
|
||||
// TODO -- Disk::look-up-one-file
|
||||
if (parent == 1)
|
||||
{
|
||||
VolumeEntry v;
|
||||
ok = disk->ReadVolume(&v, &files);
|
||||
ERROR(ok < 0, EIO)
|
||||
}
|
||||
else
|
||||
{
|
||||
FileEntry e(buffer + (parent & 0x1ff));
|
||||
ERROR(e.storage_type != DIRECTORY_FILE, ENOENT);
|
||||
|
||||
ok = disk->ReadDirectory(e.key_pointer, NULL, &files);
|
||||
ERROR(ok < 0, EIO)
|
||||
}
|
||||
// ok, now go through the file list and look for a (case insensitive) match.
|
||||
|
||||
|
||||
ok = -1;
|
||||
unsigned name_length = strlen(name);
|
||||
|
||||
for(vector<FileEntry>::iterator iter = files.begin(); iter != files.end(); iter++)
|
||||
{
|
||||
FileEntry& f = *iter;
|
||||
if ( (f.name_length == name_length) && (strcasecmp(name, f.file_name) == 0))
|
||||
{
|
||||
ok = prodos_stat(f, &entry.attr);
|
||||
fprintf(stderr, "stat %s %x (%x %x) %d\n", f.file_name, f.address, f.address >> 9, f.address & 0x1ff, ok);
|
||||
entry.ino = f.address;
|
||||
entry.attr.st_ino = f.address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR(ok < 0, ENOENT);
|
||||
|
||||
fprintf(stderr, "file found!\n");
|
||||
|
||||
fuse_reply_entry(req, &entry);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Read Functions
|
||||
static void prodos_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "open: %u\n", ino);
|
||||
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
int ok;
|
||||
|
||||
FileEntry *e = NULL;
|
||||
|
||||
ERROR(ino == 1, EISDIR)
|
||||
|
||||
ok = disk->Read(ino >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
e = new FileEntry(buffer + (ino & 0x1ff));
|
||||
|
||||
if (e->storage_type == EXTENDED_FILE)
|
||||
{
|
||||
ok = disk->Normalize(*e, 0);
|
||||
|
||||
if (ok < 0)
|
||||
{
|
||||
delete e;
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
}
|
||||
|
||||
// EXTENDED_FILE already handled (it would be an error here.)
|
||||
switch(e->storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
break;
|
||||
//case PASCAL_FILE: //?
|
||||
case DIRECTORY_FILE:
|
||||
delete e;
|
||||
ERROR(true, EISDIR)
|
||||
break;
|
||||
default:
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
|
||||
if ( (fi->flags & O_ACCMODE) != O_RDONLY)
|
||||
{
|
||||
delete e;
|
||||
ERROR(true, EACCES);
|
||||
}
|
||||
fi->fh = (uint64_t)e;
|
||||
|
||||
fuse_reply_open(req, fi);
|
||||
}
|
||||
|
||||
static void prodos_release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "release: %d\n", ino);
|
||||
|
||||
FileEntry *e = (FileEntry *)fi->fh;
|
||||
|
||||
if (e) delete e;
|
||||
|
||||
fuse_reply_err(req, 0);
|
||||
|
||||
}
|
||||
|
||||
static void prodos_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "read: %u %u %u\n", ino, size, off);
|
||||
|
||||
FileEntry *e = (FileEntry *)fi->fh;
|
||||
|
||||
ERROR(e == NULL, EIO)
|
||||
|
||||
if (off >= e->eof)
|
||||
{
|
||||
fuse_reply_buf(req, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned level = 0;
|
||||
switch(e->storage_type)
|
||||
{
|
||||
case TREE_FILE:
|
||||
level = 2;
|
||||
break;
|
||||
case SAPLING_FILE:
|
||||
level = 1;
|
||||
break;
|
||||
case SEEDLING_FILE:
|
||||
level = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// currently, reading is done on a block basis.
|
||||
// experimentally, fuse reads the entire file
|
||||
// this may not hold for larger files.
|
||||
|
||||
|
||||
// TODO -- error if size + off > eof.
|
||||
|
||||
unsigned blocks = (size + (off & 0x1ff) + BLOCK_SIZE - 1) >> 9;
|
||||
int ok;
|
||||
uint8_t *buffer = new uint8_t[blocks << 9];
|
||||
|
||||
fprintf(stderr, "ReadIndex(%x, buffer, %x, %x, %x)\n", e->key_pointer, level, (int)off, (int)blocks);
|
||||
|
||||
ok = disk->ReadIndex(e->key_pointer, buffer, level, off, blocks);
|
||||
if (ok < 0)
|
||||
{
|
||||
fuse_reply_err(req, EIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
fuse_reply_buf(req, (const char *)buffer + (off & 0x1ff), size);
|
||||
}
|
||||
|
||||
delete []buffer;
|
||||
}
|
||||
|
||||
|
||||
static struct fuse_lowlevel_ops prodos_oper;
|
||||
@ -897,6 +119,7 @@ bool make_mount_dir(string name, string &path)
|
||||
|
||||
if (name.find('/') != string::npos) return false;
|
||||
if (name.find('\\') != string::npos) return false;
|
||||
if (name.find(':') != string::npos) return false;
|
||||
|
||||
path = "";
|
||||
path = "/Volumes/" + name;
|
||||
@ -905,7 +128,7 @@ bool make_mount_dir(string name, string &path)
|
||||
|
||||
for (unsigned i = 0; i < 26; i++)
|
||||
{
|
||||
path = "/Volumes/" + name + "_" + (char)('a' + i);
|
||||
path = "/Volumes/" + name + " " + (char)('a' + i);
|
||||
|
||||
rmdir(path.c_str());
|
||||
if (mkdir(path.c_str(), 0777) == 0) return true;
|
||||
|
@ -2,7 +2,7 @@
|
||||
CC=g++
|
||||
CFLAGS=-c $(shell pkg-config fuse --cflags)
|
||||
LDFLAGS=$(shell pkg-config fuse --libs)
|
||||
SOURCES=main.cpp File.cpp Disk.cpp DiskCopy42.cpp UniversalDiskImage.cpp
|
||||
SOURCES=main.cpp File.cpp Disk.cpp DiskCopy42.cpp UniversalDiskImage.cpp profuse_dirent.cpp profuse_file.cpp profuse_stat.cpp profuse_xattr.cpp
|
||||
OBJECTS=$(SOURCES:.cpp=.o)
|
||||
EXECUTABLE=profuse
|
||||
|
||||
@ -22,4 +22,12 @@ File.o: File.cpp File.h
|
||||
|
||||
Disk.o: Disk.cpp Disk.h File.h DiskCopy42.h UniversalDiskImage.h
|
||||
|
||||
main.o: main.cpp Disk.h File.h
|
||||
main.o: main.cpp Disk.h File.h profuse.h
|
||||
|
||||
profuse_dirent.o: profuse_dirent.cpp profuse.h
|
||||
|
||||
profuse_file.o: profuse_file.cpp profuse.h
|
||||
|
||||
profuse_stat.o: profuse_stat.cpp profuse.h
|
||||
|
||||
profuse_xattr.o: profuse_xattr.cpp profuse.h
|
||||
|
50
profuse.h
Normal file
50
profuse.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* profuse.h
|
||||
* profuse
|
||||
*
|
||||
* Created by Kelvin Sherlock on 1/23/2009.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PROFUSE_H__
|
||||
#define __PROFUSE_H__
|
||||
|
||||
#include "File.h"
|
||||
#include "Disk.h"
|
||||
#include "common.h"
|
||||
|
||||
#define FUSE_USE_VERSION 26
|
||||
|
||||
#include <fuse_lowlevel.h>
|
||||
|
||||
|
||||
#undef ERROR
|
||||
#define ERROR(cond,errno) if ( (cond) ){ fuse_reply_err(req, errno); return; }
|
||||
|
||||
|
||||
extern Disk *disk;
|
||||
|
||||
bool validProdosName(const char *name);
|
||||
|
||||
// xattr
|
||||
void prodos_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size, uint32_t off);
|
||||
void prodos_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size);
|
||||
void prodos_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size);
|
||||
|
||||
//dirent
|
||||
void prodos_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
|
||||
void prodos_releasedir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
|
||||
void prodos_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi);
|
||||
|
||||
// stat
|
||||
void prodos_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
|
||||
void prodos_lookup(fuse_req_t req, fuse_ino_t parent, const char *name);
|
||||
|
||||
// file io.
|
||||
void prodos_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
|
||||
void prodos_release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi);
|
||||
void prodos_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi);
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -197,94 +197,7 @@
|
||||
<key>Notifications</key>
|
||||
<array/>
|
||||
<key>OpenEditors</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Content</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>B61B78650F16CB1000C3E140</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>main.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>B61B78660F16CB1000C3E140</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>main.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>B61B78980F16DE8200C3E140</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>B61B78610F16CB0D00C3E140</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
<key>StatusBarVisibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Geometry</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 20}, {1412, 827}}</string>
|
||||
<key>PBXModuleWindowStatusBarHidden2</key>
|
||||
<false/>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>428 146 1412 868 0 0 1920 1178 </string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Content</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>B61B78720F16CE3800C3E140</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Disk.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>B61B78730F16CE3800C3E140</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Disk.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>B61B78990F16DE8200C3E140</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>B61B78740F16CE3800C3E140</string>
|
||||
<string>B61B78750F16CE3800C3E140</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
<string>B61B78760F16CE3800C3E140</string>
|
||||
<string>B61B78770F16CE3800C3E140</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
<key>StatusBarVisibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>Geometry</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 20}, {692, 1074}}</string>
|
||||
<key>PBXModuleWindowStatusBarHidden2</key>
|
||||
<false/>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>943 50 692 1115 0 0 1920 1178 </string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<array/>
|
||||
<key>PerspectiveWidths</key>
|
||||
<array>
|
||||
<integer>-1</integer>
|
||||
@ -369,8 +282,7 @@
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
<array>
|
||||
<integer>6</integer>
|
||||
<integer>1</integer>
|
||||
<integer>17</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</array>
|
||||
@ -412,7 +324,7 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CE0B20306471E060097A5F4</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Disk.cpp</string>
|
||||
<string>DiskCopy42.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
@ -420,23 +332,27 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CE0B20406471E060097A5F4</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Disk.cpp</string>
|
||||
<string>DiskCopy42.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>B61B78970F16DE8200C3E140</string>
|
||||
<string>B6C786F40F2A612600053681</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>B6614B050EFF5F280073C4E7</string>
|
||||
<string>B679E4B60F02EFA200FB3F0C</string>
|
||||
<string>B6DBB4F10F0C6CD800F385F2</string>
|
||||
<string>B6B767C80F0FFA3900D819C9</string>
|
||||
<string>B6B17F940F1136550060F7AA</string>
|
||||
<string>B642F1530F133632001F7696</string>
|
||||
<string>B642F1540F133632001F7696</string>
|
||||
<string>B642F16A0F1341D4001F7696</string>
|
||||
<string>B61B78A20F16EA8700C3E140</string>
|
||||
<string>B6C786E50F2A5FF300053681</string>
|
||||
<string>B6C786E60F2A5FF300053681</string>
|
||||
<string>B6C786E70F2A5FF300053681</string>
|
||||
<string>B6C786EE0F2A612600053681</string>
|
||||
<string>B6C786EF0F2A612600053681</string>
|
||||
<string>B6C786F00F2A612600053681</string>
|
||||
<string>B6B7A85F0F140BBB001024D2</string>
|
||||
<string>B6B7A87E0F144D05001024D2</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
@ -450,6 +366,12 @@
|
||||
<string>B6B17F950F1136550060F7AA</string>
|
||||
<string>B6B17FA80F1140160060F7AA</string>
|
||||
<string>B6B7A8600F140BBB001024D2</string>
|
||||
<string>B6C786E80F2A5FF300053681</string>
|
||||
<string>B6C786E90F2A5FF300053681</string>
|
||||
<string>B6C786EA0F2A5FF300053681</string>
|
||||
<string>B6C786F10F2A612600053681</string>
|
||||
<string>B6C786F20F2A612600053681</string>
|
||||
<string>B6C786F30F2A612600053681</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
@ -507,9 +429,9 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>B61B78630F16CB1000C3E140</string>
|
||||
<string>B6C786AB0F2A598F00053681</string>
|
||||
<string>1CE0B1FE06471DED0097A5F4</string>
|
||||
<string>B61B78640F16CB1000C3E140</string>
|
||||
<string>B6C786AC0F2A598F00053681</string>
|
||||
<string>1CE0B20306471E060097A5F4</string>
|
||||
<string>1CE0B20506471E060097A5F4</string>
|
||||
</array>
|
||||
@ -644,9 +566,8 @@
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>B60E918C0EFD7E1E000E4348</string>
|
||||
<string>B61B78720F16CE3800C3E140</string>
|
||||
<string>1CD10A99069EF8BA00B06720</string>
|
||||
<string>/Users/kelvin/Projects/profuse/profuse.xcodeproj</string>
|
||||
<string>B61B78650F16CB1000C3E140</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
<string>189 537 1212 568 0 0 1920 1178 </string>
|
||||
@ -665,12 +586,14 @@
|
||||
<key>Dock</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>BecomeActive</key>
|
||||
<true/>
|
||||
<key>ContentConfiguration</key>
|
||||
<dict>
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1CD0528F0623707200166675</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string></string>
|
||||
<string>profuse_xattr.cpp</string>
|
||||
<key>StatusBarVisibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
@ -728,7 +651,7 @@
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>B60E918C0EFD7E1E000E4348</string>
|
||||
<string>B61B78790F16CE3800C3E140</string>
|
||||
<string>B6C786CB0F2A5E8000053681</string>
|
||||
<string>1CD0528F0623707200166675</string>
|
||||
<string>XCMainBuildResultsModuleGUID</string>
|
||||
</array>
|
||||
@ -848,13 +771,13 @@
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>1CD10A99069EF8BA00B06720</string>
|
||||
<string>B6B7A8730F140D48001024D2</string>
|
||||
<string>B6C786AD0F2A598F00053681</string>
|
||||
<string>1C162984064C10D400B95A72</string>
|
||||
<string>B6B7A8740F140D48001024D2</string>
|
||||
<string>B6B7A8750F140D48001024D2</string>
|
||||
<string>B6B7A8760F140D48001024D2</string>
|
||||
<string>B6B7A8770F140D48001024D2</string>
|
||||
<string>B6B7A8780F140D48001024D2</string>
|
||||
<string>B6C786AE0F2A598F00053681</string>
|
||||
<string>B6C786AF0F2A598F00053681</string>
|
||||
<string>B6C786B00F2A598F00053681</string>
|
||||
<string>B6C786B10F2A598F00053681</string>
|
||||
<string>B6C786B20F2A598F00053681</string>
|
||||
</array>
|
||||
<key>ToolbarConfiguration</key>
|
||||
<string>xcode.toolbar.config.debugV3</string>
|
||||
@ -1080,7 +1003,7 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>1C78EAB2065D492600B07095</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>Disk.cpp</string>
|
||||
<string>main.cpp</string>
|
||||
<key>StatusBarVisibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
@ -1157,7 +1080,7 @@
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>B60E929F0EFDA500000E4348</string>
|
||||
<string>B6B7A85B0F140B41001024D2</string>
|
||||
<string>B61B78A60F16EA8700C3E140</string>
|
||||
<string>1C78EAB2065D492600B07095</string>
|
||||
<string>1CD052920623707200166675</string>
|
||||
</array>
|
||||
@ -1168,7 +1091,7 @@
|
||||
<key>WindowToolGUID</key>
|
||||
<string>B60E929F0EFDA500000E4348</string>
|
||||
<key>WindowToolIsVisible</key>
|
||||
<false/>
|
||||
<true/>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Identifier</key>
|
||||
|
@ -12,13 +12,41 @@
|
||||
B60E91C10EFD8049000E4348 /* xmain.cpp:129 */,
|
||||
B60E92720EFDA086000E4348 /* File.cpp:88 */,
|
||||
B6D81E5B0EFDE859000219B7 /* xmain.cpp:163 */,
|
||||
B6AE1CFF0F0335FC00D36ADB /* main.cpp:30 */,
|
||||
B6AE1CFF0F0335FC00D36ADB /* main.cpp:20 */,
|
||||
);
|
||||
codeSenseManager = B60E91510EFB3628000E4348 /* Code sense */;
|
||||
executables = (
|
||||
B60E914A0EFB3612000E4348 /* profuse */,
|
||||
);
|
||||
perUserDictionary = {
|
||||
PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
|
||||
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
|
||||
PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID;
|
||||
PBXFileTableDataSourceColumnWidthsKey = (
|
||||
20,
|
||||
300,
|
||||
595,
|
||||
);
|
||||
PBXFileTableDataSourceColumnsKey = (
|
||||
PBXErrorsWarningsDataSource_TypeID,
|
||||
PBXErrorsWarningsDataSource_MessageID,
|
||||
PBXErrorsWarningsDataSource_LocationID,
|
||||
);
|
||||
};
|
||||
PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
|
||||
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
|
||||
PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
|
||||
PBXFileTableDataSourceColumnWidthsKey = (
|
||||
22,
|
||||
300,
|
||||
593,
|
||||
);
|
||||
PBXFileTableDataSourceColumnsKey = (
|
||||
PBXExecutablesDataSource_ActiveFlagID,
|
||||
PBXExecutablesDataSource_NameID,
|
||||
PBXExecutablesDataSource_CommentsID,
|
||||
);
|
||||
};
|
||||
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
|
||||
PBXFileTableDataSourceColumnSortingDirectionKey = 1;
|
||||
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
|
||||
@ -87,8 +115,8 @@
|
||||
PBXFileDataSource_Warnings_ColumnID,
|
||||
);
|
||||
};
|
||||
PBXPerProjectTemplateStateSaveDate = 253152006;
|
||||
PBXWorkspaceStateSaveDate = 253152006;
|
||||
PBXPerProjectTemplateStateSaveDate = 254433671;
|
||||
PBXWorkspaceStateSaveDate = 254433671;
|
||||
};
|
||||
perUserProjectItems = {
|
||||
B60E917F0EFD7E1E000E4348 = B60E917F0EFD7E1E000E4348 /* PBXTextBookmark */;
|
||||
@ -96,37 +124,11 @@
|
||||
B60E91810EFD7E1E000E4348 = B60E91810EFD7E1E000E4348 /* PBXTextBookmark */;
|
||||
B60E922B0EFD94CA000E4348 = B60E922B0EFD94CA000E4348 /* PBXTextBookmark */;
|
||||
B60E929C0EFDA500000E4348 = B60E929C0EFDA500000E4348 /* PBXTextBookmark */;
|
||||
B61B78610F16CB0D00C3E140 /* PBXBookmark */ = B61B78610F16CB0D00C3E140 /* PBXBookmark */;
|
||||
B61B78620F16CB1000C3E140 /* PBXTextBookmark */ = B61B78620F16CB1000C3E140 /* PBXTextBookmark */;
|
||||
B61B78670F16CB1000C3E140 /* PBXTextBookmark */ = B61B78670F16CB1000C3E140 /* PBXTextBookmark */;
|
||||
B61B78700F16CE3800C3E140 /* PBXTextBookmark */ = B61B78700F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B78710F16CE3800C3E140 /* PBXTextBookmark */ = B61B78710F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B78740F16CE3800C3E140 /* PBXTextBookmark */ = B61B78740F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B78750F16CE3800C3E140 /* PBXTextBookmark */ = B61B78750F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B78760F16CE3800C3E140 /* PBXTextBookmark */ = B61B78760F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B78770F16CE3800C3E140 /* PBXTextBookmark */ = B61B78770F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B78780F16CE3800C3E140 /* PBXTextBookmark */ = B61B78780F16CE3800C3E140 /* PBXTextBookmark */;
|
||||
B61B787B0F16CE8800C3E140 /* PBXTextBookmark */ = B61B787B0F16CE8800C3E140 /* PBXTextBookmark */;
|
||||
B61B787C0F16CE8800C3E140 /* PBXTextBookmark */ = B61B787C0F16CE8800C3E140 /* PBXTextBookmark */;
|
||||
B61B787D0F16CE8800C3E140 /* PBXTextBookmark */ = B61B787D0F16CE8800C3E140 /* PBXTextBookmark */;
|
||||
B61B787E0F16CF8D00C3E140 /* PBXTextBookmark */ = B61B787E0F16CF8D00C3E140 /* PBXTextBookmark */;
|
||||
B61B787F0F16CF8D00C3E140 /* PBXTextBookmark */ = B61B787F0F16CF8D00C3E140 /* PBXTextBookmark */;
|
||||
B61B78800F16CF8D00C3E140 /* PBXTextBookmark */ = B61B78800F16CF8D00C3E140 /* PBXTextBookmark */;
|
||||
B61B78830F16D04E00C3E140 /* PBXTextBookmark */ = B61B78830F16D04E00C3E140 /* PBXTextBookmark */;
|
||||
B61B78840F16D04E00C3E140 /* PBXTextBookmark */ = B61B78840F16D04E00C3E140 /* PBXTextBookmark */;
|
||||
B61B78850F16D04E00C3E140 /* PBXTextBookmark */ = B61B78850F16D04E00C3E140 /* PBXTextBookmark */;
|
||||
B61B788A0F16D9F000C3E140 /* PBXTextBookmark */ = B61B788A0F16D9F000C3E140 /* PBXTextBookmark */;
|
||||
B61B788B0F16D9F000C3E140 /* PBXTextBookmark */ = B61B788B0F16D9F000C3E140 /* PBXTextBookmark */;
|
||||
B61B788C0F16D9F000C3E140 /* PBXTextBookmark */ = B61B788C0F16D9F000C3E140 /* PBXTextBookmark */;
|
||||
B61B78930F16DE1400C3E140 /* PBXTextBookmark */ = B61B78930F16DE1400C3E140 /* PBXTextBookmark */;
|
||||
B61B78940F16DE1400C3E140 /* PBXTextBookmark */ = B61B78940F16DE1400C3E140 /* PBXTextBookmark */;
|
||||
B61B78950F16DE1400C3E140 /* PBXTextBookmark */ = B61B78950F16DE1400C3E140 /* PBXTextBookmark */;
|
||||
B61B78970F16DE8200C3E140 /* PBXTextBookmark */ = B61B78970F16DE8200C3E140 /* PBXTextBookmark */;
|
||||
B61B78980F16DE8200C3E140 /* PBXTextBookmark */ = B61B78980F16DE8200C3E140 /* PBXTextBookmark */;
|
||||
B61B78990F16DE8200C3E140 /* PBXTextBookmark */ = B61B78990F16DE8200C3E140 /* PBXTextBookmark */;
|
||||
B61B78A20F16EA8700C3E140 = B61B78A20F16EA8700C3E140 /* PBXTextBookmark */;
|
||||
B61B78A40F16EA8700C3E140 = B61B78A40F16EA8700C3E140 /* PBXTextBookmark */;
|
||||
B6340C7B0F22C271008931E1 = B6340C7B0F22C271008931E1 /* PBXTextBookmark */;
|
||||
B642F1530F133632001F7696 = B642F1530F133632001F7696 /* PBXTextBookmark */;
|
||||
B642F1540F133632001F7696 = B642F1540F133632001F7696 /* PBXTextBookmark */;
|
||||
B642F1550F133632001F7696 = B642F1550F133632001F7696 /* PBXTextBookmark */;
|
||||
B642F16A0F1341D4001F7696 = B642F16A0F1341D4001F7696 /* PBXTextBookmark */;
|
||||
B6614B050EFF5F280073C4E7 = B6614B050EFF5F280073C4E7 /* PBXTextBookmark */;
|
||||
B679E4B60F02EFA200FB3F0C = B679E4B60F02EFA200FB3F0C /* PBXTextBookmark */;
|
||||
@ -138,8 +140,31 @@
|
||||
B6B767CB0F0FFA3900D819C9 = B6B767CB0F0FFA3900D819C9 /* PBXTextBookmark */;
|
||||
B6B7A85F0F140BBB001024D2 = B6B7A85F0F140BBB001024D2 /* PBXTextBookmark */;
|
||||
B6B7A8600F140BBB001024D2 = B6B7A8600F140BBB001024D2 /* PBXTextBookmark */;
|
||||
B6B7A87E0F144D05001024D2 = B6B7A87E0F144D05001024D2 /* PBXTextBookmark */;
|
||||
B6DBB4F10F0C6CD800F385F2 = B6DBB4F10F0C6CD800F385F2 /* PBXTextBookmark */;
|
||||
B6C786AA0F2A598F00053681 /* PBXTextBookmark */ = B6C786AA0F2A598F00053681 /* PBXTextBookmark */;
|
||||
B6C786C90F2A5E8000053681 /* PBXTextBookmark */ = B6C786C90F2A5E8000053681 /* PBXTextBookmark */;
|
||||
B6C786CA0F2A5E8000053681 /* PBXTextBookmark */ = B6C786CA0F2A5E8000053681 /* PBXTextBookmark */;
|
||||
B6C786DD0F2A5FED00053681 /* PBXTextBookmark */ = B6C786DD0F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786DE0F2A5FED00053681 /* PBXTextBookmark */ = B6C786DE0F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786DF0F2A5FED00053681 /* PBXTextBookmark */ = B6C786DF0F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786E00F2A5FED00053681 /* PBXTextBookmark */ = B6C786E00F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786E10F2A5FED00053681 /* PBXTextBookmark */ = B6C786E10F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786E20F2A5FED00053681 /* PBXTextBookmark */ = B6C786E20F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786E30F2A5FED00053681 /* PBXTextBookmark */ = B6C786E30F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786E40F2A5FED00053681 /* PBXTextBookmark */ = B6C786E40F2A5FED00053681 /* PBXTextBookmark */;
|
||||
B6C786E50F2A5FF300053681 /* PBXTextBookmark */ = B6C786E50F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786E60F2A5FF300053681 /* PBXTextBookmark */ = B6C786E60F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786E70F2A5FF300053681 /* PBXTextBookmark */ = B6C786E70F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786E80F2A5FF300053681 /* PBXTextBookmark */ = B6C786E80F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786E90F2A5FF300053681 /* PBXTextBookmark */ = B6C786E90F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786EA0F2A5FF300053681 /* PBXTextBookmark */ = B6C786EA0F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786EB0F2A5FF300053681 /* PBXTextBookmark */ = B6C786EB0F2A5FF300053681 /* PBXTextBookmark */;
|
||||
B6C786EE0F2A612600053681 /* PBXTextBookmark */ = B6C786EE0F2A612600053681 /* PBXTextBookmark */;
|
||||
B6C786EF0F2A612600053681 /* PBXTextBookmark */ = B6C786EF0F2A612600053681 /* PBXTextBookmark */;
|
||||
B6C786F00F2A612600053681 /* PBXTextBookmark */ = B6C786F00F2A612600053681 /* PBXTextBookmark */;
|
||||
B6C786F10F2A612600053681 /* PBXTextBookmark */ = B6C786F10F2A612600053681 /* PBXTextBookmark */;
|
||||
B6C786F20F2A612600053681 /* PBXTextBookmark */ = B6C786F20F2A612600053681 /* PBXTextBookmark */;
|
||||
B6C786F30F2A612600053681 /* PBXTextBookmark */ = B6C786F30F2A612600053681 /* PBXTextBookmark */;
|
||||
B6C786F40F2A612600053681 /* PBXTextBookmark */ = B6C786F40F2A612600053681 /* PBXTextBookmark */;
|
||||
};
|
||||
sourceControlManager = B60E91500EFB3628000E4348 /* Source Control */;
|
||||
userBuildSettings = {
|
||||
@ -228,10 +253,10 @@
|
||||
};
|
||||
B60E91540EFB51FE000E4348 /* Disk.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {633, 8064}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {633, 7826}}";
|
||||
sepNavSelRange = "{9022, 68}";
|
||||
sepNavVisRange = "{8353, 1853}";
|
||||
sepNavWindowFrame = "{{511, 7}, {692, 1171}}";
|
||||
sepNavWindowFrame = "{{943, -6}, {692, 1171}}";
|
||||
};
|
||||
};
|
||||
B60E91580EFD77E3000E4348 /* common.h */ = {
|
||||
@ -326,11 +351,7 @@
|
||||
vrLen = 345;
|
||||
vrLoc = 1359;
|
||||
};
|
||||
B61B78610F16CB0D00C3E140 /* PBXBookmark */ = {
|
||||
isa = PBXBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
};
|
||||
B61B78620F16CB1000C3E140 /* PBXTextBookmark */ = {
|
||||
B61B78A20F16EA8700C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
@ -340,265 +361,25 @@
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B78670F16CB1000C3E140 /* PBXTextBookmark */ = {
|
||||
B61B78A40F16EA8700C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 832";
|
||||
name = "main.cpp: 33";
|
||||
rLen = 0;
|
||||
rLoc = 18035;
|
||||
rLoc = 323;
|
||||
rType = 0;
|
||||
vrLen = 1165;
|
||||
vrLoc = 17670;
|
||||
vrLen = 330;
|
||||
vrLoc = 441;
|
||||
};
|
||||
B61B78700F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B78710F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
B6340C7B0F22C271008931E1 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 920";
|
||||
rLen = 16;
|
||||
rLoc = 20849;
|
||||
rType = 0;
|
||||
vrLen = 1338;
|
||||
vrLoc = 18850;
|
||||
};
|
||||
B61B78740F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91530EFB51FE000E4348 /* Disk.h */;
|
||||
name = "Disk.h: 3";
|
||||
name = "main.cpp: 33";
|
||||
rLen = 0;
|
||||
rLoc = 25;
|
||||
rLoc = 323;
|
||||
rType = 0;
|
||||
vrLen = 1184;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B61B78750F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 1220;
|
||||
vrLoc = 78;
|
||||
};
|
||||
B61B78760F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 1220;
|
||||
vrLoc = 78;
|
||||
};
|
||||
B61B78770F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91530EFB51FE000E4348 /* Disk.h */;
|
||||
name = "Disk.h: 3";
|
||||
rLen = 0;
|
||||
rLoc = 25;
|
||||
rType = 0;
|
||||
vrLen = 1184;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B61B78780F16CE3800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
};
|
||||
B61B787B0F16CE8800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B787C0F16CE8800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 922";
|
||||
rLen = 0;
|
||||
rLoc = 20932;
|
||||
rType = 0;
|
||||
vrLen = 1338;
|
||||
vrLoc = 18850;
|
||||
};
|
||||
B61B787D0F16CE8800C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
};
|
||||
B61B787E0F16CF8D00C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B787F0F16CF8D00C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 924";
|
||||
rLen = 0;
|
||||
rLoc = 20884;
|
||||
rType = 0;
|
||||
vrLen = 1386;
|
||||
vrLoc = 18944;
|
||||
};
|
||||
B61B78800F16CF8D00C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
};
|
||||
B61B78830F16D04E00C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B78840F16D04E00C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 924";
|
||||
rLen = 0;
|
||||
rLoc = 20840;
|
||||
rType = 0;
|
||||
vrLen = 1346;
|
||||
vrLoc = 18944;
|
||||
};
|
||||
B61B78850F16D04E00C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
};
|
||||
B61B788A0F16D9F000C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B788B0F16D9F000C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 892";
|
||||
rLen = 0;
|
||||
rLoc = 19330;
|
||||
rType = 0;
|
||||
vrLen = 1100;
|
||||
vrLoc = 18397;
|
||||
};
|
||||
B61B788C0F16D9F000C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
};
|
||||
B61B78930F16DE1400C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B78940F16DE1400C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 1025";
|
||||
rLen = 0;
|
||||
rLoc = 22371;
|
||||
rType = 0;
|
||||
vrLen = 1338;
|
||||
vrLoc = 21056;
|
||||
};
|
||||
B61B78950F16DE1400C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
};
|
||||
B61B78970F16DE8200C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
};
|
||||
B61B78980F16DE8200C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 970";
|
||||
rLen = 0;
|
||||
rLoc = 20932;
|
||||
rType = 0;
|
||||
vrLen = 1333;
|
||||
vrLoc = 19977;
|
||||
};
|
||||
B61B78990F16DE8200C3E140 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 402";
|
||||
rLen = 68;
|
||||
rLoc = 9022;
|
||||
rType = 0;
|
||||
vrLen = 1853;
|
||||
vrLoc = 8353;
|
||||
vrLen = 330;
|
||||
vrLoc = 441;
|
||||
};
|
||||
B642F1290F132FA3001F7696 /* UniversalDiskImage.h */ = {
|
||||
uiCtxt = {
|
||||
@ -610,9 +391,9 @@
|
||||
};
|
||||
B642F12A0F132FA3001F7696 /* UniversalDiskImage.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1353, 796}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {883, 728}}";
|
||||
sepNavSelRange = "{820, 0}";
|
||||
sepNavVisRange = "{0, 964}";
|
||||
sepNavVisRange = "{500, 463}";
|
||||
sepNavWindowFrame = "{{668, 219}, {1412, 924}}";
|
||||
};
|
||||
};
|
||||
@ -636,16 +417,6 @@
|
||||
vrLen = 355;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B642F1550F133632001F7696 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 364";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rType = 0;
|
||||
vrLen = 325;
|
||||
vrLoc = 28;
|
||||
};
|
||||
B642F16A0F1341D4001F7696 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91580EFD77E3000E4348 /* common.h */;
|
||||
@ -668,10 +439,10 @@
|
||||
};
|
||||
B679E4A70F02E79300FB3F0C /* main.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1353, 14546}}";
|
||||
sepNavSelRange = "{20932, 0}";
|
||||
sepNavVisRange = "{19977, 1333}";
|
||||
sepNavWindowFrame = "{{263, 144}, {1412, 924}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1250, 3864}}";
|
||||
sepNavSelRange = "{284, 0}";
|
||||
sepNavVisRange = "{0, 950}";
|
||||
sepNavWindowFrame = "{{342, 156}, {1412, 924}}";
|
||||
};
|
||||
};
|
||||
B679E4B60F02EFA200FB3F0C /* PBXTextBookmark */ = {
|
||||
@ -694,7 +465,7 @@
|
||||
vrLen = 356;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6AE1CFF0F0335FC00D36ADB /* main.cpp:30 */ = {
|
||||
B6AE1CFF0F0335FC00D36ADB /* main.cpp:20 */ = {
|
||||
isa = PBXFileBreakpoint;
|
||||
actions = (
|
||||
);
|
||||
@ -706,7 +477,7 @@
|
||||
functionName = "prodos_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)";
|
||||
hitCount = 0;
|
||||
ignoreCount = 0;
|
||||
lineNumber = 30;
|
||||
lineNumber = 20;
|
||||
location = "ProDOS-Fuse";
|
||||
modificationTime = 251949619.113812;
|
||||
state = 2;
|
||||
@ -717,6 +488,11 @@
|
||||
name = fuse_common.h;
|
||||
path = /usr/local/include/fuse/fuse_common.h;
|
||||
sourceTree = "<absolute>";
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {883, 4032}}";
|
||||
sepNavSelRange = "{6850, 63}";
|
||||
sepNavVisRange = "{5837, 708}";
|
||||
};
|
||||
};
|
||||
B6B17F940F1136550060F7AA /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
@ -748,7 +524,7 @@
|
||||
};
|
||||
B6B17FA10F1138830060F7AA /* DiskCopy42.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {883, 588}}";
|
||||
sepNavIntBoundsRect = "{{0, 0}, {883, 616}}";
|
||||
sepNavSelRange = "{150, 0}";
|
||||
sepNavVisRange = "{0, 333}";
|
||||
sepNavWindowFrame = "{{299, 31}, {1412, 924}}";
|
||||
@ -804,15 +580,286 @@
|
||||
vrLen = 333;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6B7A87E0F144D05001024D2 /* PBXTextBookmark */ = {
|
||||
B6C786AA0F2A598F00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B60E91540EFB51FE000E4348 /* Disk.cpp */;
|
||||
name = "Disk.cpp: 328";
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 33";
|
||||
rLen = 0;
|
||||
rLoc = 7422;
|
||||
rLoc = 323;
|
||||
rType = 0;
|
||||
vrLen = 351;
|
||||
vrLoc = 31;
|
||||
vrLen = 330;
|
||||
vrLoc = 441;
|
||||
};
|
||||
B6C786B30F2A59AF00053681 /* profuse.h */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1250, 831}}";
|
||||
sepNavSelRange = "{185, 0}";
|
||||
sepNavVisRange = "{0, 1380}";
|
||||
};
|
||||
};
|
||||
B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {796, 5194}}";
|
||||
sepNavSelRange = "{2396, 68}";
|
||||
sepNavVisRange = "{0, 546}";
|
||||
};
|
||||
};
|
||||
B6C786BB0F2A5C0800053681 /* profuse_dirent.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1250, 1806}}";
|
||||
sepNavSelRange = "{193, 0}";
|
||||
sepNavVisRange = "{0, 1150}";
|
||||
};
|
||||
};
|
||||
B6C786BF0F2A5CC000053681 /* profuse_stat.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {1250, 3010}}";
|
||||
sepNavSelRange = "{181, 0}";
|
||||
sepNavVisRange = "{0, 1136}";
|
||||
};
|
||||
};
|
||||
B6C786C30F2A5DCE00053681 /* profuse_file.cpp */ = {
|
||||
uiCtxt = {
|
||||
sepNavIntBoundsRect = "{{0, 0}, {883, 1974}}";
|
||||
sepNavSelRange = "{132, 0}";
|
||||
sepNavVisRange = "{0, 365}";
|
||||
};
|
||||
};
|
||||
B6C786C90F2A5E8000053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
comments = "error: #error On FreeBSD API version 25 or greater must be used";
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
rLen = 1;
|
||||
rLoc = 265;
|
||||
rType = 1;
|
||||
};
|
||||
B6C786CA0F2A5E8000053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
name = "fuse_common.h: 266";
|
||||
rLen = 63;
|
||||
rLoc = 6850;
|
||||
rType = 0;
|
||||
vrLen = 1208;
|
||||
vrLoc = 6380;
|
||||
};
|
||||
B6C786DD0F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
name = "fuse_common.h: 266";
|
||||
rLen = 63;
|
||||
rLoc = 6850;
|
||||
rType = 0;
|
||||
vrLen = 1208;
|
||||
vrLoc = 6380;
|
||||
};
|
||||
B6C786DE0F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */;
|
||||
name = "profuse_xattr.cpp: 120";
|
||||
rLen = 68;
|
||||
rLoc = 2396;
|
||||
rType = 0;
|
||||
vrLen = 546;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786DF0F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786BB0F2A5C0800053681 /* profuse_dirent.cpp */;
|
||||
name = "profuse_dirent.cpp: 12";
|
||||
rLen = 0;
|
||||
rLoc = 135;
|
||||
rType = 0;
|
||||
vrLen = 610;
|
||||
vrLoc = 38;
|
||||
};
|
||||
B6C786E00F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
comments = "error: 'EISDIR' was not declared in this scope";
|
||||
fRef = B6C786C30F2A5DCE00053681 /* profuse_file.cpp */;
|
||||
rLen = 1;
|
||||
rLoc = 24;
|
||||
rType = 1;
|
||||
};
|
||||
B6C786E10F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
name = "fuse_common.h: 266";
|
||||
rLen = 63;
|
||||
rLoc = 6850;
|
||||
rType = 0;
|
||||
vrLen = 1208;
|
||||
vrLoc = 6380;
|
||||
};
|
||||
B6C786E20F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */;
|
||||
name = "profuse_xattr.cpp: 120";
|
||||
rLen = 68;
|
||||
rLoc = 2396;
|
||||
rType = 0;
|
||||
vrLen = 546;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786E30F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786BB0F2A5C0800053681 /* profuse_dirent.cpp */;
|
||||
name = "profuse_dirent.cpp: 12";
|
||||
rLen = 0;
|
||||
rLoc = 135;
|
||||
rType = 0;
|
||||
vrLen = 610;
|
||||
vrLoc = 38;
|
||||
};
|
||||
B6C786E40F2A5FED00053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786C30F2A5DCE00053681 /* profuse_file.cpp */;
|
||||
name = "profuse_file.cpp: 11";
|
||||
rLen = 0;
|
||||
rLoc = 132;
|
||||
rType = 0;
|
||||
vrLen = 607;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786E50F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 33";
|
||||
rLen = 0;
|
||||
rLoc = 323;
|
||||
rType = 0;
|
||||
vrLen = 330;
|
||||
vrLoc = 441;
|
||||
};
|
||||
B6C786E60F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786B30F2A59AF00053681 /* profuse.h */;
|
||||
name = "profuse.h: 15";
|
||||
rLen = 0;
|
||||
rLoc = 592;
|
||||
rType = 0;
|
||||
vrLen = 176;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786E70F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */;
|
||||
name = "profuse_xattr.cpp: 1";
|
||||
rLen = 0;
|
||||
rLoc = 0;
|
||||
rType = 0;
|
||||
vrLen = 360;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786E80F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 33";
|
||||
rLen = 0;
|
||||
rLoc = 323;
|
||||
rType = 0;
|
||||
vrLen = 330;
|
||||
vrLoc = 441;
|
||||
};
|
||||
B6C786E90F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786B30F2A59AF00053681 /* profuse.h */;
|
||||
name = "profuse.h: 15";
|
||||
rLen = 0;
|
||||
rLoc = 592;
|
||||
rType = 0;
|
||||
vrLen = 176;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786EA0F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */;
|
||||
name = "profuse_xattr.cpp: 1";
|
||||
rLen = 0;
|
||||
rLoc = 0;
|
||||
rType = 0;
|
||||
vrLen = 360;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786EB0F2A5FF300053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
name = "fuse_common.h: 266";
|
||||
rLen = 63;
|
||||
rLoc = 6850;
|
||||
rType = 0;
|
||||
vrLen = 789;
|
||||
vrLoc = 6545;
|
||||
};
|
||||
B6C786EE0F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
name = "fuse_common.h: 266";
|
||||
rLen = 63;
|
||||
rLoc = 6850;
|
||||
rType = 0;
|
||||
vrLen = 708;
|
||||
vrLoc = 5837;
|
||||
};
|
||||
B6C786EF0F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B642F12A0F132FA3001F7696 /* UniversalDiskImage.cpp */;
|
||||
name = "UniversalDiskImage.cpp: 42";
|
||||
rLen = 0;
|
||||
rLoc = 820;
|
||||
rType = 0;
|
||||
vrLen = 463;
|
||||
vrLoc = 500;
|
||||
};
|
||||
B6C786F00F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786C30F2A5DCE00053681 /* profuse_file.cpp */;
|
||||
name = "profuse_file.cpp: 11";
|
||||
rLen = 0;
|
||||
rLoc = 132;
|
||||
rType = 0;
|
||||
vrLen = 365;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786F10F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17F820F103AA70060F7AA /* fuse_common.h */;
|
||||
name = "fuse_common.h: 266";
|
||||
rLen = 63;
|
||||
rLoc = 6850;
|
||||
rType = 0;
|
||||
vrLen = 708;
|
||||
vrLoc = 5837;
|
||||
};
|
||||
B6C786F20F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B642F12A0F132FA3001F7696 /* UniversalDiskImage.cpp */;
|
||||
name = "UniversalDiskImage.cpp: 42";
|
||||
rLen = 0;
|
||||
rLoc = 820;
|
||||
rType = 0;
|
||||
vrLen = 463;
|
||||
vrLoc = 500;
|
||||
};
|
||||
B6C786F30F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6C786C30F2A5DCE00053681 /* profuse_file.cpp */;
|
||||
name = "profuse_file.cpp: 11";
|
||||
rLen = 0;
|
||||
rLoc = 132;
|
||||
rType = 0;
|
||||
vrLen = 365;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6C786F40F2A612600053681 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B6B17FA10F1138830060F7AA /* DiskCopy42.cpp */;
|
||||
name = "DiskCopy42.cpp: 11";
|
||||
rLen = 0;
|
||||
rLoc = 150;
|
||||
rType = 0;
|
||||
vrLen = 333;
|
||||
vrLoc = 0;
|
||||
};
|
||||
B6D81E5B0EFDE859000219B7 /* xmain.cpp:163 */ = {
|
||||
isa = PBXFileBreakpoint;
|
||||
@ -839,14 +886,4 @@
|
||||
sepNavWindowFrame = "{{15, 249}, {1412, 924}}";
|
||||
};
|
||||
};
|
||||
B6DBB4F10F0C6CD800F385F2 /* PBXTextBookmark */ = {
|
||||
isa = PBXTextBookmark;
|
||||
fRef = B679E4A70F02E79300FB3F0C /* main.cpp */;
|
||||
name = "main.cpp: 34";
|
||||
rLen = 0;
|
||||
rLoc = 480;
|
||||
rType = 0;
|
||||
vrLen = 315;
|
||||
vrLoc = 420;
|
||||
};
|
||||
}
|
||||
|
@ -12,6 +12,10 @@
|
||||
B642F12B0F132FA3001F7696 /* UniversalDiskImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B642F12A0F132FA3001F7696 /* UniversalDiskImage.cpp */; };
|
||||
B679E4A80F02E79300FB3F0C /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B679E4A70F02E79300FB3F0C /* main.cpp */; };
|
||||
B6B17FA20F1138830060F7AA /* DiskCopy42.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6B17FA10F1138830060F7AA /* DiskCopy42.cpp */; };
|
||||
B6C786B50F2A59FF00053681 /* profuse_xattr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */; };
|
||||
B6C786BC0F2A5C0800053681 /* profuse_dirent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6C786BB0F2A5C0800053681 /* profuse_dirent.cpp */; };
|
||||
B6C786C00F2A5CC000053681 /* profuse_stat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6C786BF0F2A5CC000053681 /* profuse_stat.cpp */; };
|
||||
B6C786C40F2A5DCE00053681 /* profuse_file.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B6C786C30F2A5DCE00053681 /* profuse_file.cpp */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
@ -38,6 +42,11 @@
|
||||
B679E4A70F02E79300FB3F0C /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
B6B17FA00F1138830060F7AA /* DiskCopy42.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiskCopy42.h; sourceTree = "<group>"; };
|
||||
B6B17FA10F1138830060F7AA /* DiskCopy42.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DiskCopy42.cpp; sourceTree = "<group>"; };
|
||||
B6C786B30F2A59AF00053681 /* profuse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = profuse.h; sourceTree = "<group>"; };
|
||||
B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = profuse_xattr.cpp; sourceTree = "<group>"; };
|
||||
B6C786BB0F2A5C0800053681 /* profuse_dirent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = profuse_dirent.cpp; sourceTree = "<group>"; };
|
||||
B6C786BF0F2A5CC000053681 /* profuse_stat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = profuse_stat.cpp; sourceTree = "<group>"; };
|
||||
B6C786C30F2A5DCE00053681 /* profuse_file.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = profuse_file.cpp; sourceTree = "<group>"; };
|
||||
B6DBB4E70F0C6BBD00F385F2 /* profuse.1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.man; path = profuse.1; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -76,6 +85,11 @@
|
||||
B679E4A70F02E79300FB3F0C /* main.cpp */,
|
||||
B6B17FA00F1138830060F7AA /* DiskCopy42.h */,
|
||||
B6B17FA10F1138830060F7AA /* DiskCopy42.cpp */,
|
||||
B6C786B30F2A59AF00053681 /* profuse.h */,
|
||||
B6C786BB0F2A5C0800053681 /* profuse_dirent.cpp */,
|
||||
B6C786C30F2A5DCE00053681 /* profuse_file.cpp */,
|
||||
B6C786BF0F2A5CC000053681 /* profuse_stat.cpp */,
|
||||
B6C786B40F2A59FE00053681 /* profuse_xattr.cpp */,
|
||||
);
|
||||
name = Source;
|
||||
sourceTree = "<group>";
|
||||
@ -151,6 +165,10 @@
|
||||
B679E4A80F02E79300FB3F0C /* main.cpp in Sources */,
|
||||
B6B17FA20F1138830060F7AA /* DiskCopy42.cpp in Sources */,
|
||||
B642F12B0F132FA3001F7696 /* UniversalDiskImage.cpp in Sources */,
|
||||
B6C786B50F2A59FF00053681 /* profuse_xattr.cpp in Sources */,
|
||||
B6C786BC0F2A5C0800053681 /* profuse_dirent.cpp in Sources */,
|
||||
B6C786C00F2A5CC000053681 /* profuse_stat.cpp in Sources */,
|
||||
B6C786C40F2A5DCE00053681 /* profuse_file.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
127
profuse_dirent.cpp
Normal file
127
profuse_dirent.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* profuse_dirent.cpp
|
||||
* profuse
|
||||
*
|
||||
* Created by Kelvin Sherlock on 1/23/2009.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "profuse.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
#pragma mark Directory Functions
|
||||
|
||||
/*
|
||||
* when the directory is opened, we load the volume/directory and store the FileEntry vector into
|
||||
* fi->fh.
|
||||
*
|
||||
*/
|
||||
void prodos_opendir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "opendir: %u\n", ino);
|
||||
// verify it's a directory/volume here?
|
||||
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
vector<FileEntry> files;
|
||||
bool ok;
|
||||
|
||||
|
||||
ok = disk->Read(ino == 1 ? 2 : ino >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
if (ino == 1)
|
||||
{
|
||||
VolumeEntry v(buffer + 0x04);
|
||||
|
||||
ok = disk->ReadVolume(&v, &files);
|
||||
|
||||
ERROR(ok < 0, EIO)
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
|
||||
ERROR(e.storage_type != DIRECTORY_FILE, ENOTDIR)
|
||||
|
||||
ok = disk->ReadDirectory(e.key_pointer, NULL, &files);
|
||||
|
||||
ERROR(ok < 0, EIO);
|
||||
}
|
||||
|
||||
// copy the vector contents to a vector *.
|
||||
vector<FileEntry> *fp = new vector<FileEntry>();
|
||||
files.swap(*fp);
|
||||
|
||||
fi->fh = (uint64_t)fp;
|
||||
fuse_reply_open(req, fi);
|
||||
}
|
||||
|
||||
void prodos_releasedir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr,"releasedir: %d\n", ino);
|
||||
vector<FileEntry> *files = (vector<FileEntry> *)fi->fh;
|
||||
|
||||
if (files) delete files;
|
||||
|
||||
fuse_reply_err(req, 0);
|
||||
}
|
||||
|
||||
void prodos_readdir(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi)
|
||||
{
|
||||
vector<FileEntry> *files = (vector<FileEntry> *)fi->fh;
|
||||
struct stat st;
|
||||
|
||||
fprintf(stderr, "readdir %u %u %u\n", ino, size, off);
|
||||
|
||||
// TODO -- add "." and ".." entries...
|
||||
|
||||
|
||||
// if the offset >= number of entries, get out.
|
||||
if (!files || files->size() <= off)
|
||||
{
|
||||
fprintf(stderr, "fuse_reply_buf(req, NULL, 0)\n");
|
||||
fuse_reply_buf(req, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// now some dirent info...
|
||||
|
||||
bzero(&st, sizeof(st));
|
||||
// only mode and ino are used.
|
||||
|
||||
char *buffer = new char[size];
|
||||
|
||||
unsigned count = files->size();
|
||||
unsigned current_size = 0;
|
||||
for (unsigned i = off; i < count; ++i)
|
||||
{
|
||||
FileEntry &f = (*files)[i];
|
||||
|
||||
st.st_mode = f.storage_type == DIRECTORY_FILE ? S_IFDIR | 0555 : S_IFREG | 0444;
|
||||
st.st_ino = f.address;
|
||||
|
||||
unsigned entry_size = fuse_add_direntry(req, NULL, 0, f.file_name, NULL, 0);
|
||||
if (entry_size + current_size >= size) break;
|
||||
|
||||
|
||||
fuse_add_direntry(req, (char *)buffer + current_size, size, f.file_name, &st, i + 1);
|
||||
current_size += entry_size;
|
||||
|
||||
}
|
||||
|
||||
fuse_reply_buf(req, buffer, current_size);
|
||||
delete []buffer;
|
||||
}
|
||||
|
134
profuse_file.cpp
Normal file
134
profuse_file.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* profuse_file.cpp
|
||||
* profuse
|
||||
*
|
||||
* Created by Kelvin Sherlock on 1/23/2009.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "profuse.h"
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#pragma mark Read Functions
|
||||
|
||||
void prodos_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "open: %u\n", ino);
|
||||
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
int ok;
|
||||
|
||||
FileEntry *e = NULL;
|
||||
|
||||
ERROR(ino == 1, EISDIR)
|
||||
|
||||
ok = disk->Read(ino >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
e = new FileEntry(buffer + (ino & 0x1ff));
|
||||
|
||||
if (e->storage_type == EXTENDED_FILE)
|
||||
{
|
||||
ok = disk->Normalize(*e, 0);
|
||||
|
||||
if (ok < 0)
|
||||
{
|
||||
delete e;
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
}
|
||||
|
||||
// EXTENDED_FILE already handled (it would be an error here.)
|
||||
switch(e->storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
break;
|
||||
//case PASCAL_FILE: //?
|
||||
case DIRECTORY_FILE:
|
||||
delete e;
|
||||
ERROR(true, EISDIR)
|
||||
break;
|
||||
default:
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
|
||||
if ( (fi->flags & O_ACCMODE) != O_RDONLY)
|
||||
{
|
||||
delete e;
|
||||
ERROR(true, EACCES);
|
||||
}
|
||||
fi->fh = (uint64_t)e;
|
||||
|
||||
fuse_reply_open(req, fi);
|
||||
}
|
||||
|
||||
void prodos_release(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "release: %d\n", ino);
|
||||
|
||||
FileEntry *e = (FileEntry *)fi->fh;
|
||||
|
||||
if (e) delete e;
|
||||
|
||||
fuse_reply_err(req, 0);
|
||||
|
||||
}
|
||||
|
||||
void prodos_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi)
|
||||
{
|
||||
fprintf(stderr, "read: %u %u %u\n", ino, size, off);
|
||||
|
||||
FileEntry *e = (FileEntry *)fi->fh;
|
||||
|
||||
ERROR(e == NULL, EIO)
|
||||
|
||||
if (off >= e->eof)
|
||||
{
|
||||
fuse_reply_buf(req, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned level = 0;
|
||||
switch(e->storage_type)
|
||||
{
|
||||
case TREE_FILE:
|
||||
level = 2;
|
||||
break;
|
||||
case SAPLING_FILE:
|
||||
level = 1;
|
||||
break;
|
||||
case SEEDLING_FILE:
|
||||
level = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// currently, reading is done on a block basis.
|
||||
// experimentally, fuse reads the entire file
|
||||
// this may not hold for larger files.
|
||||
|
||||
|
||||
// TODO -- error if size + off > eof.
|
||||
|
||||
unsigned blocks = (size + (off & 0x1ff) + BLOCK_SIZE - 1) >> 9;
|
||||
int ok;
|
||||
uint8_t *buffer = new uint8_t[blocks << 9];
|
||||
|
||||
fprintf(stderr, "ReadIndex(%x, buffer, %x, %x, %x)\n", e->key_pointer, level, (int)off, (int)blocks);
|
||||
|
||||
ok = disk->ReadIndex(e->key_pointer, buffer, level, off, blocks);
|
||||
if (ok < 0)
|
||||
{
|
||||
fuse_reply_err(req, EIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
fuse_reply_buf(req, (const char *)buffer + (off & 0x1ff), size);
|
||||
}
|
||||
|
||||
delete []buffer;
|
||||
}
|
214
profuse_stat.cpp
Normal file
214
profuse_stat.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* prodos_stat.cpp
|
||||
* profuse
|
||||
*
|
||||
* Created by Kelvin Sherlock on 1/23/2009.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#pragma mark Stat Functions
|
||||
|
||||
#include "profuse.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
using std::vector;
|
||||
|
||||
int prodos_stat(FileEntry& e, struct stat *st)
|
||||
{
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
int ok;
|
||||
|
||||
|
||||
if (e.storage_type == EXTENDED_FILE)
|
||||
{
|
||||
ok = disk->Normalize(e, 0);
|
||||
if (ok < 0) return ok;
|
||||
}
|
||||
|
||||
st->st_blksize = BLOCK_SIZE;
|
||||
|
||||
st->st_ctime = e.creation;
|
||||
#ifdef HAVE_STAT_BIRTHTIME
|
||||
st->st_birthtime = e.creation;
|
||||
#endif
|
||||
|
||||
st->st_mtime = e.last_mod;
|
||||
st->st_atime = e.last_mod;
|
||||
|
||||
|
||||
st->st_nlink = 1;
|
||||
st->st_mode = 0444 | S_IFREG;
|
||||
st->st_size = e.eof;
|
||||
|
||||
|
||||
if (e.storage_type == DIRECTORY_FILE)
|
||||
{
|
||||
ok = disk->Read(e.key_pointer, buffer);
|
||||
if (ok < 0) return -1;
|
||||
|
||||
SubdirEntry se(buffer + 0x04);
|
||||
|
||||
if (se.storage_type != SUBDIR_HEADER) return -1;
|
||||
|
||||
st->st_mode = S_IFDIR | 0555;
|
||||
st->st_size = BLOCK_SIZE;
|
||||
st->st_nlink = se.file_count + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
//case PASCAL_FILE:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prodos_stat(const VolumeEntry &v, struct stat *st)
|
||||
{
|
||||
|
||||
if (v.storage_type != VOLUME_HEADER) return -1;
|
||||
|
||||
st->st_mode = S_IFDIR | 0555;
|
||||
st->st_ctime = v.creation;
|
||||
|
||||
#ifdef HAVE_STAT_BIRTHTIME
|
||||
st->st_birthtime = v.creation;
|
||||
#endif
|
||||
st->st_mtime = v.creation;
|
||||
st->st_atime = v.creation;
|
||||
|
||||
st->st_nlink = v.file_count + 1;
|
||||
st->st_size = BLOCK_SIZE;
|
||||
st->st_blksize = BLOCK_SIZE;
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void prodos_getattr(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
||||
{
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
struct stat st;
|
||||
int ok;
|
||||
|
||||
fprintf(stderr, "get_attr %u\n", ino);
|
||||
|
||||
bzero(&st, sizeof(st));
|
||||
|
||||
/*
|
||||
* ino 1 is the volume header. Others are pointers.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
ok = disk->Read(ino == 1 ? 2 : ino >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
// ino 1 is the volume header.
|
||||
if (ino == 1)
|
||||
{
|
||||
VolumeEntry v(buffer + 0x04);
|
||||
ok = prodos_stat(v, &st);
|
||||
ERROR(ok < 0, EIO);
|
||||
|
||||
st.st_ino = ino;
|
||||
|
||||
fuse_reply_attr(req, &st, 0.0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
ok = prodos_stat(e, &st);
|
||||
|
||||
ERROR(ok < 0, EIO);
|
||||
|
||||
st.st_ino = ino;
|
||||
|
||||
fuse_reply_attr(req, &st, 0.0); //
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO -- add Disk::Lookup support so we don't have to parse the entire dir header.
|
||||
// TODO -- add caching.
|
||||
void prodos_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
|
||||
{
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
struct fuse_entry_param entry;
|
||||
int ok;
|
||||
vector<FileEntry> files;
|
||||
|
||||
|
||||
fprintf(stderr, "lookup: %d %s\n", parent, name);
|
||||
|
||||
ERROR(!validProdosName(name), ENOENT)
|
||||
|
||||
ok = disk->Read(parent == 1 ? 2 : parent >> 9, buffer);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
bzero(&entry, sizeof(entry));
|
||||
|
||||
entry.attr_timeout = 0.0;
|
||||
entry.entry_timeout = 0.0;
|
||||
|
||||
// get the file list
|
||||
// TODO -- Disk::look-up-one-file
|
||||
if (parent == 1)
|
||||
{
|
||||
VolumeEntry v;
|
||||
ok = disk->ReadVolume(&v, &files);
|
||||
ERROR(ok < 0, EIO)
|
||||
}
|
||||
else
|
||||
{
|
||||
FileEntry e(buffer + (parent & 0x1ff));
|
||||
ERROR(e.storage_type != DIRECTORY_FILE, ENOENT);
|
||||
|
||||
ok = disk->ReadDirectory(e.key_pointer, NULL, &files);
|
||||
ERROR(ok < 0, EIO)
|
||||
}
|
||||
// ok, now go through the file list and look for a (case insensitive) match.
|
||||
|
||||
|
||||
ok = -1;
|
||||
unsigned name_length = strlen(name);
|
||||
|
||||
for(vector<FileEntry>::iterator iter = files.begin(); iter != files.end(); ++iter)
|
||||
{
|
||||
FileEntry& f = *iter;
|
||||
if ( (f.name_length == name_length) && (strcasecmp(name, f.file_name) == 0))
|
||||
{
|
||||
ok = prodos_stat(f, &entry.attr);
|
||||
fprintf(stderr, "stat %s %x (%x %x) %d\n", f.file_name, f.address, f.address >> 9, f.address & 0x1ff, ok);
|
||||
entry.ino = f.address;
|
||||
entry.attr.st_ino = f.address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ERROR(ok < 0, ENOENT);
|
||||
|
||||
fprintf(stderr, "file found!\n");
|
||||
|
||||
fuse_reply_entry(req, &entry);
|
||||
}
|
||||
|
365
profuse_xattr.cpp
Normal file
365
profuse_xattr.cpp
Normal file
@ -0,0 +1,365 @@
|
||||
/*
|
||||
* profuse_xattr.cpp
|
||||
* profuse
|
||||
*
|
||||
* Created by Kelvin Sherlock on 1/23/2009.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "profuse.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <errno.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
#pragma mark XAttribute Functions
|
||||
|
||||
|
||||
static void xattr_filetype(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
uint8_t attr = e.file_type;
|
||||
unsigned attr_size = 1;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
// consider position here?
|
||||
fuse_reply_buf(req, (char *)&attr, attr_size);
|
||||
}
|
||||
|
||||
|
||||
static void xattr_auxtype(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
uint8_t attr[2];
|
||||
unsigned attr_size = 2;
|
||||
|
||||
attr[0] = e.aux_type & 0xff;
|
||||
attr[1] = (e.aux_type >> 8) & 0xff;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
// consider position here?
|
||||
fuse_reply_buf(req, (char *)&attr, attr_size);
|
||||
}
|
||||
|
||||
static void xattr_textencoding(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
// TODO -- ascii text encoding for ascii files?
|
||||
const char attr[] = "MACINTOSH;0";
|
||||
unsigned attr_size = sizeof(attr) - 1;
|
||||
|
||||
// currently only valid for Teach Files, "ASCII" Text
|
||||
|
||||
if (e.file_type == 0x04 || (e.file_type == 0x50 && e.aux_type == 0x5445))
|
||||
/* do nothing */ ;
|
||||
else
|
||||
{
|
||||
ERROR(true, ENOENT)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
// consider position here?
|
||||
fuse_reply_buf(req, (char *)&attr, attr_size);
|
||||
}
|
||||
|
||||
static void xattr_rfork(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
int ok;
|
||||
unsigned level;
|
||||
|
||||
ERROR (e.storage_type != EXTENDED_FILE, ENOENT)
|
||||
|
||||
ok = disk->Normalize(e, 1);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
level = 0;
|
||||
break;
|
||||
case SAPLING_FILE:
|
||||
level = 1;
|
||||
break;
|
||||
case TREE_FILE:
|
||||
level = 2;
|
||||
break;
|
||||
default:
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, e.eof);
|
||||
return;
|
||||
}
|
||||
|
||||
size = std::min((uint32_t)(size + off), e.eof);
|
||||
|
||||
unsigned blocks = (size + (off & 0x1ff) + BLOCK_SIZE - 1) >> 9;
|
||||
uint8_t *buffer = new uint8_t[blocks << 9];
|
||||
|
||||
fprintf(stderr, "ReadIndex(%x, buffer, %x, %x, %x)\n", e.key_pointer, level, (int)off, (int)blocks);
|
||||
|
||||
ok = disk->ReadIndex(e.key_pointer, buffer, level, off, blocks);
|
||||
|
||||
if (ok < 0)
|
||||
{
|
||||
fuse_reply_err(req, EIO);
|
||||
}
|
||||
else
|
||||
{
|
||||
fuse_reply_buf(req, (char *)buffer + (off & 0x1ff), size);
|
||||
}
|
||||
delete []buffer;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Finder info.
|
||||
static void xattr_finfo(FileEntry& e, fuse_req_t req, size_t size, off_t off)
|
||||
{
|
||||
int ok;
|
||||
ExtendedEntry ee;
|
||||
|
||||
uint8_t attr[32];
|
||||
unsigned attr_size = 32;
|
||||
|
||||
ERROR (e.storage_type != EXTENDED_FILE, ENOENT)
|
||||
|
||||
ok = disk->Normalize(e, 1, &ee);
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
// sanity check
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
break;
|
||||
default:
|
||||
ERROR(true, EIO)
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
ERROR (size < attr_size, ERANGE)
|
||||
|
||||
memcpy(attr, ee.FInfo, 16);
|
||||
memcpy(attr + 16, ee.xFInfo, 16);
|
||||
|
||||
fuse_reply_buf(req, (char *)attr, attr_size);
|
||||
}
|
||||
|
||||
|
||||
static bool isTextFile(unsigned ftype, unsigned auxtype)
|
||||
{
|
||||
if (ftype == 0x04) return true; // ascii text
|
||||
if (ftype == 0x50 && auxtype == 0x5445) return true; // teach text
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void prodos_listxattr(fuse_req_t req, fuse_ino_t ino, size_t size)
|
||||
{
|
||||
// list of supported attributes.
|
||||
//
|
||||
#define NO_ATTR() \
|
||||
{ \
|
||||
if (size) fuse_reply_buf(req, NULL, 0); \
|
||||
else fuse_reply_xattr(req, 0); \
|
||||
return; \
|
||||
}
|
||||
|
||||
fprintf(stderr, "listxattr %u\n", ino);
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
int ok;
|
||||
unsigned attr_size;
|
||||
string attr;
|
||||
|
||||
|
||||
|
||||
if(ino == 1)
|
||||
NO_ATTR()
|
||||
|
||||
ok = disk->Read(ino >> 9, buffer);
|
||||
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
|
||||
|
||||
attr += "prodos.FileType";
|
||||
attr.append(1, 0);
|
||||
|
||||
attr += "prodos.AuxType";
|
||||
attr.append(1, 0);
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case EXTENDED_FILE:
|
||||
{
|
||||
// TODO -- pretend there's no resource fork if resource fork eof == 0 ?
|
||||
//
|
||||
//ok = disk->Normalize(e, 1);
|
||||
//ERROR(ok < 0, EIO)
|
||||
|
||||
attr += "prodos.ResourceFork";
|
||||
attr.append(1, 0);
|
||||
|
||||
attr += "com.apple.FinderInfo";
|
||||
attr.append(1, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
break;
|
||||
|
||||
case DIRECTORY_FILE:
|
||||
NO_ATTR()
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
NO_ATTR()
|
||||
break;
|
||||
}
|
||||
|
||||
if (isTextFile(e.file_type, e.aux_type))
|
||||
{
|
||||
attr += "com.apple.TextEncoding";
|
||||
attr.append(1, 0);
|
||||
}
|
||||
|
||||
attr_size = attr.length();
|
||||
|
||||
fprintf(stderr, "%d %s\n", attr_size, attr.c_str());
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
fuse_reply_xattr(req, attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < attr_size)
|
||||
{
|
||||
fuse_reply_err(req, ERANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
fuse_reply_buf(req, attr.data(), attr_size);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* offset is only valid in OS X for the resource fork.
|
||||
*
|
||||
*/
|
||||
void prodos_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size, uint32_t off)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
#define NO_ATTRIBUTE ENOENT
|
||||
#else
|
||||
#define NO_ATTRIBUTE EOPNOTSUPP
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "getxattr: %u %s %u %u \n", ino, name, (int)size, (int)off);
|
||||
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
|
||||
|
||||
ERROR(ino == 1, NO_ATTRIBUTE) // finder can't handle EISDIR.
|
||||
|
||||
|
||||
int ok = disk->Read(ino >> 9, buffer);
|
||||
|
||||
ERROR(ok < 0, EIO)
|
||||
|
||||
|
||||
FileEntry e(buffer + (ino & 0x1ff));
|
||||
|
||||
switch(e.storage_type)
|
||||
{
|
||||
case SEEDLING_FILE:
|
||||
case SAPLING_FILE:
|
||||
case TREE_FILE:
|
||||
case EXTENDED_FILE:
|
||||
break;
|
||||
case DIRECTORY_FILE:
|
||||
ERROR(true, NO_ATTRIBUTE) // Finder can't handle EISDIR.
|
||||
default:
|
||||
ERROR(true, NO_ATTRIBUTE);
|
||||
}
|
||||
|
||||
if (strcmp("prodos.FileType", name) == 0)
|
||||
{
|
||||
xattr_filetype(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp("prodos.AuxType", name) == 0)
|
||||
{
|
||||
xattr_auxtype(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp("com.apple.TextEncoding", name) == 0)
|
||||
{
|
||||
xattr_textencoding(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (e.storage_type == EXTENDED_FILE) && (strcmp("prodos.ResourceFork", name) == 0))
|
||||
{
|
||||
xattr_rfork(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (e.storage_type == EXTENDED_FILE) && (strcmp("com.apple.FinderInfo", name) == 0))
|
||||
{
|
||||
xattr_finfo(e, req, size, off);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fuse_reply_err(req, NO_ATTRIBUTE);
|
||||
|
||||
}
|
||||
/*
|
||||
* Linux, et alia do not have an offset parameter.
|
||||
*/
|
||||
void prodos_getxattr(fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
|
||||
{
|
||||
prodos_getxattr(req, ino, name, size, 0);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user