~ubuntu-branches/ubuntu/vivid/basilisk2/vivid

« back to all changes in this revision

Viewing changes to src/MacOSX/extfs_macosx.mm

  • Committer: Package Import Robot
  • Author(s): Jonas Smedegaard, Jonas Smedegaard, Jérémy Lal, Giulio Paci
  • Date: 2012-05-19 02:08:30 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120519020830-o59ui1wsfftg55m6
Tags: 0.9.20120331-1
* Upstream update

[ Jonas Smedegaard ]
* Drop local CDBS snippets: All included in main cdbs now.
* Use source format 3.0 (quilt), and stop including patchsys-quilt.mk.
  Stop build-depending on quilt, patchutils.
* Add full licensing header to debian/rules, and update copyright
  years.
* Add README.source (and drop outdated README.cdbs-tweaks).
* Refresh patches with shortening quilt options --no-index
  --no-timestamps -pab, and fix their path prefix.
* Rewrite copyright file using draft DEP-5 format.
* Update control file Vcs-* fields: Packaging moved to Git.
* Ease building with git-buildpackage:
  + Add gbp.conf, enabling pristine-tar and tag signing.
  + Git-ignore quilt .pc dir.
* Bump debhelper compat level to 7.
* Update Vcs-Browser field to use anonscm.debian.org.
* Add Giulio Paci and Jérémy Lal as uploaders, and permit Debian
  Maintainers to upload.

[ Jérémy Lal ]
* Drop patch 1002 to fix capitalized flag: corrected upstream.

[ Giulio Paci ]
* Restart package development.
  Closes: #662175.
* Add patches to fix compilation and documentation.
* Provide JIT flavor on supported architectures (i386 and amd64).
* Bump standards-version to 3.9.3.
* Update copyright file:
  + Adjust licenses now clarified/improved upstream.
* Update ChangeLog.cvs.
* Enable CDBS autogeneration of autotools files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *      $Id: extfs_macosx.mm,v 1.9 2007/01/24 02:37:06 asvitkine Exp $
3
 
 *
4
 
 *      extfs_macosx.mm - Access Mac OS X Finder and resource information (using Carbon calls).
5
 
 *                    Based on:
6
 
 *
7
 
 *  extfs_unix.cpp - MacOS file system for access native file system access, Unix specific stuff
8
 
 *
9
 
 *  Basilisk II (C) 1997-2005 Christian Bauer
10
 
 *
11
 
 *  This program is free software; you can redistribute it and/or modify
12
 
 *  it under the terms of the GNU General Public License as published by
13
 
 *  the Free Software Foundation; either version 2 of the License, or
14
 
 *  (at your option) any later version.
15
 
 *
16
 
 *  This program is distributed in the hope that it will be useful,
17
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 
 *  GNU General Public License for more details.
20
 
 *
21
 
 *  You should have received a copy of the GNU General Public License
22
 
 *  along with this program; if not, write to the Free Software
23
 
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 
 */
25
 
 
26
 
#include <sys/types.h>
27
 
#include <sys/stat.h>
28
 
#include <stdio.h>
29
 
#include <stdlib.h>
30
 
#include <unistd.h>
31
 
#include <dirent.h>
32
 
#include <errno.h>
33
 
 
34
 
#include "sysdeps.h"
35
 
#include "extfs_macosx.h"
36
 
#include "extfs.h"
37
 
 
38
 
#define DEBUG 0
39
 
#include "debug.h"
40
 
 
41
 
 
42
 
// Default Finder flags
43
 
const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited;
44
 
 
45
 
 
46
 
/*
47
 
 *  Initialization
48
 
 */
49
 
 
50
 
void extfs_init(void)
51
 
{
52
 
}
53
 
 
54
 
 
55
 
/*
56
 
 *  Deinitialization
57
 
 */
58
 
 
59
 
void extfs_exit(void)
60
 
{
61
 
}
62
 
 
63
 
 
64
 
/*
65
 
 *  Add component to path name
66
 
 */
67
 
 
68
 
void add_path_component(char *path, const char *component)
69
 
{
70
 
        int l = strlen(path);
71
 
        if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') {
72
 
                path[l] = '/';
73
 
                path[l+1] = 0;
74
 
        }
75
 
        strncat(path, component, MAX_PATH_LENGTH-1);
76
 
}
77
 
 
78
 
 
79
 
/*
80
 
 *  Add /rsrc to path name. Note that the 'correct' way to do this is to
81
 
 *  append '/..namedfork/rsrc', but I use this short form to save chars.
82
 
 */
83
 
 
84
 
void add_rsrc(const char *path, char *dest)
85
 
{
86
 
        int l = strlen(path);
87
 
 
88
 
        if ( l > MAX_PATH_LENGTH-5 )            // If there is no room to add "rsrc\0"
89
 
                return;
90
 
 
91
 
        *dest = '\0';
92
 
        strncat(dest, path, l);
93
 
 
94
 
        if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') {
95
 
                dest[l] = '/';
96
 
                dest[l+1] = 0;
97
 
        }
98
 
        strcat(dest, "rsrc");
99
 
}
100
 
 
101
 
 
102
 
/*
103
 
 * Resource forks on Mac OS X are kept on a UFS volume as /path/file/rsrc
104
 
 *
105
 
 * On HFS volumes, there is of course the data and rsrc fork, but the Darwin
106
 
 * filesystem layer presents the resource fork using the above pseudo path
107
 
 */
108
 
 
109
 
static int open_rsrc(const char *path, int flag)
110
 
{
111
 
        char path_rsrc[MAX_PATH_LENGTH];
112
 
 
113
 
        add_rsrc(path, path_rsrc);
114
 
        return open(path_rsrc, flag);
115
 
}
116
 
 
117
 
 
118
 
/*
119
 
 * Finder info is a little bit harder. We need to use Carbon library calls to access them
120
 
 */
121
 
 
122
 
 
123
 
/*
124
 
 *  Get/set finder info for file/directory specified by full path
125
 
 */
126
 
 
127
 
struct ext2type {
128
 
        const char *ext;
129
 
        uint32 type;
130
 
        uint32 creator;
131
 
};
132
 
 
133
 
static const ext2type e2t_translation[] = {
134
 
        {".Z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')},
135
 
        {".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')},
136
 
        {".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
137
 
        {".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
138
 
        {".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')},
139
 
        {".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')},
140
 
        {".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')},
141
 
        {".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')},
142
 
        {".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
143
 
        {".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
144
 
        {".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')},
145
 
        {".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')},
146
 
        {".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')},
147
 
        {".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')},
148
 
        {".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')},
149
 
        {".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')},
150
 
        {".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')},
151
 
        {".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')},
152
 
        {".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')},
153
 
        {".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')},
154
 
        {".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')},
155
 
        {".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')},
156
 
        {".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')},
157
 
        {".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')},
158
 
        {".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')},
159
 
        {".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')},
160
 
        {".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')},
161
 
        {".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')},
162
 
        {".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')},
163
 
        {".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')},
164
 
        {".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')},
165
 
        {".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')},
166
 
        {".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')},
167
 
        {".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')},
168
 
        {".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')},
169
 
        {".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')},
170
 
        {".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
171
 
        {".C", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
172
 
        {".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
173
 
        {".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
174
 
        {".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
175
 
        {".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
176
 
        {".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
177
 
        {".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
178
 
        {".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
179
 
        {".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
180
 
        {".S", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
181
 
        {".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
182
 
        {".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')},
183
 
        {".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')},
184
 
        {".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')},
185
 
        {".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')},
186
 
        {".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')},
187
 
        {".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')},
188
 
        {".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')},
189
 
        {".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')},
190
 
        {".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')},
191
 
        {NULL, 0, 0}    // End marker
192
 
};
193
 
 
194
 
// Mac OS X way of doing the above
195
 
 
196
 
#import <Foundation/NSString.h>
197
 
 
198
 
extern "C"
199
 
{
200
 
        NSString        *NSHFSTypeOfFile                        (const NSString *);
201
 
        uint32          NSHFSTypeCodeFromFileType       (const NSString *);             // Actually returns an OSType
202
 
}
203
 
 
204
 
uint32 fileType (const char *cPath)
205
 
{
206
 
        NSString        *copy = [NSString stringWithCString: cPath],
207
 
                                *type = NSHFSTypeOfFile(copy);
208
 
 
209
 
        if ( type == nil )
210
 
        {
211
 
                D(NSLog(@"No type for file %s", cPath));
212
 
                return 0;                                                               // Should this be '????' or '    ' ?
213
 
        }
214
 
 
215
 
        D(NSLog(@"Got type %@ for %s", type, cPath));
216
 
        return NSHFSTypeCodeFromFileType(type);
217
 
}
218
 
 
219
 
 
220
 
void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
221
 
{
222
 
    FSRef       fsRef;
223
 
    int32       status;
224
 
        // Set default finder info
225
 
        Mac_memset(finfo, 0, SIZEOF_FInfo);
226
 
        if (fxinfo)
227
 
                Mac_memset(fxinfo, 0, SIZEOF_FXInfo);
228
 
        WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS);
229
 
        WriteMacInt32(finfo + fdLocation, (uint32)-1);
230
 
 
231
 
        status = FSPathMakeRef((const uint8 *)path, &fsRef, NULL);
232
 
        if ( status == noErr )
233
 
        {
234
 
                FSCatalogInfo   cInfo;
235
 
                uint32                  AllFinderInfo = kFSCatInfoFinderInfo;
236
 
 
237
 
                if (fxinfo)
238
 
                        AllFinderInfo |= kFSCatInfoFinderXInfo;
239
 
 
240
 
                status = FSGetCatalogInfo(&fsRef, AllFinderInfo, &cInfo, NULL, NULL, NULL);
241
 
                if ( status == noErr )
242
 
                {
243
 
                        // byte-swap them to big endian (network order) if necessary
244
 
                        ((FileInfo *)&cInfo.finderInfo)->fileType = htonl(((FileInfo *)&cInfo.finderInfo)->fileType);
245
 
                        ((FileInfo *)&cInfo.finderInfo)->fileCreator = htonl(((FileInfo *)&cInfo.finderInfo)->fileCreator);
246
 
                        ((FileInfo *)&cInfo.finderInfo)->finderFlags = htons(((FileInfo *)&cInfo.finderInfo)->finderFlags);
247
 
                        D(printf("get_finfo(%s,...) - Got info of '%16.16s'\n", path, cInfo.finderInfo));
248
 
                        Host2Mac_memcpy(finfo, &cInfo.finderInfo, SIZEOF_FInfo);
249
 
                        if (fxinfo)
250
 
                                Host2Mac_memcpy(fxinfo, &cInfo.extFinderInfo, SIZEOF_FXInfo);
251
 
                        return;
252
 
                }
253
 
                else
254
 
                        printf("get_finfo(%s,...) failed to get catalog info\n", path);
255
 
        }
256
 
        else
257
 
                printf("get_finfo(%s,...) failed to get FSRef\n", path);
258
 
 
259
 
 
260
 
        // No Finder info file, translate file name extension to MacOS type/creator
261
 
        if (!is_dir) {
262
 
                int path_len = strlen(path);
263
 
                for (int i=0; e2t_translation[i].ext; i++) {
264
 
                        int ext_len = strlen(e2t_translation[i].ext);
265
 
                        if (path_len < ext_len)
266
 
                                continue;
267
 
                        if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) {
268
 
                                WriteMacInt32(finfo + fdType, e2t_translation[i].type);
269
 
                                WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator);
270
 
                                break;
271
 
                        }
272
 
                }
273
 
        }
274
 
 
275
 
 
276
 
        // Use alternate code to get type
277
 
        uint32  type = fileType(path);
278
 
 
279
 
        if ( type )
280
 
                WriteMacInt32(finfo + fdType, type);
281
 
}
282
 
 
283
 
void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
284
 
{
285
 
    FSRef       fsRef;
286
 
    OSErr       status;
287
 
 
288
 
        status = FSPathMakeRef((const uint8 *)path, &fsRef, NULL);
289
 
        if ( status == noErr )
290
 
        {
291
 
                FSCatalogInfo   cInfo;
292
 
 
293
 
                status = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &cInfo, NULL, NULL, NULL);
294
 
                if ( status == noErr )
295
 
                {
296
 
                        FSCatalogInfoBitmap whichInfo = kFSCatInfoNone;
297
 
                        if (finfo) {
298
 
                                whichInfo |= kFSCatInfoFinderInfo;
299
 
                                /*
300
 
                                  FIXME: Some users reported that directories could
301
 
                                  mysteriously disappear from a MacOS X 10.4 Finder
302
 
                                  point of view.
303
 
 
304
 
                                  An alternative is to use the ".finfo/" technique
305
 
                                  on MacOS X provided that attributes are first
306
 
                                  initialised from an FSGetCatalogInfo() call.
307
 
                                */
308
 
                                uint8 oldFlags1, oldFlags2;
309
 
                                if (is_dir) {
310
 
                                        oldFlags1 = cInfo.finderInfo[fdFlags];
311
 
                                        oldFlags2 = cInfo.finderInfo[fdFlags + 1];
312
 
                                }
313
 
                                Mac2Host_memcpy(&cInfo.finderInfo,    finfo,  SIZEOF_FInfo);
314
 
                                if (is_dir) {
315
 
                                        cInfo.finderInfo[fdFlags] = oldFlags1;
316
 
                                        cInfo.finderInfo[fdFlags + 1] = oldFlags2;
317
 
                                }
318
 
                        }
319
 
                        if (fxinfo) {
320
 
                                whichInfo |= kFSCatInfoFinderXInfo;
321
 
                                Mac2Host_memcpy(&cInfo.extFinderInfo, fxinfo, SIZEOF_FXInfo);
322
 
                        }
323
 
                        // byte-swap them to system byte order from big endian (network order) if necessary
324
 
                        ((FileInfo *)&cInfo.finderInfo)->fileType = ntohl(((FileInfo *)&cInfo.finderInfo)->fileType);
325
 
                        ((FileInfo *)&cInfo.finderInfo)->fileCreator = ntohl(((FileInfo *)&cInfo.finderInfo)->fileCreator);
326
 
                        ((FileInfo *)&cInfo.finderInfo)->finderFlags = ntohs(((FileInfo *)&cInfo.finderInfo)->finderFlags);
327
 
                        FSSetCatalogInfo(&fsRef, whichInfo, &cInfo);
328
 
                }
329
 
    }
330
 
}
331
 
 
332
 
 
333
 
/*
334
 
 *  Resource fork emulation functions
335
 
 */
336
 
 
337
 
uint32 get_rfork_size(const char *path)
338
 
{
339
 
        // Open resource file
340
 
        int fd = open_rsrc(path, O_RDONLY);
341
 
        if (fd < 0)
342
 
                return 0;
343
 
 
344
 
        // Get size
345
 
        off_t size = lseek(fd, 0, SEEK_END);
346
 
        
347
 
        // Close file and return size
348
 
        close(fd);
349
 
        return size < 0 ? 0 : size;
350
 
}
351
 
 
352
 
int open_rfork(const char *path, int flag)
353
 
{
354
 
        return open_rsrc(path, flag);
355
 
}
356
 
 
357
 
void close_rfork(const char *path, int fd)
358
 
{
359
 
        close(fd);
360
 
}
361
 
 
362
 
 
363
 
/*
364
 
 *  Read "length" bytes from file to "buffer",
365
 
 *  returns number of bytes read (or -1 on error)
366
 
 */
367
 
 
368
 
ssize_t extfs_read(int fd, void *buffer, size_t length)
369
 
{
370
 
        return read(fd, buffer, length);
371
 
}
372
 
 
373
 
 
374
 
/*
375
 
 *  Write "length" bytes from "buffer" to file,
376
 
 *  returns number of bytes written (or -1 on error)
377
 
 */
378
 
 
379
 
ssize_t extfs_write(int fd, void *buffer, size_t length)
380
 
{
381
 
        return write(fd, buffer, length);
382
 
}
383
 
 
384
 
 
385
 
/*
386
 
 *  Remove file/directory (and associated helper files),
387
 
 *  returns false on error (and sets errno)
388
 
 */
389
 
 
390
 
bool extfs_remove(const char *path)
391
 
{
392
 
        // Remove helpers first, don't complain if this fails
393
 
        char helper_path[MAX_PATH_LENGTH];
394
 
        add_rsrc(path, helper_path);
395
 
        remove(helper_path);
396
 
 
397
 
        // Now remove file or directory (and helper directories in the directory)
398
 
        if (remove(path) < 0) {
399
 
                if (errno == EISDIR || errno == ENOTEMPTY) {
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
 
        add_rsrc(old_path, old_helper_path);
418
 
        add_rsrc(new_path, new_helper_path);
419
 
        rename(old_helper_path, new_helper_path);
420
 
 
421
 
        // Now rename file
422
 
        return rename(old_path, new_path) == 0;
423
 
}
424
 
 
425
 
 
426
 
// Convert from the host OS filename encoding to MacRoman
427
 
const char *host_encoding_to_macroman(const char *filename)
428
 
{
429
 
        static char filename_mr[64];
430
 
        CFStringRef sref = CFStringCreateWithCString(0, filename, kCFStringEncodingUTF8);
431
 
        if (sref) {
432
 
                memset(filename_mr, 0, sizeof(filename_mr));
433
 
                if (CFStringGetCString(sref, filename_mr, sizeof(filename_mr), kCFStringEncodingMacRoman)) {
434
 
                        return filename_mr;
435
 
                }
436
 
                CFRelease(sref);
437
 
        }
438
 
        return filename;
439
 
}
440
 
 
441
 
 
442
 
// Convert from MacRoman to the host OS filename encoding
443
 
const char *macroman_to_host_encoding(const char *filename)
444
 
{
445
 
        static char filename_mr[64];
446
 
        CFStringRef sref = CFStringCreateWithCString(0, filename, kCFStringEncodingMacRoman);
447
 
        if (sref) {
448
 
                memset(filename_mr, 0, sizeof(filename_mr));
449
 
                if (CFStringGetCString(sref, filename_mr, sizeof(filename_mr), kCFStringEncodingUTF8)) {
450
 
                        return filename_mr;
451
 
                }
452
 
                CFRelease(sref);
453
 
        }
454
 
        return filename;
455
 
}
456