ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/extfs_unix.cpp
(Generate patch)

Comparing BasiliskII/src/Unix/extfs_unix.cpp (file contents):
Revision 1.4 by cebix, 1999-10-22T13:57:05Z vs.
Revision 1.17 by cebix, 2001-03-31T14:32:00Z

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines