ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/extfs_beos.cpp
Revision: 1.1
Committed: 1999-10-19T17:41:28Z (25 years, 1 month ago) by cebix
Branch: MAIN
Log Message:
- added external file system
- moved most init/deinit code to InitAll()/ExitAll() in main.cpp

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * extfs_beos.cpp - MacOS file system for access native file system access, BeOS specific stuff
3     *
4     * Basilisk II (C) 1997-1999 Christian Bauer
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     #include <sys/types.h>
22     #include <sys/stat.h>
23     #include <stdio.h>
24     #include <stdlib.h>
25     #include <unistd.h>
26     #include <dirent.h>
27     #include <errno.h>
28    
29     #include <fs_attr.h>
30    
31     #include "sysdeps.h"
32     #include "extfs.h"
33     #include "extfs_defs.h"
34    
35     #define DEBUG 0
36     #include "debug.h"
37    
38    
39     // Default Finder flags
40     const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited;
41    
42     // Temporary buffer for transfers from/to kernel space
43     const int TMP_BUF_SIZE = 0x10000;
44     static uint8 *tmp_buf = NULL;
45    
46    
47     /*
48     * Initialization
49     */
50    
51     void extfs_init(void)
52     {
53     // Allocate temporary buffer
54     tmp_buf = new uint8[TMP_BUF_SIZE];
55     }
56    
57    
58     /*
59     * Deinitialization
60     */
61    
62     void extfs_exit(void)
63     {
64     // Delete temporary buffer
65     delete[] tmp_buf;
66     }
67    
68    
69     /*
70     * Get/set finder type/creator for file specified by full path
71     */
72    
73     struct mime2type {
74     const char *mime;
75     uint32 type;
76     uint32 creator;
77     bool reversible; // type -> mime translation possible
78     };
79    
80     static const mime2type m2t_translation[] = {
81     {"application/x-compress", 'ZIVM', 'LZIV', true},
82     {"application/x-gzip", 'Gzip', 'Gzip', true},
83     {"application/x-macbinary", 'BINA', '????', false},
84     {"application/mac-binhex40", 'TEXT', 'SITx', false},
85     {"application/pdf", 'PDF ', 'CARO', true},
86     {"application/postscript", 'TEXT', 'ttxt', false},
87     {"application/x-stuffit", 'SIT!', 'SITx', true},
88     {"application/x-tar", 'TARF', 'TAR ', true},
89     {"application/x-uuencode", 'TEXT', 'SITx', false},
90     {"application/zip", 'ZIP ', 'ZIP ', true},
91     {"audio/x-8svx", '8SVX', 'SNDM', true},
92     {"audio/x-aifc", 'AIFC', 'TVOD', true},
93     {"audio/x-aiff", 'AIFF', 'TVOD', true},
94     {"audio/basic", 'ULAW', 'TVOD', true},
95     {"audio/x-midi", 'MIDI', 'TVOD', true},
96     {"audio/x-mpeg", 'MPG ', 'TVOD', true},
97     {"audio/x-wav", 'WAVE', 'TVOD', true},
98     {"image/x-bmp", 'BMPf', 'ogle', true},
99     {"image/gif", 'GIFf', 'ogle', true},
100     {"image/x-ilbm", 'ILBM', 'GKON', true},
101     {"image/jpeg", 'JPEG', 'ogle', true},
102     {"image/jpeg", 'JFIF', 'ogle', true},
103     {"image/x-photoshop", '8BPS', '8BIM', true},
104     {"image/pict", 'PICT', 'ogle', true},
105     {"image/png", 'PNGf', 'ogle', true},
106     {"image/x-sgi", '.SGI', 'ogle', true},
107     {"image/x-targa", 'TPIC', 'ogle', true},
108     {"image/tiff", 'TIFF', 'ogle', true},
109     {"text/html", 'TEXT', 'MOSS', false},
110     {"text/plain", 'TEXT', 'ttxt', true},
111     {"text/rtf", 'TEXT', 'MSWD', false},
112     {"text/x-source-code", 'TEXT', 'R*ch', false},
113     {"video/mpeg", 'MPEG', 'TVOD', true},
114     {"video/quicktime", 'MooV', 'TVOD', true},
115     {"video/x-flc", 'FLI ', 'TVOD', true},
116     {"video/x-msvideo", 'VfW ', 'TVOD', true},
117     {NULL, 0, 0, false} // End marker
118     };
119    
120     void get_finder_type(const char *path, uint32 &type, uint32 &creator)
121     {
122     type = 0;
123     creator = 0;
124    
125     // Open file
126     int fd = open(path, O_RDONLY);
127     if (fd < 0)
128     return;
129    
130     // Read BeOS MIME type and close file
131     char mime[256];
132     ssize_t actual = fs_read_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, mime, 256);
133     mime[255] = 0;
134    
135     if (actual > 0) {
136    
137     // Translate MIME type to MacOS type/creator
138     char mactype[4];
139     if (sscanf(mime, "application/x-MacOS-%c%c%c%c", mactype, mactype+1, mactype+2, mactype+3) == 4) {
140    
141     // MacOS style type
142     memcpy(&type, mactype, 4);
143    
144     } else {
145    
146     // MIME string, look in table
147     for (int i=0; m2t_translation[i].mime; i++) {
148     if (!strcmp(mime, m2t_translation[i].mime)) {
149     type = m2t_translation[i].type;
150     creator = m2t_translation[i].creator;
151     break;
152     }
153     }
154     }
155     }
156    
157     // Override file type with MACOS:CREATOR attribute
158     fs_read_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, &creator, 4);
159    
160     // Close file
161     close(fd);
162     }
163    
164     void set_finder_type(const char *path, uint32 type, uint32 creator)
165     {
166     // Open file
167     int fd = open(path, O_WRONLY);
168     if (fd < 0)
169     return;
170    
171     // Set BEOS:TYPE attribute
172     if (type) {
173     bool written = false;
174     for (int i=0; m2t_translation[i].mime; i++) {
175     if (m2t_translation[i].type == type && m2t_translation[i].reversible) {
176     fs_write_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, m2t_translation[i].mime, strlen(m2t_translation[i].mime) + 1);
177     written = true;
178     break;
179     }
180     }
181     if (!written) {
182     char mime[256];
183     sprintf(mime, "application/x-MacOS-%c%c%c%c", type >> 24, type >> 16, type >> 8, type);
184     fs_write_attr(fd, "BEOS:TYPE", B_MIME_STRING_TYPE, 0, mime, strlen(mime) + 1);
185     }
186     }
187    
188     // Set MACOS:CREATOR attribute
189     if (creator)
190     fs_write_attr(fd, "MACOS:CREATOR", B_UINT32_TYPE, 0, &creator, 4);
191    
192     // Close file
193     close(fd);
194     }
195    
196    
197     /*
198     * Get/set finder flags for file/dir specified by full path (MACOS:HFS_FLAGS attribute)
199     */
200    
201     void get_finder_flags(const char *path, uint16 &flags)
202     {
203     flags = DEFAULT_FINDER_FLAGS; // Default
204    
205     // Open file
206     int fd = open(path, O_RDONLY);
207     if (fd < 0)
208     return;
209    
210     // Read MACOS:HFS_FLAGS attribute
211     fs_read_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, &flags, 2);
212    
213     // Close file
214     close(fd);
215     }
216    
217     void set_finder_flags(const char *path, uint16 flags)
218     {
219     // Open file
220     int fd = open(path, O_WRONLY);
221     if (fd < 0)
222     return;
223    
224     // Write MACOS:HFS_FLAGS attribute
225     if (flags != DEFAULT_FINDER_FLAGS)
226     fs_write_attr(fd, "MACOS:HFS_FLAGS", B_UINT16_TYPE, 0, &flags, 2);
227     else
228     fs_remove_attr(fd, "MACOS:HFS_FLAGS");
229    
230     // Close file
231     close(fd);
232     }
233    
234    
235     /*
236     * Resource fork emulation functions
237     */
238    
239     uint32 get_rfork_size(const char *path)
240     {
241     // Open file
242     int fd = open(path, O_RDONLY);
243     if (fd < 0)
244     return 0;
245    
246     // Get size of MACOS:RFORK attribute
247     struct attr_info info;
248     if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0)
249     info.size = 0;
250    
251     // Close file and return size
252     close(fd);
253     return info.size;
254     }
255    
256     int open_rfork(const char *path, int flag)
257     {
258     // Open original file
259     int fd = open(path, flag);
260     if (fd < 0)
261     return -1;
262    
263     // Open temporary file for resource fork
264     char rname[L_tmpnam];
265     tmpnam(rname);
266     int rfd = open(rname, O_RDWR | O_CREAT | O_TRUNC, 0664);
267     if (rfd < 0) {
268     close(fd);
269     return -1;
270     }
271     unlink(rname); // File will be deleted when closed
272    
273     // Get size of MACOS:RFORK attribute
274     struct attr_info info;
275     if (fs_stat_attr(fd, "MACOS:RFORK", &info) < 0)
276     info.size = 0;
277    
278     // Copy resource data from attribute to temporary file
279     if (info.size > 0) {
280    
281     // Allocate buffer
282     void *buf = malloc(info.size);
283     if (buf == NULL) {
284     close(rfd);
285     close(fd);
286     return -1;
287     }
288    
289     // Copy data
290     fs_read_attr(fd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, info.size);
291     write(rfd, buf, info.size);
292     lseek(rfd, 0, SEEK_SET);
293    
294     // Free buffer
295     if (buf)
296     free(buf);
297     }
298    
299     // Close original file
300     close(fd);
301     return rfd;
302     }
303    
304     void close_rfork(const char *path, int fd)
305     {
306     if (fd < 0)
307     return;
308    
309     // Get size of temporary file
310     struct stat st;
311     if (fstat(fd, &st) < 0)
312     st.st_size = 0;
313    
314     // Open original file
315     int ofd = open(path, O_WRONLY);
316     if (ofd > 0) {
317    
318     // Copy resource data to MACOS:RFORK attribute
319     if (st.st_size > 0) {
320    
321     // Allocate buffer
322     void *buf = malloc(st.st_size);
323     if (buf == NULL) {
324     close(ofd);
325     close(fd);
326     return;
327     }
328    
329     // Copy data
330     lseek(fd, 0, SEEK_SET);
331     read(fd, buf, st.st_size);
332     fs_write_attr(ofd, "MACOS:RFORK", B_RAW_TYPE, 0, buf, st.st_size);
333    
334     // Free buffer
335     if (buf)
336     free(buf);
337    
338     } else
339     fs_remove_attr(ofd, "MACOS:RFORK");
340    
341     // Close original file
342     close(ofd);
343     }
344    
345     // Close temporary file
346     close(fd);
347     }
348    
349    
350     /*
351     * Read "length" bytes from file to "buffer",
352     * returns number of bytes read (or 0)
353     */
354    
355     static inline ssize_t sread(int fd, void *buf, size_t count)
356     {
357     ssize_t res;
358     while ((res = read(fd, buf, count)) == B_INTERRUPTED) ;
359     return res;
360     }
361    
362     size_t extfs_read(int fd, void *buffer, size_t length)
363     {
364     errno = 0;
365    
366     // Buffer in kernel space?
367     size_t actual = 0;
368     if ((uint32)buffer < 0x80000000) {
369    
370     // Yes, transfer via buffer
371     while (length) {
372     size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
373     ssize_t res = sread(fd, tmp_buf, transfer_size);
374     if (res >= 0) {
375     memcpy(buffer, tmp_buf, res);
376     buffer = (void *)((uint8 *)buffer + res);
377     length -= res;
378     actual += res;
379     }
380     if (res != transfer_size)
381     return actual;
382     }
383    
384     } else {
385    
386     // No, transfer directly
387     actual = sread(fd, buffer, length);
388     if (actual < 0)
389     actual = 0;
390     }
391     return actual;
392     }
393    
394    
395     /*
396     * Write "length" bytes from "buffer" to file,
397     * returns number of bytes written (or 0)
398     */
399    
400     static inline ssize_t swrite(int fd, void *buf, size_t count)
401     {
402     ssize_t res;
403     while ((res = write(fd, buf, count)) == B_INTERRUPTED) ;
404     return res;
405     }
406    
407     size_t extfs_write(int fd, void *buffer, size_t length)
408     {
409     errno = 0;
410    
411     // Buffer in kernel space?
412     size_t actual = 0;
413     if ((uint32)buffer < 0x80000000) {
414    
415     // Yes, transfer via buffer
416     while (length) {
417     size_t transfer_size = (length > TMP_BUF_SIZE) ? TMP_BUF_SIZE : length;
418     memcpy(tmp_buf, buffer, transfer_size);
419     ssize_t res = swrite(fd, tmp_buf, transfer_size);
420     if (res >= 0) {
421     buffer = (void *)((uint8 *)buffer + res);
422     length -= res;
423     actual += res;
424     }
425     if (res != transfer_size)
426     return actual;
427     }
428    
429     } else {
430    
431     // No, transfer directly
432     actual = swrite(fd, buffer, length);
433     if (actual < 0)
434     actual = 0;
435     }
436     return actual;
437     }