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.8 by cebix, 1999-11-08T17:00:13Z

# 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 > *  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 >        uint16 pad0;
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  
# Line 141 | 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)) == sizeof(finf_struct)) {
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 157 | 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 = {0, 0, DEFAULT_FINDER_FLAGS, 0};
263 +        read(fd, &finf, sizeof(finf_struct));
264 +
265 +        // Set Finder flags
266 +        finf.type = htonl(type);
267 +        finf.creator = htonl(creator);
268 +
269 +        // Update file
270 +        lseek(fd, 0, SEEK_SET);
271 +        write(fd, &finf, sizeof(finf_struct));
272 +        close(fd);
273   }
274  
275  
276   /*
277 < *  Get/set finder flags for file/dir specified by full path (MACOS:HFS_FLAGS attribute)
277 > *  Get/set finder flags for file/dir specified by full path
278   */
279  
280   void get_finder_flags(const char *path, uint16 &flags)
281   {
282          flags = DEFAULT_FINDER_FLAGS;   // Default
283 +
284 +        // Open Finder info file
285 +        int fd = open_finf(path, O_RDONLY);
286 +        if (fd < 0)
287 +                return;
288 +
289 +        // Read Finder flags
290 +        finf_struct finf;
291 +        if (read(fd, &finf, sizeof(finf_struct)) == sizeof(finf_struct))
292 +                flags = ntohs(finf.flags);
293 +
294 +        // Close file
295 +        close(fd);
296   }
297  
298   void set_finder_flags(const char *path, uint16 flags)
299   {
300 +        // Open Finder info file
301 +        int fd = open_finf(path, O_RDWR);
302 +        if (fd < 0)
303 +                return;
304 +
305 +        // Read file
306 +        finf_struct finf = {0, 0, DEFAULT_FINDER_FLAGS, 0};
307 +        read(fd, &finf, sizeof(finf_struct));
308 +
309 +        // Set Finder flags
310 +        finf.flags = htons(flags);
311 +
312 +        // Update file
313 +        lseek(fd, 0, SEEK_SET);
314 +        write(fd, &finf, sizeof(finf_struct));
315 +        close(fd);
316   }
317  
318  
# Line 180 | Line 322 | void set_finder_flags(const char *path,
322  
323   uint32 get_rfork_size(const char *path)
324   {
325 <        return 0;
325 >        // Open resource file
326 >        int fd = open_rsrc(path, O_RDONLY);
327 >        if (fd < 0)
328 >                return 0;
329 >
330 >        // Get size
331 >        off_t size = lseek(fd, 0, SEEK_END);
332 >        
333 >        // Close file and return size
334 >        close(fd);
335 >        return size < 0 ? 0 : size;
336   }
337  
338   int open_rfork(const char *path, int flag)
339   {
340 <        return -1;
340 >        return open_rsrc(path, flag);
341   }
342  
343   void close_rfork(const char *path, int fd)
344   {
345 +        close(fd);
346   }
347  
348  
# Line 215 | Line 368 | size_t extfs_write(int fd, void *buffer,
368          errno = 0;
369          return write(fd, buffer, length);
370   }
371 +
372 +
373 + /*
374 + *  Remove file/directory (and associated helper files),
375 + *  returns false on error (and sets errno)
376 + */
377 +
378 + bool extfs_remove(const char *path)
379 + {
380 +        // Remove helpers first, don't complain if this fails
381 +        char helper_path[MAX_PATH_LENGTH];
382 +        make_helper_path(path, helper_path, ".finf/", false);
383 +        remove(helper_path);
384 +        make_helper_path(path, helper_path, ".rsrc/", false);
385 +        remove(helper_path);
386 +
387 +        // Now remove file or directory
388 +        if (remove(path) < 0) {
389 +                if (errno == EISDIR)
390 +                        return rmdir(path) == 0;
391 +                else
392 +                        return false;
393 +        }
394 +        return true;
395 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines