mirror of
https://github.com/zydeco/libmfs.git
synced 2024-12-28 07:29:55 +00:00
libmfs 1.0.2
This commit is contained in:
parent
7bee43c9d6
commit
567eb930ae
2
Makefile
2
Makefile
@ -3,7 +3,7 @@ LIB = libmfs.a
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
AR = ar
|
AR = ar
|
||||||
RANLIB = ranlib
|
RANLIB = ranlib
|
||||||
CFLAGS = -Wno-multichar -fPIC -std=c99 -I.. -DUSE_LIBRES
|
CFLAGS = -arch i386 -arch ppc -arch x86_64 -fPIC -std=c99 -I.. -DUSE_LIBRES
|
||||||
|
|
||||||
all: $(LIB)
|
all: $(LIB)
|
||||||
|
|
||||||
|
4
fobj.h
4
fobj.h
@ -1,12 +1,12 @@
|
|||||||
// reverse engineered FOBJ resource
|
// reverse engineered FOBJ resource
|
||||||
// values are big endian
|
|
||||||
struct __attribute__ ((__packed__)) FOBJrsrc {
|
struct __attribute__ ((__packed__)) FOBJrsrc {
|
||||||
int16_t fdType; // 8 = folder, 4 = disk
|
int16_t fdType; // 8 = folder, 4 = disk
|
||||||
struct {
|
struct {
|
||||||
int16_t v,h;
|
int16_t v,h;
|
||||||
} fdIconPos; // icon position in window
|
} fdIconPos; // icon position in window
|
||||||
char _rsv1[6]; // unknown
|
char _rsv1[6]; // unknown
|
||||||
int16_t parent; // parent folder, kMFSFolder* or ID
|
int16_t parent; // parent folder, kMFSFolder*
|
||||||
char _rsv2[12]; // unknown
|
char _rsv2[12]; // unknown
|
||||||
uint32_t fdCrDat; // creation date (mac)
|
uint32_t fdCrDat; // creation date (mac)
|
||||||
uint32_t fdMdDat; // modification date (mac)
|
uint32_t fdMdDat; // modification date (mac)
|
||||||
|
137
mfs.c
137
mfs.c
@ -21,7 +21,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#define __USE_BSD // linux strdup
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -31,7 +30,7 @@
|
|||||||
#include "fobj.h"
|
#include "fobj.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char * libmfs_id = "libmfs 1.0.1 (C)2008-2009 namedfork.net";
|
const char * libmfs_id = "libmfs 1.0.2 (C)2008-2010 namedfork.net";
|
||||||
|
|
||||||
// printable flags
|
// printable flags
|
||||||
#define BINFLG8(x) ((x)&0x80?'1':'0'),((x)&0x40?'1':'0'),((x)&0x20?'1':'0'),((x)&0x10?'1':'0'),((x)&0x08?'1':'0'),((x)&0x04?'1':'0'),((x)&0x02?'1':'0'),((x)&0x01?'1':'0')
|
#define BINFLG8(x) ((x)&0x80?'1':'0'),((x)&0x40?'1':'0'),((x)&0x20?'1':'0'),((x)&0x10?'1':'0'),((x)&0x08?'1':'0'),((x)&0x04?'1':'0'),((x)&0x02?'1':'0'),((x)&0x01?'1':'0')
|
||||||
@ -158,50 +157,50 @@ struct timespec mfs_timespec (uint32_t mfsDate) {
|
|||||||
#if defined(LIBMFS_VERBOSE)
|
#if defined(LIBMFS_VERBOSE)
|
||||||
int mfs_printmdb (MFSMasterDirectoryBlock *mdb) {
|
int mfs_printmdb (MFSMasterDirectoryBlock *mdb) {
|
||||||
time_t t;
|
time_t t;
|
||||||
printf("MASTER DIRECTORY BLOCK:\n");
|
fprintf(stderr, "MASTER DIRECTORY BLOCK:\n");
|
||||||
printf(" signature: $%04X\n", mdb->drSigWord);
|
fprintf(stderr, " signature: $%04X\n", mdb->drSigWord);
|
||||||
t = mfs_time(mdb->drCrDate);
|
t = mfs_time(mdb->drCrDate);
|
||||||
printf(" creation: %s", asctime(localtime(&t)));
|
fprintf(stderr, " creation: %s", asctime(localtime(&t)));
|
||||||
t = mfs_time(mdb->drLsBkUp);
|
t = mfs_time(mdb->drLsBkUp);
|
||||||
printf(" backup: %s", asctime(localtime(&t)));
|
fprintf(stderr, " backup: %s", asctime(localtime(&t)));
|
||||||
printf(" attributes: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", BINFLG16(mdb->drAtrb));
|
fprintf(stderr, " attributes: %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n", BINFLG16(mdb->drAtrb));
|
||||||
printf(" files: %d\n", mdb->drNmFls);
|
fprintf(stderr, " files: %d\n", mdb->drNmFls);
|
||||||
printf(" dir.start: %d\n", mdb->drDirSt);
|
fprintf(stderr, " dir.start: %d\n", mdb->drDirSt);
|
||||||
printf(" dir.len: %d\n", mdb->drBlLen);
|
fprintf(stderr, " dir.len: %d\n", mdb->drBlLen);
|
||||||
printf(" al.bks: %d\n", mdb->drNmAlBlks);
|
fprintf(stderr, " al.bks: %d\n", mdb->drNmAlBlks);
|
||||||
printf(" al.bksz: %d\n", mdb->drAlBlkSiz);
|
fprintf(stderr, " al.bksz: %d\n", mdb->drAlBlkSiz);
|
||||||
printf(" al.bytes: %d\n", mdb->drClpSiz);
|
fprintf(stderr, " al.bytes: %d\n", mdb->drClpSiz);
|
||||||
printf(" al.first: %d\n", mdb->drAlBlSt);
|
fprintf(stderr, " al.first: %d\n", mdb->drAlBlSt);
|
||||||
printf(" fn.next: %d\n", mdb->drNxtFNum);
|
fprintf(stderr, " fn.next: %d\n", mdb->drNxtFNum);
|
||||||
printf(" free: %d\n", mdb->drFreeBks);
|
fprintf(stderr, " free: %d\n", mdb->drFreeBks);
|
||||||
char volName[28];
|
char volName[28];
|
||||||
strncpy(volName, (char*)&mdb->drVN[1], mdb->drVN[0]);
|
strncpy(volName, (char*)&mdb->drVN[1], mdb->drVN[0]);
|
||||||
printf(" name: %s\n", volName);
|
fprintf(stderr, " name: %s\n", volName);
|
||||||
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfs_printrecord (MFSDirectoryRecord *rec) {
|
int mfs_printrecord (MFSDirectoryRecord *rec) {
|
||||||
printf("DIRECTORY RECORD:\n");
|
fprintf(stderr, "DIRECTORY RECORD:\n");
|
||||||
printf(" name: %s\n", rec->flCName);
|
fprintf(stderr, " name: %s\n", rec->flCName);
|
||||||
printf(" flags: %c%c%c%c%c%c%c%c\n", BINFLG8(rec->flFlags));
|
fprintf(stderr, " flags: %c%c%c%c%c%c%c%c\n", BINFLG8(rec->flFlags));
|
||||||
printf(" version: %d\n", rec->flTyp);
|
fprintf(stderr, " version: %d\n", rec->flTyp);
|
||||||
printf(" inode: %d\n", rec->flFlNum);
|
fprintf(stderr, " inode: %d\n", rec->flFlNum);
|
||||||
printf(" data.blk: %d\n", rec->flStBlk);
|
fprintf(stderr, " data.blk: %d\n", rec->flStBlk);
|
||||||
printf(" data.lgl: %d\n", rec->flLgLen);
|
fprintf(stderr, " data.lgl: %d\n", rec->flLgLen);
|
||||||
printf(" data.pyl: %d\n", rec->flPyLen);
|
fprintf(stderr, " data.pyl: %d\n", rec->flPyLen);
|
||||||
printf(" rsrc.blk: %d\n", rec->flRStBlk);
|
fprintf(stderr, " rsrc.blk: %d\n", rec->flRStBlk);
|
||||||
printf(" rsrc.lgl: %d\n", rec->flRLgLen);
|
fprintf(stderr, " rsrc.lgl: %d\n", rec->flRLgLen);
|
||||||
printf(" rsrc.pyl: %d\n", rec->flRPyLen);
|
fprintf(stderr, " rsrc.pyl: %d\n", rec->flRPyLen);
|
||||||
time_t t = mfs_time(rec->flCrDat);
|
time_t t = mfs_time(rec->flCrDat);
|
||||||
printf(" created: %s", asctime(localtime(&t)));
|
fprintf(stderr, " created: %s", asctime(localtime(&t)));
|
||||||
t = mfs_time(rec->flMdDat);
|
t = mfs_time(rec->flMdDat);
|
||||||
printf(" modified: %s", asctime(localtime(&t)));
|
fprintf(stderr, " modified: %s", asctime(localtime(&t)));
|
||||||
// user words
|
// user words
|
||||||
printf(" folder: %d\n", ntohs(rec->flUsrWds.folder));
|
fprintf(stderr, " folder: %d\n", ntohs(rec->flUsrWds.folder));
|
||||||
uint16_t fflags = ntohs(rec->flUsrWds.flags);
|
uint16_t fflags = ntohs(rec->flUsrWds.flags);
|
||||||
printf(" fflags: %04X\n%s%s%s%s%s%s%s%s%s", fflags,
|
fprintf(stderr, " fflags: %04X\n%s%s%s%s%s%s%s%s%s", fflags,
|
||||||
((fflags & kIsOnDesk)? " on desktop\n":""),
|
((fflags & kIsOnDesk)? " on desktop\n":""),
|
||||||
((fflags & kSwitchLaunch)? " switch launch\n":""),
|
((fflags & kRequireSwitchLaunch)?" switch launch\n":""),
|
||||||
((fflags & kIsShared)? " shared\n":""),
|
((fflags & kIsShared)? " shared\n":""),
|
||||||
((fflags & kHasNoINITs)? " no INITs\n":""),
|
((fflags & kHasNoINITs)? " no INITs\n":""),
|
||||||
((fflags & kHasBeenInited)? " inited\n":""),
|
((fflags & kHasBeenInited)? " inited\n":""),
|
||||||
@ -210,6 +209,7 @@ int mfs_printrecord (MFSDirectoryRecord *rec) {
|
|||||||
((fflags & kHasBundle)? " bundle\n":""),
|
((fflags & kHasBundle)? " bundle\n":""),
|
||||||
((fflags & kIsInvisible)? " invisible\n":"")
|
((fflags & kIsInvisible)? " invisible\n":"")
|
||||||
);
|
);
|
||||||
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -395,42 +395,16 @@ MFSFork* mfs_fkopen (MFSVolume *vol, MFSDirectoryRecord *rec, int mode, int writ
|
|||||||
// header
|
// header
|
||||||
as->magic = htonl(kAppleDoubleMagic);
|
as->magic = htonl(kAppleDoubleMagic);
|
||||||
as->version = htonl(kAppleDoubleVersion);
|
as->version = htonl(kAppleDoubleVersion);
|
||||||
memcpy(&as->filesystem, "Macintosh ", 16);
|
memcpy(&as->filesystem, "Mac OS X ", 16);
|
||||||
int e = 0;
|
int e = 0;
|
||||||
|
|
||||||
// resource fork
|
|
||||||
if (fk->fkLgLen) {
|
|
||||||
as->entry[e].type = htonl(kAppleDoubleResourceForkEntry);
|
|
||||||
as->entry[e].offset = htonl(kAppleDoubleResourceForkOffset);
|
|
||||||
as->entry[e].length = htonl((uint32_t)fk->fkLgLen);
|
|
||||||
e++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// real name
|
|
||||||
as->entry[e].type = htonl(kAppleDoubleRealNameEntry);
|
|
||||||
as->entry[e].offset = htonl(kAppleDoubleRealNameOffset);
|
|
||||||
as->entry[e].length = htonl((uint32_t)(rec->flNam[0]));
|
|
||||||
strcpy((void*)as+kAppleDoubleRealNameOffset, rec->flCName);
|
|
||||||
e++;
|
|
||||||
|
|
||||||
// file info
|
|
||||||
as->entry[e].type = htonl(kAppleDoubleFileInfoEntry);
|
|
||||||
as->entry[e].offset = htonl(kAppleDoubleFileInfoOffset);
|
|
||||||
as->entry[e].length = htonl(kAppleDoubleFileInfoLength);
|
|
||||||
AppleDoubleMacFileInfo *mfi = (void*)as+kAppleDoubleFileInfoOffset;
|
|
||||||
mfi->creationDate = htonl(rec->flCrDat);
|
|
||||||
mfi->modificationDate = htonl(rec->flMdDat);
|
|
||||||
mfi->backupDate = htonl(0);
|
|
||||||
mfi->attributes = htonl((uint32_t)(rec->flFlags & 0x7F));
|
|
||||||
e++;
|
|
||||||
|
|
||||||
// finder info
|
// finder info
|
||||||
as->entry[e].type = htonl(kAppleDoubleFinderInfoEntry);
|
as->entry[e].type = htonl(kAppleDoubleFinderInfoEntry);
|
||||||
as->entry[e].offset = htonl(kAppleDoubleFinderInfoOffset);
|
as->entry[e].offset = htonl(kAppleDoubleFinderInfoOffset);
|
||||||
as->entry[e].length = htonl(kAppleDoubleFinderInfoLength);
|
as->entry[e].length = htonl(kAppleDoubleFinderInfoLength);
|
||||||
memcpy((void*)as+kAppleDoubleFinderInfoOffset, &rec->flUsrWds, 16);
|
memcpy((void*)as+kAppleDoubleFinderInfoOffset, &rec->flUsrWds, 16);
|
||||||
e++;
|
e++;
|
||||||
|
/*
|
||||||
// finder comment
|
// finder comment
|
||||||
#ifdef USE_LIBRES
|
#ifdef USE_LIBRES
|
||||||
size_t commentLength;
|
size_t commentLength;
|
||||||
@ -441,6 +415,16 @@ MFSFork* mfs_fkopen (MFSVolume *vol, MFSDirectoryRecord *rec, int mode, int writ
|
|||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
// resource fork
|
||||||
|
// kernel complains if it's not the last entry
|
||||||
|
if (fk->fkLgLen) {
|
||||||
|
as->entry[e].type = htonl(kAppleDoubleResourceForkEntry);
|
||||||
|
as->entry[e].offset = htonl(kAppleDoubleResourceForkOffset);
|
||||||
|
as->entry[e].length = htonl((uint32_t)fk->fkLgLen);
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
|
||||||
// number of entries written
|
// number of entries written
|
||||||
as->numEntries = htons(e);
|
as->numEntries = htons(e);
|
||||||
@ -473,27 +457,9 @@ MFSFork* mfs_dhopen (MFSVolume *vol, MFSFolder *folder) {
|
|||||||
// header
|
// header
|
||||||
as->magic = htonl(kAppleDoubleMagic);
|
as->magic = htonl(kAppleDoubleMagic);
|
||||||
as->version = htonl(kAppleDoubleVersion);
|
as->version = htonl(kAppleDoubleVersion);
|
||||||
memcpy(&as->filesystem, "Macintosh ", 16);
|
memcpy(&as->filesystem, "Mac OS X ", 16);
|
||||||
int e = 0;
|
int e = 0;
|
||||||
|
|
||||||
// real name
|
|
||||||
as->entry[e].type = htonl(kAppleDoubleRealNameEntry);
|
|
||||||
as->entry[e].offset = htonl(kAppleDoubleRealNameOffset);
|
|
||||||
as->entry[e].length = htonl(strlen(folder->fdCNam));
|
|
||||||
strcpy((void*)as+kAppleDoubleRealNameOffset, folder->fdCNam);
|
|
||||||
e++;
|
|
||||||
|
|
||||||
// file info
|
|
||||||
as->entry[e].type = htonl(kAppleDoubleFileInfoEntry);
|
|
||||||
as->entry[e].offset = htonl(kAppleDoubleFileInfoOffset);
|
|
||||||
as->entry[e].length = htonl(kAppleDoubleFileInfoLength);
|
|
||||||
AppleDoubleMacFileInfo *mfi = (void*)as+kAppleDoubleFileInfoOffset;
|
|
||||||
mfi->creationDate = htonl(folder->fdCrDat);
|
|
||||||
mfi->modificationDate = htonl(folder->fdMdDat);
|
|
||||||
mfi->backupDate = htonl(0);
|
|
||||||
mfi->attributes = htonl(0);
|
|
||||||
e++;
|
|
||||||
|
|
||||||
// finder info
|
// finder info
|
||||||
MFSFInfo finfo = {0, 0, 0, {0, 0}, 0};
|
MFSFInfo finfo = {0, 0, 0, {0, 0}, 0};
|
||||||
finfo.flags = htons(folder->fdFlags);
|
finfo.flags = htons(folder->fdFlags);
|
||||||
@ -505,6 +471,8 @@ MFSFork* mfs_dhopen (MFSVolume *vol, MFSFolder *folder) {
|
|||||||
memcpy((void*)as+kAppleDoubleFinderInfoOffset, &finfo, 16);
|
memcpy((void*)as+kAppleDoubleFinderInfoOffset, &finfo, 16);
|
||||||
e++;
|
e++;
|
||||||
|
|
||||||
|
// TODO: finder comment as xattr
|
||||||
|
/*
|
||||||
// finder comment
|
// finder comment
|
||||||
#ifdef USE_LIBRES
|
#ifdef USE_LIBRES
|
||||||
size_t commentLength;
|
size_t commentLength;
|
||||||
@ -515,7 +483,7 @@ MFSFork* mfs_dhopen (MFSVolume *vol, MFSFolder *folder) {
|
|||||||
e++;
|
e++;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
// number of entries written
|
// number of entries written
|
||||||
as->numEntries = htons(e);
|
as->numEntries = htons(e);
|
||||||
|
|
||||||
@ -691,10 +659,11 @@ int mfs_load_folders (MFSVolume *vol) {
|
|||||||
|
|
||||||
// print folders
|
// print folders
|
||||||
#if defined(LIBMFS_VERBOSE)
|
#if defined(LIBMFS_VERBOSE)
|
||||||
printf("FOLDERS:\n# PAR# SUB NAME\n");
|
fprintf(stderr, "FOLDERS:\n# PAR# SUB NAME\n");
|
||||||
for(i=0; i < count; i++)
|
for(i=0; i < count; i++)
|
||||||
printf("%-7hd%-7hd%-4hd%s\n", vol->folders[i].fdID, vol->folders[i].fdParent,
|
fprintf(stderr, "%-7hd%-7hd%-4hd%s\n", vol->folders[i].fdID, vol->folders[i].fdParent,
|
||||||
vol->folders[i].fdSubdirs, vol->folders[i].fdCNam);
|
vol->folders[i].fdSubdirs, vol->folders[i].fdCNam);
|
||||||
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(fobj);
|
free(fobj);
|
||||||
|
6
mfs.h
6
mfs.h
@ -182,12 +182,8 @@ typedef struct MFSFork MFSFork;
|
|||||||
|
|
||||||
#define kAppleDoubleHeaderLength 0x300
|
#define kAppleDoubleHeaderLength 0x300
|
||||||
#define kAppleDoubleResourceForkOffset kAppleDoubleHeaderLength
|
#define kAppleDoubleResourceForkOffset kAppleDoubleHeaderLength
|
||||||
#define kAppleDoubleFileInfoOffset 0x70
|
#define kAppleDoubleFinderInfoOffset 0x70
|
||||||
#define kAppleDoubleFileInfoLength 0x10
|
|
||||||
#define kAppleDoubleFinderInfoOffset 0x80
|
|
||||||
#define kAppleDoubleFinderInfoLength 0x20
|
#define kAppleDoubleFinderInfoLength 0x20
|
||||||
#define kAppleDoubleRealNameOffset 0xA0
|
|
||||||
#define kAppleDoubleCommentOffset 0x1A0
|
|
||||||
|
|
||||||
// open/close volume
|
// open/close volume
|
||||||
MFSVolume* mfs_vopen (const char *path, size_t offset, int flags);
|
MFSVolume* mfs_vopen (const char *path, size_t offset, int flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user