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, 4 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

# 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 * The .finf files store a FInfo/DInfo, followed by a FXInfo/DXInfo
82 * (16+16 bytes)
83 */
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 if (helper_dir[strlen(helper_dir) - 1] == '/') // Remove trailing "/"
109 helper_dir[strlen(helper_dir) - 1] = 0;
110 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 if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY)
119 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 {".htm", 'TEXT', 'MOSS'},
188 {".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 {".qxd", 'XDOC', 'XPR3'},
209 {".hfv", 'DDim', 'ddsk'},
210 {".dsk", 'DDim', 'ddsk'},
211 {".img", 'rohd', 'ddsk'},
212 {NULL, 0, 0} // End marker
213 };
214
215 void get_finfo(const char *path, uint32 finfo, uint32 fxinfo)
216 {
217 // 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
224 // Read Finder info file
225 int fd = open_finf(path, O_RDONLY);
226 if (fd >= 0) {
227 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 return;
233 }
234
235 // No Finder info file, translate file name extension to MacOS type/creator
236 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 }
249 }
250 }
251
252 void set_finfo(const char *path, uint32 finfo, uint32 fxinfo)
253 {
254 // Open Finder info file
255 int fd = open_finf(path, O_RDWR);
256 if (fd < 0)
257 return;
258
259 // Write file
260 write(fd, Mac2HostAddr(finfo), SIZEOF_FInfo);
261 if (fxinfo)
262 write(fd, Mac2HostAddr(fxinfo), SIZEOF_FXInfo);
263 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 * returns number of bytes read (or -1 on error)
300 */
301
302 ssize_t extfs_read(int fd, void *buffer, size_t length)
303 {
304 return read(fd, buffer, length);
305 }
306
307
308 /*
309 * Write "length" bytes from "buffer" to file,
310 * returns number of bytes written (or -1 on error)
311 */
312
313 ssize_t extfs_write(int fd, void *buffer, size_t length)
314 {
315 return write(fd, buffer, length);
316 }
317
318
319 /*
320 * 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 // Now remove file or directory (and helper directories in the directory)
334 if (remove(path) < 0) {
335 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 return rmdir(path) == 0;
345 } else
346 return false;
347 }
348 return true;
349 }
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 }
373
374
375 /*
376 * 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 }