Subversion Repositories Games.Descent

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 1
/*
2
 * Haiku 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_HAIKU
13
 
14
#include <os/kernel/OS.h>
15
#include <os/app/Roster.h>
16
#include <os/storage/Volume.h>
17
#include <os/storage/VolumeRoster.h>
18
#include <os/storage/Directory.h>
19
#include <os/storage/Entry.h>
20
#include <os/storage/Path.h>
21
#include <os/kernel/fs_info.h>
22
#include <os/device/scsi.h>
23
 
24
#include <errno.h>
25
#include <unistd.h>
26
 
27
#include "physfs_internal.h"
28
 
29
int __PHYSFS_platformInit(void)
30
{
31
    return 1;  /* always succeed. */
32
} /* __PHYSFS_platformInit */
33
 
34
 
35
void __PHYSFS_platformDeinit(void)
36
{
37
    /* no-op */
38
} /* __PHYSFS_platformDeinit */
39
 
40
 
41
static char *getMountPoint(const char *devname, char *buf, size_t bufsize)
42
{
43
    BVolumeRoster mounts;
44
    BVolume vol;
45
 
46
    mounts.Rewind();
47
    while (mounts.GetNextVolume(&vol) == B_NO_ERROR)
48
    {
49
        fs_info fsinfo;
50
        fs_stat_dev(vol.Device(), &fsinfo);
51
        if (strcmp(devname, fsinfo.device_name) == 0)
52
        {
53
            BDirectory directory;
54
            BEntry entry;
55
            BPath path;
56
            const char *str;
57
 
58
            if ( (vol.GetRootDirectory(&directory) < B_OK) ||
59
                 (directory.GetEntry(&entry) < B_OK) ||
60
                 (entry.GetPath(&path) < B_OK) ||
61
                 ( (str = path.Path()) == NULL) )
62
                return NULL;
63
 
64
            strncpy(buf, str, bufsize-1);
65
            buf[bufsize-1] = '\0';
66
            return buf;
67
        } /* if */
68
    } /* while */
69
 
70
    return NULL;
71
} /* getMountPoint */
72
 
73
 
74
    /*
75
     * This function is lifted from Simple Directmedia Layer (SDL):
76
     *  https://www.libsdl.org/  ... this is zlib-licensed code, too.
77
     */
78
static void tryDir(const char *d, PHYSFS_StringCallback callback, void *data)
79
{
80
    BDirectory dir;
81
    dir.SetTo(d);
82
    if (dir.InitCheck() != B_NO_ERROR)
83
        return;
84
 
85
    dir.Rewind();
86
    BEntry entry;
87
    while (dir.GetNextEntry(&entry) >= 0)
88
    {
89
        BPath path;
90
        const char *name;
91
        entry_ref e;
92
 
93
        if (entry.GetPath(&path) != B_NO_ERROR)
94
            continue;
95
 
96
        name = path.Path();
97
 
98
        if (entry.GetRef(&e) != B_NO_ERROR)
99
            continue;
100
 
101
        if (entry.IsDirectory())
102
        {
103
            if (strcmp(e.name, "floppy") != 0)
104
                tryDir(name, callback, data);
105
            continue;
106
        } /* if */
107
 
108
        const int devfd = open(name, O_RDONLY);
109
        if (devfd < 0)
110
            continue;
111
 
112
        device_geometry g;
113
        const int rc = ioctl(devfd, B_GET_GEOMETRY, &g, sizeof (g));
114
        close(devfd);
115
        if (rc < 0)
116
            continue;
117
 
118
        if (g.device_type != B_CD)
119
            continue;
120
 
121
        char mntpnt[B_FILE_NAME_LENGTH];
122
        if (getMountPoint(name, mntpnt, sizeof (mntpnt)))
123
            callback(data, mntpnt);
124
    } /* while */
125
} /* tryDir */
126
 
127
 
128
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
129
{
130
    tryDir("/dev/disk", cb, data);
131
} /* __PHYSFS_platformDetectAvailableCDs */
132
 
133
 
134
static team_id getTeamID(void)
135
{
136
    thread_info info;
137
    thread_id tid = find_thread(NULL);
138
    get_thread_info(tid, &info);
139
    return info.team;
140
} /* getTeamID */
141
 
142
 
143
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
144
{
145
    image_info info;
146
    int32 cookie = 0;
147
 
148
    while (get_next_image_info(0, &cookie, &info) == B_OK)
149
    {
150
        if (info.type == B_APP_IMAGE)
151
            break;
152
    } /* while */
153
 
154
    BEntry entry(info.name, true);
155
    BPath path;
156
    status_t rc = entry.GetPath(&path);  /* (path) now has binary's path. */
157
    assert(rc == B_OK);
158
    rc = path.GetParent(&path); /* chop filename, keep directory. */
159
    assert(rc == B_OK);
160
    const char *str = path.Path();
161
    assert(str != NULL);
162
    const size_t len = strlen(str);
163
    char *retval = (char *) allocator.Malloc(len + 2);
164
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
165
    strcpy(retval, str);
166
    retval[len] = '/';
167
    retval[len+1] = '\0';
168
    return retval;
169
} /* __PHYSFS_platformCalcBaseDir */
170
 
171
 
172
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
173
{
174
    const char *userdir = __PHYSFS_getUserDir();
175
    const char *append = "config/settings/";
176
    const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
177
    char *retval = (char *) allocator.Malloc(len);
178
    BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
179
    snprintf(retval, len, "%s%s%s/", userdir, append, app);
180
    return retval;
181
} /* __PHYSFS_platformCalcPrefDir */
182
 
183
#endif  /* PHYSFS_PLATFORM_HAIKU */
184
 
185
/* end of physfs_platform_haiku.cpp ... */
186