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.2 by cebix, 1999-10-20T17:23:56Z vs.
Revision 1.11 by cebix, 2000-01-21T13:47:04Z

# Line 57 | Line 57 | void extfs_exit(void)
57  
58  
59   /*
60 + *  Add component to path name
61 + */
62 +
63 + void add_path_component(char *path, const char *component)
64 + {
65 +        int l = strlen(path);
66 +        if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') {
67 +                path[l] = '/';
68 +                path[l+1] = 0;
69 +        }
70 +        strncat(path, component, MAX_PATH_LENGTH-1);
71 + }
72 +
73 +
74 + /*
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 +
83 + // Layout of Finder info helper files (all fields big-endian)
84 + struct finf_struct {
85 +        uint32 type;
86 +        uint32 creator;
87 +        uint16 flags;
88 +        uint8 pad0[22]; // total size: 32 bytes to match the size of FInfo+FXInfo
89 + };
90 +
91 + static void make_helper_path(const char *src, char *dest, const char *add, bool only_dir = false)
92 + {
93 +        dest[0] = 0;
94 +
95 +        // Get pointer to last component of path
96 +        const char *last_part = strrchr(src, '/');
97 +        if (last_part)
98 +                last_part++;
99 +        else
100 +                last_part = src;
101 +
102 +        // Copy everything before
103 +        strncpy(dest, src, last_part-src);
104 +        dest[last_part-src] = 0;
105 +
106 +        // Add additional component
107 +        strncat(dest, add, MAX_PATH_LENGTH-1);
108 +
109 +        // Add last component
110 +        if (!only_dir)
111 +                strncat(dest, last_part, MAX_PATH_LENGTH-1);
112 + }
113 +
114 + static int create_helper_dir(const char *path, const char *add)
115 + {
116 +        char helper_dir[MAX_PATH_LENGTH];
117 +        make_helper_path(path, helper_dir, add, true);
118 +        return mkdir(helper_dir, 0777);
119 + }
120 +
121 + static int open_helper(const char *path, const char *add, int flag)
122 + {
123 +        char helper_path[MAX_PATH_LENGTH];
124 +        make_helper_path(path, helper_path, add);
125 +
126 +        if ((flag & O_ACCMODE) == O_RDWR || (flag & O_ACCMODE) == O_WRONLY)
127 +                flag |= O_CREAT;
128 +        int fd = open(helper_path, flag, 0666);
129 +        if (fd < 0) {
130 +                if (errno == ENOENT && (flag & O_CREAT)) {
131 +                        // One path component was missing, probably the helper
132 +                        // directory. Try to create it and re-open the file.
133 +                        int ret = create_helper_dir(path, add);
134 +                        if (ret < 0)
135 +                                return ret;
136 +                        fd = open(helper_path, flag, 0666);
137 +                }
138 +        }
139 +        return fd;
140 + }
141 +
142 + static int open_finf(const char *path, int flag)
143 + {
144 +        return open_helper(path, ".finf/", flag);
145 + }
146 +
147 + static int open_rsrc(const char *path, int flag)
148 + {
149 +        return open_helper(path, ".rsrc/", flag);
150 + }
151 +
152 +
153 + /*
154   *  Get/set finder type/creator for file specified by full path
155   */
156  
# Line 126 | Line 220 | void get_finder_type(const char *path, u
220          type = 0;
221          creator = 0;
222  
223 <        // Translate file name extension to MacOS type/creator
223 >        // Open Finder info file
224 >        int fd = open_finf(path, O_RDONLY);
225 >        if (fd >= 0) {
226 >
227 >                // Read file
228 >                finf_struct finf;
229 >                if (read(fd, &finf, sizeof(finf_struct)) >= 8) {
230 >
231 >                        // Type/creator are in Finder info file, return them
232 >                        type = ntohl(finf.type);
233 >                        creator = ntohl(finf.creator);
234 >                        close(fd);
235 >                        return;
236 >                }
237 >                close(fd);
238 >        }
239 >
240 >        // No Finder info file, translate file name extension to MacOS type/creator
241          int path_len = strlen(path);
242          for (int i=0; e2t_translation[i].ext; i++) {
243                  int ext_len = strlen(e2t_translation[i].ext);
# Line 142 | Line 253 | void get_finder_type(const char *path, u
253  
254   void set_finder_type(const char *path, uint32 type, uint32 creator)
255   {
256 +        // Open Finder info file
257 +        int fd = open_finf(path, O_RDWR);
258 +        if (fd < 0)
259 +                return;
260 +
261 +        // Read file
262 +        finf_struct finf;
263 +        finf.flags = DEFAULT_FINDER_FLAGS;
264 +        memset(&finf, 0, sizeof(finf_struct));
265 +        read(fd, &finf, sizeof(finf_struct));
266 +
267 +        // Set Finder flags
268 +        finf.type = htonl(type);
269 +        finf.creator = htonl(creator);
270 +
271 +        // Update file
272 +        lseek(fd, 0, SEEK_SET);
273 +        write(fd, &finf, sizeof(finf_struct));
274 +        close(fd);
275   }
276  
277  
278   /*
279 < *  Get/set finder flags for file/dir specified by full path (MACOS:HFS_FLAGS attribute)
279 > *  Get/set finder flags for file/dir specified by full path
280   */
281  
282   void get_finder_flags(const char *path, uint16 &flags)
283   {
284          flags = DEFAULT_FINDER_FLAGS;   // Default
285 +
286 +        // Open Finder info file
287 +        int fd = open_finf(path, O_RDONLY);
288 +        if (fd < 0)
289 +                return;
290 +
291 +        // Read Finder flags
292 +        finf_struct finf;
293 +        if (read(fd, &finf, sizeof(finf_struct)) >= 10)
294 +                flags = ntohs(finf.flags);
295 +
296 +        // Close file
297 +        close(fd);
298   }
299  
300   void set_finder_flags(const char *path, uint16 flags)
301   {
302 +        // Open Finder info file
303 +        int fd = open_finf(path, O_RDWR);
304 +        if (fd < 0)
305 +                return;
306 +
307 +        // Read file
308 +        finf_struct finf;
309 +        memset(&finf, 0, sizeof(finf_struct));
310 +        finf.flags = DEFAULT_FINDER_FLAGS;
311 +        read(fd, &finf, sizeof(finf_struct));
312 +
313 +        // Set Finder flags
314 +        finf.flags = htons(flags);
315 +
316 +        // Update file
317 +        lseek(fd, 0, SEEK_SET);
318 +        write(fd, &finf, sizeof(finf_struct));
319 +        close(fd);
320   }
321  
322  
# Line 165 | Line 326 | void set_finder_flags(const char *path,
326  
327   uint32 get_rfork_size(const char *path)
328   {
329 <        return 0;
329 >        // Open resource file
330 >        int fd = open_rsrc(path, O_RDONLY);
331 >        if (fd < 0)
332 >                return 0;
333 >
334 >        // Get size
335 >        off_t size = lseek(fd, 0, SEEK_END);
336 >        
337 >        // Close file and return size
338 >        close(fd);
339 >        return size < 0 ? 0 : size;
340   }
341  
342   int open_rfork(const char *path, int flag)
343   {
344 <        return -1;
344 >        return open_rsrc(path, flag);
345   }
346  
347   void close_rfork(const char *path, int fd)
348   {
349 +        close(fd);
350   }
351  
352  
353   /*
354   *  Read "length" bytes from file to "buffer",
355 < *  returns number of bytes read (or 0)
355 > *  returns number of bytes read (or -1 on error)
356   */
357  
358 < size_t extfs_read(int fd, void *buffer, size_t length)
358 > ssize_t extfs_read(int fd, void *buffer, size_t length)
359   {
188        errno = 0;
360          return read(fd, buffer, length);
361   }
362  
363  
364   /*
365   *  Write "length" bytes from "buffer" to file,
366 < *  returns number of bytes written (or 0)
366 > *  returns number of bytes written (or -1 on error)
367   */
368  
369 < size_t extfs_write(int fd, void *buffer, size_t length)
369 > ssize_t extfs_write(int fd, void *buffer, size_t length)
370   {
200        errno = 0;
371          return write(fd, buffer, length);
372   }
373 +
374 +
375 + /*
376 + *  Remove file/directory (and associated helper files),
377 + *  returns false on error (and sets errno)
378 + */
379 +
380 + bool extfs_remove(const char *path)
381 + {
382 +        // Remove helpers first, don't complain if this fails
383 +        char helper_path[MAX_PATH_LENGTH];
384 +        make_helper_path(path, helper_path, ".finf/", false);
385 +        remove(helper_path);
386 +        make_helper_path(path, helper_path, ".rsrc/", false);
387 +        remove(helper_path);
388 +
389 +        // Now remove file or directory (and helper directories in the directory)
390 +        if (remove(path) < 0) {
391 +                if (errno == EISDIR || errno == ENOTEMPTY) {
392 +                        helper_path[0] = 0;
393 +                        strncpy(helper_path, path, MAX_PATH_LENGTH-1);
394 +                        add_path_component(helper_path, ".finf");
395 +                        rmdir(helper_path);
396 +                        helper_path[0] = 0;
397 +                        strncpy(helper_path, path, MAX_PATH_LENGTH-1);
398 +                        add_path_component(helper_path, ".rsrc");
399 +                        rmdir(helper_path);
400 +                        return rmdir(path) == 0;
401 +                } else
402 +                        return false;
403 +        }
404 +        return true;
405 + }
406 +
407 +
408 + /*
409 + *  Rename/move file/directory (and associated helper files),
410 + *  returns false on error (and sets errno)
411 + */
412 +
413 + bool extfs_rename(const char *old_path, const char *new_path)
414 + {
415 +        // Rename helpers first, don't complain if this fails
416 +        char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH];
417 +        make_helper_path(old_path, old_helper_path, ".finf/", false);
418 +        make_helper_path(new_path, new_helper_path, ".finf/", false);
419 +        create_helper_dir(new_path, ".finf/");
420 +        rename(old_helper_path, new_helper_path);
421 +        make_helper_path(old_path, old_helper_path, ".rsrc/", false);
422 +        make_helper_path(new_path, new_helper_path, ".rsrc/", false);
423 +        create_helper_dir(new_path, ".rsrc/");
424 +        rename(old_helper_path, new_helper_path);
425 +
426 +        // Now rename file
427 +        return rename(old_path, new_path) == 0;
428 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines