ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/BeOS/extfs_beos.cpp
Revision: 1.2
Committed: 1999-10-19T21:33:57Z (25 years, 1 month ago) by cebix
Branch: MAIN
CVS Tags: snapshot-21101999
Changes since 1.1: +6 -1 lines
Log Message:
- fixed compilation problems on BeOS

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