ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/extfs_amiga.cpp
Revision: 1.8
Committed: 2000-07-21T18:01:06Z (24 years, 3 months ago) by cebix
Branch: MAIN
Changes since 1.7: +40 -91 lines
Log Message:
- extfs: replaced get/set_finder_*() functions by get/set_finfo(), helper
  files now store complete FInfo/FXInfo

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 cebix 1.8 *
81     * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo
82     * (16+16 bytes)
83 cebix 1.1 */
84    
85     static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false)
86     {
87     dest[0] = 0;
88    
89     // Get pointer to last component of path
90     const char *last_part = FilePart((char *)src);
91    
92     // Copy everything before
93     strncpy(dest, src, last_part-src);
94     dest[last_part-src] = 0;
95    
96     // Add additional component
97     AddPart(dest, (char *)add, MAX_PATH_LENGTH);
98    
99     // Add last component
100     if (!only_dir)
101     AddPart(dest, (char *)last_part, MAX_PATH_LENGTH);
102     }
103    
104     static int create_helper_dir(const char *path, const char *add)
105     {
106     char helper_dir[MAX_PATH_LENGTH];
107     make_helper_path(path, helper_dir, add, true);
108 cebix 1.8 if (helper_dir[strlen(helper_dir) - 1] == '/') // Remove trailing "/"
109     helper_dir[strlen(helper_dir) - 1] = 0;
110 cebix 1.1 return mkdir(helper_dir, 0777);
111     }
112    
113     static int open_helper(const char *path, const char *add, int flag)
114     {
115     char helper_path[MAX_PATH_LENGTH];
116     make_helper_path(path, helper_path, add);
117    
118 cebix 1.2 if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY)
119 cebix 1.1 flag |= O_CREAT;
120     int fd = open(helper_path, flag, 0666);
121     if (fd < 0) {
122     if (errno == ENOENT && (flag & O_CREAT)) {
123     // One path component was missing, probably the helper
124     // directory. Try to create it and re-open the file.
125     int ret = create_helper_dir(path, add);
126     if (ret < 0)
127     return ret;
128     fd = open(helper_path, flag, 0666);
129     }
130     }
131     return fd;
132     }
133    
134     static int open_finf(const char *path, int flag)
135     {
136     return open_helper(path, ".finf/", flag);
137     }
138    
139     static int open_rsrc(const char *path, int flag)
140     {
141     return open_helper(path, ".rsrc/", flag);
142     }
143    
144    
145     /*
146     * Get/set finder type/creator for file specified by full path
147     */
148    
149     struct ext2type {
150     const char *ext;
151     uint32 type;
152     uint32 creator;
153     };
154    
155     static const ext2type e2t_translation[] = {
156     {".Z", 'ZIVM', 'LZIV'},
157     {".gz", 'Gzip', 'Gzip'},
158     {".hqx", 'TEXT', 'SITx'},
159     {".pdf", 'PDF ', 'CARO'},
160     {".ps", 'TEXT', 'ttxt'},
161     {".sit", 'SIT!', 'SITx'},
162     {".tar", 'TARF', 'TAR '},
163     {".uu", 'TEXT', 'SITx'},
164     {".uue", 'TEXT', 'SITx'},
165     {".zip", 'ZIP ', 'ZIP '},
166     {".8svx", '8SVX', 'SNDM'},
167     {".aifc", 'AIFC', 'TVOD'},
168     {".aiff", 'AIFF', 'TVOD'},
169     {".au", 'ULAW', 'TVOD'},
170     {".mid", 'MIDI', 'TVOD'},
171     {".midi", 'MIDI', 'TVOD'},
172     {".mp2", 'MPG ', 'TVOD'},
173     {".mp3", 'MPG ', 'TVOD'},
174     {".wav", 'WAVE', 'TVOD'},
175     {".bmp", 'BMPf', 'ogle'},
176     {".gif", 'GIFf', 'ogle'},
177     {".lbm", 'ILBM', 'GKON'},
178     {".ilbm", 'ILBM', 'GKON'},
179     {".jpg", 'JPEG', 'ogle'},
180     {".jpeg", 'JPEG', 'ogle'},
181     {".pict", 'PICT', 'ogle'},
182     {".png", 'PNGf', 'ogle'},
183     {".sgi", '.SGI', 'ogle'},
184     {".tga", 'TPIC', 'ogle'},
185     {".tif", 'TIFF', 'ogle'},
186     {".tiff", 'TIFF', 'ogle'},
187 cebix 1.8 {".htm", 'TEXT', 'MOSS'},
188 cebix 1.1 {".html", 'TEXT', 'MOSS'},
189     {".txt", 'TEXT', 'ttxt'},
190     {".rtf", 'TEXT', 'MSWD'},
191     {".c", 'TEXT', 'R*ch'},
192     {".C", 'TEXT', 'R*ch'},
193     {".cc", 'TEXT', 'R*ch'},
194     {".cpp", 'TEXT', 'R*ch'},
195     {".cxx", 'TEXT', 'R*ch'},
196     {".h", 'TEXT', 'R*ch'},
197     {".hh", 'TEXT', 'R*ch'},
198     {".hpp", 'TEXT', 'R*ch'},
199     {".hxx", 'TEXT', 'R*ch'},
200     {".s", 'TEXT', 'R*ch'},
201     {".S", 'TEXT', 'R*ch'},
202     {".i", 'TEXT', 'R*ch'},
203     {".mpg", 'MPEG', 'TVOD'},
204     {".mpeg", 'MPEG', 'TVOD'},
205     {".mov", 'MooV', 'TVOD'},
206     {".fli", 'FLI ', 'TVOD'},
207     {".avi", 'VfW ', 'TVOD'},
208 cebix 1.8 {".qxd", 'XDOC', 'XPR3'},
209     {".hfv", 'DDim', 'ddsk'},
210     {".dsk", 'DDim', 'ddsk'},
211     {".img", 'rohd', 'ddsk'},
212 cebix 1.1 {NULL, 0, 0} // End marker
213     };
214    
215 cebix 1.8 void get_finfo(const char *path, uint32 finfo, uint32 fxinfo)
216 cebix 1.1 {
217 cebix 1.8 // Set default finder info
218     Mac_memset(finfo, 0, SIZEOF_FInfo);
219     if (fxinfo)
220     Mac_memset(fxinfo, 0, SIZEOF_FXInfo);
221     WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS);
222     WriteMacInt32(finfo + fdLocation, (uint32)-1);
223 cebix 1.1
224 cebix 1.8 // Read Finder info file
225 cebix 1.1 int fd = open_finf(path, O_RDONLY);
226     if (fd >= 0) {
227 cebix 1.8 ssize_t actual = read(fd, Mac2HostAddr(finfo), SIZEOF_FInfo);
228     if (fxinfo)
229     actual += read(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo);
230     close(fd);
231     if (actual >= SIZEOF_FInfo)
232 cebix 1.1 return;
233     }
234    
235     // No Finder info file, translate file name extension to MacOS type/creator
236 cebix 1.8 struct stat st;
237     if (stat(path, &st) == 0 && !S_ISDIR(st.st_mode)) {
238     int path_len = strlen(path);
239     for (int i=0; e2t_translation[i].ext; i++) {
240     int ext_len = strlen(e2t_translation[i].ext);
241     if (path_len < ext_len)
242     continue;
243     if (!strcasecmp(path + path_len - ext_len, e2t_translation[i].ext)) {
244     WriteMacInt32(finfo + fdType, e2t_translation[i].type);
245     WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator);
246     break;
247     }
248 cebix 1.1 }
249     }
250     }
251    
252 cebix 1.8 void set_finfo(const char *path, uint32 finfo, uint32 fxinfo)
253 cebix 1.1 {
254     // Open Finder info file
255     int fd = open_finf(path, O_RDWR);
256     if (fd < 0)
257     return;
258    
259 cebix 1.8 // Write file
260     write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo);
261     if (fxinfo)
262     write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo);
263 cebix 1.1 close(fd);
264     }
265    
266    
267     /*
268     * Resource fork emulation functions
269     */
270    
271     uint32 get_rfork_size(const char *path)
272     {
273     // Open resource file
274     int fd = open_rsrc(path, O_RDONLY);
275     if (fd < 0)
276     return 0;
277    
278     // Get size
279     off_t size = lseek(fd, 0, SEEK_END);
280    
281     // Close file and return size
282     close(fd);
283     return size < 0 ? 0 : size;
284     }
285    
286     int open_rfork(const char *path, int flag)
287     {
288     return open_rsrc(path, flag);
289     }
290    
291     void close_rfork(const char *path, int fd)
292     {
293     close(fd);
294     }
295    
296    
297     /*
298     * Read "length" bytes from file to "buffer",
299 cebix 1.5 * returns number of bytes read (or -1 on error)
300 cebix 1.1 */
301    
302 cebix 1.5 ssize_t extfs_read(int fd, void *buffer, size_t length)
303 cebix 1.1 {
304     return read(fd, buffer, length);
305     }
306    
307    
308     /*
309     * Write "length" bytes from "buffer" to file,
310 cebix 1.5 * returns number of bytes written (or -1 on error)
311 cebix 1.1 */
312    
313 cebix 1.5 ssize_t extfs_write(int fd, void *buffer, size_t length)
314 cebix 1.1 {
315     return write(fd, buffer, length);
316     }
317    
318    
319     /*
320 cebix 1.3 * Remove file/directory (and associated helper files),
321     * returns false on error (and sets errno)
322     */
323    
324     bool extfs_remove(const char *path)
325     {
326     // Remove helpers first, don't complain if this fails
327     char helper_path[MAX_PATH_LENGTH];
328     make_helper_path(path, helper_path, ".finf/", false);
329     remove(helper_path);
330     make_helper_path(path, helper_path, ".rsrc/", false);
331     remove(helper_path);
332    
333 cebix 1.4 // Now remove file or directory (and helper directories in the directory)
334 cebix 1.3 if (remove(path) < 0) {
335 cebix 1.4 if (errno == EISDIR || errno == ENOTEMPTY) {
336     helper_path[0] = 0;
337     strncpy(helper_path, path, MAX_PATH_LENGTH-1);
338     add_path_component(helper_path, ".finf");
339     rmdir(helper_path);
340     helper_path[0] = 0;
341     strncpy(helper_path, path, MAX_PATH_LENGTH-1);
342     add_path_component(helper_path, ".rsrc");
343     rmdir(helper_path);
344 cebix 1.3 return rmdir(path) == 0;
345 cebix 1.4 } else
346 cebix 1.3 return false;
347     }
348     return true;
349 cebix 1.4 }
350    
351    
352     /*
353     * Rename/move file/directory (and associated helper files),
354     * returns false on error (and sets errno)
355     */
356    
357     bool extfs_rename(const char *old_path, const char *new_path)
358     {
359     // Rename helpers first, don't complain if this fails
360     char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH];
361     make_helper_path(old_path, old_helper_path, ".finf/", false);
362     make_helper_path(new_path, new_helper_path, ".finf/", false);
363     create_helper_dir(new_path, ".finf/");
364     rename(old_helper_path, new_helper_path);
365     make_helper_path(old_path, old_helper_path, ".rsrc/", false);
366     make_helper_path(new_path, new_helper_path, ".rsrc/", false);
367     create_helper_dir(new_path, ".rsrc/");
368     rename(old_helper_path, new_helper_path);
369    
370     // Now rename file
371     return rename(old_path, new_path) == 0;
372 cebix 1.3 }
373    
374    
375     /*
376 cebix 1.1 * ftruncate() is missing from libnix
377     */
378    
379     extern unsigned long *__stdfiledes;
380    
381     int ftruncate(int fd, off_t size)
382     {
383     if (SetFileSize(__stdfiledes[fd], size, OFFSET_BEGINNING) < 0)
384     return -1;
385     else
386     return 0;
387     }