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 (24 years, 8 months 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

# Content
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 "sysdeps.h"
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <dirent.h>
31 #include <errno.h>
32
33 #include <fs_attr.h>
34 #include <support/TypeConstants.h>
35 #include <storage/Mime.h>
36
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 }