mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-16 14:30:34 +00:00
Full sparsebundle implementation
This commit is contained in:
parent
091db05aac
commit
2a15911938
@ -19,13 +19,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "disk_unix.h"
|
#include "disk_unix.h"
|
||||||
|
#include "tinyxml2.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// - Factory needs to actually check stuff
|
|
||||||
// - Add to basilisk build
|
// - Add to basilisk build
|
||||||
// - Add to 'make links'
|
// - Add to 'make links'
|
||||||
|
// - Test on Linux
|
||||||
|
// - Iterate through factories
|
||||||
|
|
||||||
typedef ssize_t (band_func)(int fd, void *buf, size_t len);
|
typedef ssize_t (band_func)(int fd, void *buf, size_t len);
|
||||||
|
|
||||||
@ -132,23 +134,131 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
using tinyxml2::XML_NO_ERROR;
|
||||||
|
using tinyxml2::XMLElement;
|
||||||
|
|
||||||
|
// Simplistic plist parser
|
||||||
|
struct plist {
|
||||||
|
plist() : doc(true, tinyxml2::COLLAPSE_WHITESPACE) { }
|
||||||
|
|
||||||
|
bool open(const char *path) {
|
||||||
|
if (doc.LoadFile(path) != XML_NO_ERROR)
|
||||||
|
return false;
|
||||||
|
tinyxml2::XMLHandle hnd(&doc);
|
||||||
|
dict = hnd.FirstChildElement("plist").FirstChildElement("dict")
|
||||||
|
.ToElement();
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *str_val(const char *key) {
|
||||||
|
return value(key, "string");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool int_val(const char *key, loff_t *i) {
|
||||||
|
const char *v = value(key, "integer");
|
||||||
|
if (!v || !*v)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *endp;
|
||||||
|
long long ll = strtoll(v, &endp, 10);
|
||||||
|
if (*endp)
|
||||||
|
return false;
|
||||||
|
*i = ll;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
tinyxml2::XMLDocument doc;
|
||||||
|
XMLElement *dict;
|
||||||
|
|
||||||
|
const char *value(const char *key, const char *type) {
|
||||||
|
// Assume it's a flat plist
|
||||||
|
XMLElement *cur = dict->FirstChildElement();
|
||||||
|
bool found_key = false;
|
||||||
|
while (cur) {
|
||||||
|
if (found_key) {
|
||||||
|
if (strcmp(cur->Name(), type) != 0)
|
||||||
|
return NULL;
|
||||||
|
return cur->GetText();
|
||||||
|
}
|
||||||
|
found_key = strcmp(cur->Name(), "key") == 0
|
||||||
|
&& strcmp(cur->GetText(), key) == 0;
|
||||||
|
cur = cur->NextSiblingElement();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int try_open(const char *path, bool read_only) {
|
||||||
|
int oflags = (read_only ? O_RDONLY : O_RDWR);
|
||||||
|
#if defined(__MACOSX__)
|
||||||
|
oflags |= O_EXLOCK;
|
||||||
|
#endif
|
||||||
|
int fd = open(path, oflags);
|
||||||
|
#if defined(__MACOSX__)
|
||||||
|
if (fd == -1) {
|
||||||
|
if (errno == EOPNOTSUPP) { // no locking support
|
||||||
|
oflags &= ~O_EXLOCK;
|
||||||
|
fd = open(path, oflags);
|
||||||
|
} else if (errno == EAGAIN) { // already locked
|
||||||
|
fprintf(stderr, "sparsebundle: Refusing to double-mount\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
disk_generic *disk_sparsebundle_factory(const char *path, bool read_only) {
|
disk_generic *disk_sparsebundle_factory(const char *path, bool read_only) {
|
||||||
if (strstr(path, ".sparsebundle") == NULL)
|
// Does it look like a sparsebundle?
|
||||||
return NULL; // FIXME: real test
|
|
||||||
|
|
||||||
// FIXME: actually read these
|
|
||||||
loff_t band_size = 1048576;
|
|
||||||
loff_t total_size = 53687091200;
|
|
||||||
|
|
||||||
// FIXME: check for double-mount, writable
|
|
||||||
int token = 0;
|
|
||||||
read_only = false;
|
|
||||||
|
|
||||||
char buf[PATH_MAX + 1];
|
char buf[PATH_MAX + 1];
|
||||||
|
if (snprintf(buf, PATH_MAX, "%s/%s", path, "Info.plist") >= PATH_MAX)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
plist pl;
|
||||||
|
if (!pl.open(buf))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
const char *type;
|
||||||
|
if (!(type = pl.str_val("diskimage-bundle-type")))
|
||||||
|
return NULL;
|
||||||
|
if (strcmp(type, "com.apple.diskimage.sparsebundle") != 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
|
// Find the sparsebundle parameters
|
||||||
|
loff_t version, band_size, total_size;
|
||||||
|
if (!pl.int_val("bundle-backingstore-version", &version) || version != 1) {
|
||||||
|
fprintf(stderr, "sparsebundle: Bad version\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!pl.int_val("band-size", &band_size)
|
||||||
|
|| !pl.int_val("size", &total_size)) {
|
||||||
|
fprintf(stderr, "sparsebundle: Can't find size\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check if we can open it
|
||||||
|
if (snprintf(buf, PATH_MAX, "%s/%s", path, "token") >= PATH_MAX)
|
||||||
|
return NULL;
|
||||||
|
int token = try_open(buf, read_only);
|
||||||
|
if (token == -1 && !read_only) { // try again, read-only
|
||||||
|
read_only = true;
|
||||||
|
token = try_open(buf, read_only);
|
||||||
|
}
|
||||||
|
if (token == -1) {
|
||||||
|
fprintf(stderr, "sparsebundle: Can't open the bundle\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We're good to go!
|
||||||
if (snprintf(buf, PATH_MAX, "%s/%s", path, "bands") >= PATH_MAX)
|
if (snprintf(buf, PATH_MAX, "%s/%s", path, "bands") >= PATH_MAX)
|
||||||
return NULL;
|
return NULL;
|
||||||
char *bands = strdup(buf);
|
char *bands = strdup(buf);
|
||||||
|
|
||||||
return new disk_sparsebundle(bands, token, read_only, band_size,
|
return new disk_sparsebundle(bands, token, read_only, band_size,
|
||||||
total_size);
|
total_size);
|
||||||
}
|
}
|
||||||
|
2095
BasiliskII/src/Unix/tinyxml2.cpp
Executable file
2095
BasiliskII/src/Unix/tinyxml2.cpp
Executable file
File diff suppressed because it is too large
Load Diff
1968
BasiliskII/src/Unix/tinyxml2.h
Executable file
1968
BasiliskII/src/Unix/tinyxml2.h
Executable file
File diff suppressed because it is too large
Load Diff
@ -59,7 +59,7 @@ SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp
|
|||||||
../macos_util.cpp ../timer.cpp timer_unix.cpp ../xpram.cpp xpram_unix.cpp \
|
../macos_util.cpp ../timer.cpp timer_unix.cpp ../xpram.cpp xpram_unix.cpp \
|
||||||
../adb.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp \
|
../adb.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp \
|
||||||
../gfxaccel.cpp ../video.cpp video_blit.cpp ../audio.cpp ../ether.cpp ../thunks.cpp \
|
../gfxaccel.cpp ../video.cpp video_blit.cpp ../audio.cpp ../ether.cpp ../thunks.cpp \
|
||||||
../serial.cpp ../extfs.cpp disk_sparsebundle.cpp \
|
../serial.cpp ../extfs.cpp disk_sparsebundle.cpp tinyxml2.cpp \
|
||||||
about_window_unix.cpp ../user_strings.cpp user_strings_unix.cpp \
|
about_window_unix.cpp ../user_strings.cpp user_strings_unix.cpp \
|
||||||
vm_alloc.cpp sigsegv.cpp rpc_unix.cpp \
|
vm_alloc.cpp sigsegv.cpp rpc_unix.cpp \
|
||||||
sshpty.c strlcpy.c $(SYSSRCS) $(CPUSRCS) $(MONSRCS) $(SLIRP_SRCS)
|
sshpty.c strlcpy.c $(SYSSRCS) $(CPUSRCS) $(MONSRCS) $(SLIRP_SRCS)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user