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

# User Rev Content
1 cebix 1.1 /*
2     * extfs_amiga.cpp - MacOS file system for access native file system access, AmigaOS specific stuff
3     *
4 cebix 1.7 * Basilisk II (C) 1997-2000 Christian Bauer
5 cebix 1.1 *
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 cebix 1.6 uint8 pad0[22]; // total size: 32 bytes to match the size of FInfo+FXInfo
88 cebix 1.1 };
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 cebix 1.2 if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY)
122 cebix 1.1 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 cebix 1.6 if (read(fd, &finf, sizeof(finf_struct)) >= 8) {
225 cebix 1.1
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 cebix 1.6 finf_struct finf;
258     finf.flags = DEFAULT_FINDER_FLAGS;
259     memset(&finf, 0, sizeof(finf_struct));
260 cebix 1.1 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 cebix 1.6 if (read(fd, &finf, sizeof(finf_struct)) >= 10)
289 cebix 1.1 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 cebix 1.6 finf_struct finf;
304     memset(&finf, 0, sizeof(finf_struct));
305     finf.flags = DEFAULT_FINDER_FLAGS;
306 cebix 1.1 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 cebix 1.5 * returns number of bytes read (or -1 on error)
351 cebix 1.1 */
352    
353 cebix 1.5 ssize_t extfs_read(int fd, void *buffer, size_t length)
354 cebix 1.1 {
355     return read(fd, buffer, length);
356     }
357    
358    
359     /*
360     * Write "length" bytes from "buffer" to file,
361 cebix 1.5 * returns number of bytes written (or -1 on error)
362 cebix 1.1 */
363    
364 cebix 1.5 ssize_t extfs_write(int fd, void *buffer, size_t length)
365 cebix 1.1 {
366     return write(fd, buffer, length);
367     }
368    
369    
370     /*
371 cebix 1.3 * 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 cebix 1.4 // Now remove file or directory (and helper directories in the directory)
385 cebix 1.3 if (remove(path) < 0) {
386 cebix 1.4 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 cebix 1.3 return rmdir(path) == 0;
396 cebix 1.4 } else
397 cebix 1.3 return false;
398     }
399     return true;
400 cebix 1.4 }
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 cebix 1.3 }
424    
425    
426     /*
427 cebix 1.1 * 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     }