7768
+ − 1
/*
+ − 2
* BeOS platform-dependent support routines for PhysicsFS.
+ − 3
*
+ − 4
* Please see the file LICENSE.txt in the source's root directory.
+ − 5
*
+ − 6
* This file written by Ryan C. Gordon.
+ − 7
*/
+ − 8
+ − 9
#define __PHYSICSFS_INTERNAL__
+ − 10
#include "physfs_platforms.h"
+ − 11
+ − 12
#ifdef PHYSFS_PLATFORM_BEOS
+ − 13
+ − 14
#ifdef PHYSFS_PLATFORM_HAIKU
+ − 15
#include <os/kernel/OS.h>
+ − 16
#include <os/app/Roster.h>
+ − 17
#include <os/storage/Volume.h>
+ − 18
#include <os/storage/VolumeRoster.h>
+ − 19
#include <os/storage/Directory.h>
+ − 20
#include <os/storage/Entry.h>
+ − 21
#include <os/storage/Path.h>
+ − 22
#include <os/kernel/fs_info.h>
+ − 23
#include <os/device/scsi.h>
+ − 24
#include <os/support/Locker.h>
+ − 25
#else
+ − 26
#include <be/kernel/OS.h>
+ − 27
#include <be/app/Roster.h>
+ − 28
#include <be/storage/Volume.h>
+ − 29
#include <be/storage/VolumeRoster.h>
+ − 30
#include <be/storage/Directory.h>
+ − 31
#include <be/storage/Entry.h>
+ − 32
#include <be/storage/Path.h>
+ − 33
#include <be/kernel/fs_info.h>
+ − 34
#include <be/device/scsi.h>
+ − 35
#include <be/support/Locker.h>
+ − 36
#endif
+ − 37
+ − 38
#include <errno.h>
+ − 39
#include <unistd.h>
+ − 40
+ − 41
#include "physfs_internal.h"
+ − 42
+ − 43
int __PHYSFS_platformInit(void)
+ − 44
{
+ − 45
return 1; /* always succeed. */
+ − 46
} /* __PHYSFS_platformInit */
+ − 47
+ − 48
+ − 49
int __PHYSFS_platformDeinit(void)
+ − 50
{
+ − 51
return 1; /* always succeed. */
+ − 52
} /* __PHYSFS_platformDeinit */
+ − 53
+ − 54
+ − 55
static char *getMountPoint(const char *devname, char *buf, size_t bufsize)
+ − 56
{
+ − 57
BVolumeRoster mounts;
+ − 58
BVolume vol;
+ − 59
+ − 60
mounts.Rewind();
+ − 61
while (mounts.GetNextVolume(&vol) == B_NO_ERROR)
+ − 62
{
+ − 63
fs_info fsinfo;
+ − 64
fs_stat_dev(vol.Device(), &fsinfo);
+ − 65
if (strcmp(devname, fsinfo.device_name) == 0)
+ − 66
{
+ − 67
BDirectory directory;
+ − 68
BEntry entry;
+ − 69
BPath path;
+ − 70
const char *str;
+ − 71
+ − 72
if ( (vol.GetRootDirectory(&directory) < B_OK) ||
+ − 73
(directory.GetEntry(&entry) < B_OK) ||
+ − 74
(entry.GetPath(&path) < B_OK) ||
+ − 75
( (str = path.Path()) == NULL) )
+ − 76
return NULL;
+ − 77
+ − 78
strncpy(buf, str, bufsize-1);
+ − 79
buf[bufsize-1] = '\0';
+ − 80
return buf;
+ − 81
} /* if */
+ − 82
} /* while */
+ − 83
+ − 84
return NULL;
+ − 85
} /* getMountPoint */
+ − 86
+ − 87
+ − 88
/*
+ − 89
* This function is lifted from Simple Directmedia Layer (SDL):
+ − 90
* http://www.libsdl.org/ ... this is zlib-licensed code, too.
+ − 91
*/
+ − 92
static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
+ − 93
{
+ − 94
BDirectory dir;
+ − 95
dir.SetTo(d);
+ − 96
if (dir.InitCheck() != B_NO_ERROR)
+ − 97
return;
+ − 98
+ − 99
dir.Rewind();
+ − 100
BEntry entry;
+ − 101
while (dir.GetNextEntry(&entry) >= 0)
+ − 102
{
+ − 103
BPath path;
+ − 104
const char *name;
+ − 105
entry_ref e;
+ − 106
+ − 107
if (entry.GetPath(&path) != B_NO_ERROR)
+ − 108
continue;
+ − 109
+ − 110
name = path.Path();
+ − 111
+ − 112
if (entry.GetRef(&e) != B_NO_ERROR)
+ − 113
continue;
+ − 114
+ − 115
if (entry.IsDirectory())
+ − 116
{
+ − 117
if (strcmp(e.name, "floppy") != 0)
+ − 118
tryDir(name, callback, data);
+ − 119
continue;
+ − 120
} /* if */
+ − 121
+ − 122
if (strcmp(e.name, "raw") != 0) /* ignore partitions. */
+ − 123
continue;
+ − 124
+ − 125
const int devfd = open(name, O_RDONLY);
+ − 126
if (devfd < 0)
+ − 127
continue;
+ − 128
+ − 129
device_geometry g;
+ − 130
const int rc = ioctl(devfd, B_GET_GEOMETRY, &g, sizeof (g));
+ − 131
close(devfd);
+ − 132
if (rc < 0)
+ − 133
continue;
+ − 134
+ − 135
if (g.device_type != B_CD)
+ − 136
continue;
+ − 137
+ − 138
char mntpnt[B_FILE_NAME_LENGTH];
+ − 139
if (getMountPoint(name, mntpnt, sizeof (mntpnt)))
+ − 140
callback(data, mntpnt);
+ − 141
} /* while */
+ − 142
} /* tryDir */
+ − 143
+ − 144
+ − 145
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+ − 146
{
+ − 147
tryDir("/dev/disk", cb, data);
+ − 148
} /* __PHYSFS_platformDetectAvailableCDs */
+ − 149
+ − 150
+ − 151
static team_id getTeamID(void)
+ − 152
{
+ − 153
thread_info info;
+ − 154
thread_id tid = find_thread(NULL);
+ − 155
get_thread_info(tid, &info);
+ − 156
return info.team;
+ − 157
} /* getTeamID */
+ − 158
+ − 159
+ − 160
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+ − 161
{
+ − 162
image_info info;
+ − 163
int32 cookie = 0;
+ − 164
+ − 165
while (get_next_image_info(0, &cookie, &info) == B_OK)
+ − 166
{
+ − 167
if (info.type == B_APP_IMAGE)
+ − 168
break;
+ − 169
} /* while */
+ − 170
+ − 171
BEntry entry(info.name, true);
+ − 172
BPath path;
+ − 173
status_t rc = entry.GetPath(&path); /* (path) now has binary's path. */
+ − 174
assert(rc == B_OK);
+ − 175
rc = path.GetParent(&path); /* chop filename, keep directory. */
+ − 176
assert(rc == B_OK);
+ − 177
const char *str = path.Path();
+ − 178
assert(str != NULL);
+ − 179
const size_t len = strlen(str);
+ − 180
char *retval = (char *) allocator.Malloc(len + 2);
+ − 181
BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ − 182
strcpy(retval, str);
+ − 183
retval[len] = '/';
+ − 184
retval[len+1] = '\0';
+ − 185
return retval;
+ − 186
} /* __PHYSFS_platformCalcBaseDir */
+ − 187
+ − 188
+ − 189
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+ − 190
{
+ − 191
const char *userdir = __PHYSFS_getUserDir();
+ − 192
const char *append = "config/settings/";
+ − 193
const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
+ − 194
char *retval = allocator.Malloc(len);
+ − 195
BAIL_IF_MACRO(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
+ − 196
snprintf(retval, len, "%s%s%s/", userdir, append, app);
+ − 197
return retval;
+ − 198
} /* __PHYSFS_platformCalcPrefDir */
+ − 199
+ − 200
+ − 201
void *__PHYSFS_platformGetThreadID(void)
+ − 202
{
+ − 203
return (void *) find_thread(NULL);
+ − 204
} /* __PHYSFS_platformGetThreadID */
+ − 205
+ − 206
+ − 207
void *__PHYSFS_platformCreateMutex(void)
+ − 208
{
+ − 209
return new BLocker("PhysicsFS lock", true);
+ − 210
} /* __PHYSFS_platformCreateMutex */
+ − 211
+ − 212
+ − 213
void __PHYSFS_platformDestroyMutex(void *mutex)
+ − 214
{
+ − 215
delete ((BLocker *) mutex);
+ − 216
} /* __PHYSFS_platformDestroyMutex */
+ − 217
+ − 218
+ − 219
int __PHYSFS_platformGrabMutex(void *mutex)
+ − 220
{
+ − 221
return ((BLocker *) mutex)->Lock() ? 1 : 0;
+ − 222
} /* __PHYSFS_platformGrabMutex */
+ − 223
+ − 224
+ − 225
void __PHYSFS_platformReleaseMutex(void *mutex)
+ − 226
{
+ − 227
((BLocker *) mutex)->Unlock();
+ − 228
} /* __PHYSFS_platformReleaseMutex */
+ − 229
+ − 230
+ − 231
int __PHYSFS_platformSetDefaultAllocator(PHYSFS_Allocator *a)
+ − 232
{
+ − 233
return 0; /* just use malloc() and friends. */
+ − 234
} /* __PHYSFS_platformSetDefaultAllocator */
+ − 235
+ − 236
#endif /* PHYSFS_PLATFORM_BEOS */
+ − 237
+ − 238
/* end of beos.cpp ... */
+ − 239