ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/extfs_amiga.cpp
Revision: 1.7
Committed: 2000-04-10T18:52:36Z (24 years, 7 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-13072000
Changes since 1.6: +1 -1 lines
Log Message:
- updated copyright info: 1999->2000

File Contents

# Content
1 /*
2 * extfs_amiga.cpp - MacOS file system for access native file system access, AmigaOS specific stuff
3 *
4 * Basilisk II (C) 1997-2000 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 <exec/types.h>
22 #include <proto/dos.h>
23
24 #include <sys/types.h>
25 #include <sys/stat.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 "sysdeps.h"
34 #include "extfs.h"
35 #include "extfs_defs.h"
36
37 #define DEBUG 0
38 #include "debug.h"
39
40
41 // Default Finder flags
42 const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited;
43
44
45 /*
46 * Initialization
47 */
48
49 void extfs_init(void)
50 {
51 }
52
53
54 /*
55 * Deinitialization
56 */
57
58 void extfs_exit(void)
59 {
60 }
61
62
63 /*
64 * Add component to path name
65 */
66
67 void add_path_component(char *path, const char *component)
68 {
69 AddPart(path, (char *)component, MAX_PATH_LENGTH);
70 }
71
72
73 /*
74 * Finder info and resource forks are kept in helper files
75 *
76 * Finder info:
77 * /path/.finf/file
78 * Resource fork:
79 * /path/.rsrc/file
80 */
81
82 // Layout of Finder info helper files (all fields big-endian)
83 struct finf_struct {
84 uint32 type;
85 uint32 creator;
86 uint16 flags;
87 uint8 pad0[22]; // total size: 32 bytes to match the size of FInfo+FXInfo
88 };
89
90 static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false)
91 {
92 dest[0] = 0;
93
94 // Get pointer to last component of path
95 const char *last_part = FilePart((char *)src);
96
97 // Copy everything before
98 strncpy(dest, src, last_part-src);
99 dest[last_part-src] = 0;
100
101 // Add additional component
102 AddPart(dest, (char *)add, MAX_PATH_LENGTH);
103
104 // Add last component
105 if (!only_dir)
106 AddPart(dest, (char *)last_part, MAX_PATH_LENGTH);
107 }
108
109 static int create_helper_dir(const char *path, const char *add)
110 {
111 char helper_dir[MAX_PATH_LENGTH];
112 make_helper_path(path, helper_dir, add, true);
113 return mkdir(helper_dir, 0777);
114 }
115
116 static int open_helper(const char *path, const char *add, int flag)
117 {
118 char helper_path[MAX_PATH_LENGTH];
119 make_helper_path(path, helper_path, add);
120
121 if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY)
122 flag |= O_CREAT;
123 int fd = open(helper_path, flag, 0666);
124 if (fd < 0) {
125 if (errno == ENOENT && (flag & O_CREAT)) {
126 // One path component was missing, probably the helper
127 // directory. Try to create it and re-open the file.
128 int ret = create_helper_dir(path, add);
129 if (ret < 0)
130 return ret;
131 fd = open(helper_path, flag, 0666);
132 }
133 }
134 return fd;
135 }
136
137 static int open_finf(const char *path, int flag)
138 {
139 return open_helper(path, ".finf/", flag);
140 }
141
142 static int open_rsrc(const char *path, int flag)
143 {
144 return open_helper(path, ".rsrc/", flag);
145 }
146
147
148 /*
149 * Get/set finder type/creator for file specified by full path
150 */
151
152 struct ext2type {
153 const char *ext;
154 uint32 type;
155 uint32 creator;
156 };
157
158 static const ext2type e2t_translation[] = {
159 {".Z", 'ZIVM', 'LZIV'},
160 {".gz", 'Gzip', 'Gzip'},
161 {".hqx", 'TEXT', 'SITx'},
162 {".pdf", 'PDF ', 'CARO'},
163 {".ps", 'TEXT', 'ttxt'},
164 {".sit", 'SIT!', 'SITx'},
165 {".tar", 'TARF', 'TAR '},
166 {".uu", 'TEXT', 'SITx'},
167 {".uue", 'TEXT', 'SITx'},
168 {".zip", 'ZIP ', 'ZIP '},
169 {".8svx", '8SVX', 'SNDM'},
170 {".aifc", 'AIFC', 'TVOD'},
171 {".aiff", 'AIFF', 'TVOD'},
172 {".au", 'ULAW', 'TVOD'},
173 {".mid", 'MIDI', 'TVOD'},
174 {".midi", 'MIDI', 'TVOD'},
175 {".mp2", 'MPG ', 'TVOD'},
176 {".mp3", 'MPG ', 'TVOD'},
177 {".wav", 'WAVE', 'TVOD'},
178 {".bmp", 'BMPf', 'ogle'},
179 {".gif", 'GIFf', 'ogle'},
180 {".lbm", 'ILBM', 'GKON'},
181 {".ilbm", 'ILBM', 'GKON'},
182 {".jpg", 'JPEG', 'ogle'},
183 {".jpeg", 'JPEG', 'ogle'},
184 {".pict", 'PICT', 'ogle'},
185 {".png", 'PNGf', 'ogle'},
186 {".sgi", '.SGI', 'ogle'},
187 {".tga", 'TPIC', 'ogle'},
188 {".tif", 'TIFF', 'ogle'},
189 {".tiff", 'TIFF', 'ogle'},
190 {".html", 'TEXT', 'MOSS'},
191 {".txt", 'TEXT', 'ttxt'},
192 {".rtf", 'TEXT', 'MSWD'},
193 {".c", 'TEXT', 'R*ch'},
194 {".C", 'TEXT', 'R*ch'},
195 {".cc", 'TEXT', 'R*ch'},
196 {".cpp", 'TEXT', 'R*ch'},
197 {".cxx", 'TEXT', 'R*ch'},
198 {".h", 'TEXT', 'R*ch'},
199 {".hh", 'TEXT', 'R*ch'},
200 {".hpp", 'TEXT', 'R*ch'},
201 {".hxx", 'TEXT', 'R*ch'},
202 {".s", 'TEXT', 'R*ch'},
203 {".S", 'TEXT', 'R*ch'},
204 {".i", 'TEXT', 'R*ch'},
205 {".mpg", 'MPEG', 'TVOD'},
206 {".mpeg", 'MPEG', 'TVOD'},
207 {".mov", 'MooV', 'TVOD'},
208 {".fli", 'FLI ', 'TVOD'},
209 {".avi", 'VfW ', 'TVOD'},
210 {NULL, 0, 0} // End marker
211 };
212
213 void get_finder_type(const char *path, uint32 &type, uint32 &creator)
214 {
215 type = 0;
216 creator = 0;
217
218 // Open Finder info file
219 int fd = open_finf(path, O_RDONLY);
220 if (fd >= 0) {
221
222 // Read file
223 finf_struct finf;
224 if (read(fd, &finf, sizeof(finf_struct)) >= 8) {
225
226 // Type/creator are in Finder info file, return them
227 type = ntohl(finf.type);
228 creator = ntohl(finf.creator);
229 close(fd);
230 return;
231 }
232 close(fd);
233 }
234
235 // No Finder info file, translate file name extension to MacOS type/creator
236 int path_len = strlen(path);
237 for (int i=0; e2t_translation[i].ext; i++) {
238 int ext_len = strlen(e2t_translation[i].ext);
239 if (path_len < ext_len)
240 continue;
241 if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) {
242 type = e2t_translation[i].type;
243 creator = e2t_translation[i].creator;
244 break;
245 }
246 }
247 }
248
249 void set_finder_type(const char *path, uint32 type, uint32 creator)
250 {
251 // Open Finder info file
252 int fd = open_finf(path, O_RDWR);
253 if (fd < 0)
254 return;
255
256 // Read file
257 finf_struct finf;
258 finf.flags = DEFAULT_FINDER_FLAGS;
259 memset(&finf, 0, sizeof(finf_struct));
260 read(fd, &finf, sizeof(finf_struct));
261
262 // Set Finder flags
263 finf.type = htonl(type);
264 finf.creator = htonl(creator);
265
266 // Update file
267 lseek(fd, 0, SEEK_SET);
268 write(fd, &finf, sizeof(finf_struct));
269 close(fd);
270 }
271
272
273 /*
274 * Get/set finder flags for file/dir specified by full path
275 */
276
277 void get_finder_flags(const char *path, uint16 &flags)
278 {
279 flags = DEFAULT_FINDER_FLAGS; // Default
280
281 // Open Finder info file
282 int fd = open_finf(path, O_RDONLY);
283 if (fd < 0)
284 return;
285
286 // Read Finder flags
287 finf_struct finf;
288 if (read(fd, &finf, sizeof(finf_struct)) >= 10)
289 flags = ntohs(finf.flags);
290
291 // Close file
292 close(fd);
293 }
294
295 void set_finder_flags(const char *path, uint16 flags)
296 {
297 // Open Finder info file
298 int fd = open_finf(path, O_RDWR);
299 if (fd < 0)
300 return;
301
302 // Read file
303 finf_struct finf;
304 memset(&finf, 0, sizeof(finf_struct));
305 finf.flags = DEFAULT_FINDER_FLAGS;
306 read(fd, &finf, sizeof(finf_struct));
307
308 // Set Finder flags
309 finf.flags = htons(flags);
310
311 // Update file
312 lseek(fd, 0, SEEK_SET);
313 write(fd, &finf, sizeof(finf_struct));
314 close(fd);
315 }
316
317
318 /*
319 * Resource fork emulation functions
320 */
321
322 uint32 get_rfork_size(const char *path)
323 {
324 // Open resource file
325 int fd = open_rsrc(path, O_RDONLY);
326 if (fd < 0)
327 return 0;
328
329 // Get size
330 off_t size = lseek(fd, 0, SEEK_END);
331
332 // Close file and return size
333 close(fd);
334 return size < 0 ? 0 : size;
335 }
336
337 int open_rfork(const char *path, int flag)
338 {
339 return open_rsrc(path, flag);
340 }
341
342 void close_rfork(const char *path, int fd)
343 {
344 close(fd);
345 }
346
347
348 /*
349 * Read "length" bytes from file to "buffer",
350 * returns number of bytes read (or -1 on error)
351 */
352
353 ssize_t extfs_read(int fd, void *buffer, size_t length)
354 {
355 return read(fd, buffer, length);
356 }
357
358
359 /*
360 * Write "length" bytes from "buffer" to file,
361 * returns number of bytes written (or -1 on error)
362 */
363
364 ssize_t extfs_write(int fd, void *buffer, size_t length)
365 {
366 return write(fd, buffer, length);
367 }
368
369
370 /*
371 * Remove file/directory (and associated helper files),
372 * returns false on error (and sets errno)
373 */
374
375 bool extfs_remove(const char *path)
376 {
377 // Remove helpers first, don't complain if this fails
378 char helper_path[MAX_PATH_LENGTH];
379 make_helper_path(path, helper_path, ".finf/", false);
380 remove(helper_path);
381 make_helper_path(path, helper_path, ".rsrc/", false);
382 remove(helper_path);
383
384 // Now remove file or directory (and helper directories in the directory)
385 if (remove(path) < 0) {
386 if (errno == EISDIR || errno == ENOTEMPTY) {
387 helper_path[0] = 0;
388 strncpy(helper_path, path, MAX_PATH_LENGTH-1);
389 add_path_component(helper_path, ".finf");
390 rmdir(helper_path);
391 helper_path[0] = 0;
392 strncpy(helper_path, path, MAX_PATH_LENGTH-1);
393 add_path_component(helper_path, ".rsrc");
394 rmdir(helper_path);
395 return rmdir(path) == 0;
396 } else
397 return false;
398 }
399 return true;
400 }
401
402
403 /*
404 * Rename/move file/directory (and associated helper files),
405 * returns false on error (and sets errno)
406 */
407
408 bool extfs_rename(const char *old_path, const char *new_path)
409 {
410 // Rename helpers first, don't complain if this fails
411 char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH];
412 make_helper_path(old_path, old_helper_path, ".finf/", false);
413 make_helper_path(new_path, new_helper_path, ".finf/", false);
414 create_helper_dir(new_path, ".finf/");
415 rename(old_helper_path, new_helper_path);
416 make_helper_path(old_path, old_helper_path, ".rsrc/", false);
417 make_helper_path(new_path, new_helper_path, ".rsrc/", false);
418 create_helper_dir(new_path, ".rsrc/");
419 rename(old_helper_path, new_helper_path);
420
421 // Now rename file
422 return rename(old_path, new_path) == 0;
423 }
424
425
426 /*
427 * ftruncate() is missing from libnix
428 */
429
430 extern unsigned long *__stdfiledes;
431
432 int ftruncate(int fd, off_t size)
433 {
434 if (SetFileSize(__stdfiledes[fd], size, OFFSET_BEGINNING) < 0)
435 return -1;
436 else
437 return 0;
438 }