|
boredzo@1478
|
1 |
//
|
|
boredzo@1478
|
2 |
// CFGrowlAdditions.c
|
|
boredzo@1478
|
3 |
// Growl
|
|
boredzo@1478
|
4 |
//
|
|
boredzo@1478
|
5 |
// Created by Mac-arena the Bored Zo on Wed Jun 18 2004.
|
|
ingmarstein@3040
|
6 |
// Copyright 2005-2006 The Growl Project.
|
|
boredzo@1478
|
7 |
//
|
|
ingmarstein@2290
|
8 |
// This file is under the BSD License, refer to License.txt for details
|
|
boredzo@1478
|
9 |
|
|
boredzo@1478
|
10 |
#include <Carbon/Carbon.h>
|
|
boredzo@2020
|
11 |
#include <unistd.h>
|
|
ingmarstein@2634
|
12 |
#include <netinet/in.h>
|
|
ingmarstein@2634
|
13 |
#include <arpa/inet.h>
|
|
ingmarstein@2634
|
14 |
#include <netdb.h>
|
|
ingmarstein@2602
|
15 |
#include "CFGrowlAdditions.h"
|
|
boredzo@1478
|
16 |
|
|
ingmarstein@3184
|
17 |
#ifndef MIN
|
|
ingmarstein@3184
|
18 |
# define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
ingmarstein@3184
|
19 |
#endif
|
|
ingmarstein@3184
|
20 |
|
|
rudy@2946
|
21 |
extern Boolean CFStringGetFileSystemRepresentation() __attribute__((weak_import));
|
|
evands@3712
|
22 |
extern CFIndex CFStringGetMaximumSizeOfFileSystemRepresentation(CFStringRef string) __attribute__((weak_import));
|
|
rudy@2946
|
23 |
|
|
ingmarstein@2602
|
24 |
char *createFileSystemRepresentationOfString(CFStringRef str) {
|
|
ingmarstein@2602
|
25 |
char *buffer;
|
|
evands@3721
|
26 |
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4
|
|
evands@3721
|
27 |
/* CFStringGetFileSystemRepresentation will cause a link error despite the weak_import attribute above on 10.5 when compiling with 10.2 compatibility using gcc 3.3.
|
|
evands@3721
|
28 |
* PPC will therefore always use the 10.3 and below method of creating a file system representation.
|
|
evands@3721
|
29 |
*/
|
|
ingmarstein@2602
|
30 |
if (CFStringGetFileSystemRepresentation) {
|
|
ingmarstein@2602
|
31 |
CFIndex size = CFStringGetMaximumSizeOfFileSystemRepresentation(str);
|
|
ingmarstein@2602
|
32 |
buffer = malloc(size);
|
|
ingmarstein@2602
|
33 |
CFStringGetFileSystemRepresentation(str, buffer, size);
|
|
evands@3721
|
34 |
} else
|
|
evands@3721
|
35 |
#endif
|
|
evands@3721
|
36 |
{
|
|
ingmarstein@2641
|
37 |
buffer = malloc(512);
|
|
ingmarstein@2641
|
38 |
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, str, kCFURLPOSIXPathStyle, false);
|
|
ingmarstein@2641
|
39 |
if (!CFURLGetFileSystemRepresentation(url, false, (UInt8 *)buffer, 512)) {
|
|
ingmarstein@2641
|
40 |
free(buffer);
|
|
ingmarstein@2641
|
41 |
buffer = NULL;
|
|
ingmarstein@2641
|
42 |
}
|
|
ingmarstein@2641
|
43 |
CFRelease(url);
|
|
ingmarstein@2602
|
44 |
}
|
|
ingmarstein@2602
|
45 |
return buffer;
|
|
ingmarstein@2602
|
46 |
}
|
|
ingmarstein@2602
|
47 |
|
|
evands@3429
|
48 |
STRING_TYPE createStringWithDate(CFDateRef date) {
|
|
ingmarstein@2602
|
49 |
CFLocaleRef locale = CFLocaleCopyCurrent();
|
|
ingmarstein@2602
|
50 |
CFDateFormatterRef dateFormatter = CFDateFormatterCreate(kCFAllocatorDefault,
|
|
ingmarstein@2602
|
51 |
locale,
|
|
ingmarstein@2602
|
52 |
kCFDateFormatterMediumStyle,
|
|
ingmarstein@2602
|
53 |
kCFDateFormatterMediumStyle);
|
|
ingmarstein@2602
|
54 |
CFRelease(locale);
|
|
ingmarstein@2602
|
55 |
CFStringRef dateString = CFDateFormatterCreateStringWithDate(kCFAllocatorDefault,
|
|
ingmarstein@2602
|
56 |
dateFormatter,
|
|
ingmarstein@2602
|
57 |
date);
|
|
ingmarstein@2602
|
58 |
CFRelease(dateFormatter);
|
|
ingmarstein@2602
|
59 |
return dateString;
|
|
ingmarstein@2602
|
60 |
}
|
|
boredzo@1478
|
61 |
|
|
evands@3429
|
62 |
STRING_TYPE createStringWithContentsOfFile(CFStringRef filename, CFStringEncoding encoding) {
|
|
ingmarstein@2652
|
63 |
CFStringRef str = NULL;
|
|
ingmarstein@2652
|
64 |
|
|
ingmarstein@2652
|
65 |
char *path = createFileSystemRepresentationOfString(filename);
|
|
ingmarstein@2652
|
66 |
if (path) {
|
|
ingmarstein@2652
|
67 |
FILE *fp = fopen(path, "rb");
|
|
ingmarstein@2652
|
68 |
if (fp) {
|
|
ingmarstein@2652
|
69 |
fseek(fp, 0, SEEK_END);
|
|
ingmarstein@2652
|
70 |
unsigned long size = ftell(fp);
|
|
ingmarstein@2652
|
71 |
fseek(fp, 0, SEEK_SET);
|
|
ingmarstein@2652
|
72 |
unsigned char *buffer = malloc(size);
|
|
ingmarstein@2652
|
73 |
if (buffer && fread(buffer, 1, size, fp) == size)
|
|
ingmarstein@2652
|
74 |
str = CFStringCreateWithBytes(kCFAllocatorDefault, buffer, size, encoding, true);
|
|
ingmarstein@2652
|
75 |
fclose(fp);
|
|
ingmarstein@2652
|
76 |
}
|
|
ingmarstein@2652
|
77 |
free(path);
|
|
ingmarstein@2652
|
78 |
}
|
|
ingmarstein@2652
|
79 |
|
|
ingmarstein@2652
|
80 |
return str;
|
|
ingmarstein@2652
|
81 |
}
|
|
ingmarstein@2652
|
82 |
|
|
evands@3429
|
83 |
STRING_TYPE createStringWithStringAndCharacterAndString(STRING_TYPE str0, UniChar ch, STRING_TYPE str1) {
|
|
ingmarstein@2632
|
84 |
CFStringRef cfstr0 = (CFStringRef)str0;
|
|
ingmarstein@2632
|
85 |
CFStringRef cfstr1 = (CFStringRef)str1;
|
|
ingmarstein@2632
|
86 |
CFIndex len0 = (cfstr0 ? CFStringGetLength(cfstr0) : 0);
|
|
ingmarstein@2632
|
87 |
CFIndex len1 = (cfstr1 ? CFStringGetLength(cfstr1) : 0);
|
|
ingmarstein@2632
|
88 |
unsigned length = (len0 + (ch != 0xffff) + len1);
|
|
ingmarstein@2632
|
89 |
|
|
ingmarstein@2632
|
90 |
UniChar *buf = malloc(sizeof(UniChar) * length);
|
|
ingmarstein@2632
|
91 |
unsigned i = 0U;
|
|
ingmarstein@2632
|
92 |
|
|
ingmarstein@2632
|
93 |
if (cfstr0) {
|
|
ingmarstein@2632
|
94 |
CFStringGetCharacters(cfstr0, CFRangeMake(0, len0), buf);
|
|
ingmarstein@2632
|
95 |
i += len0;
|
|
ingmarstein@2632
|
96 |
}
|
|
ingmarstein@2632
|
97 |
if (ch != 0xffff)
|
|
ingmarstein@2632
|
98 |
buf[i++] = ch;
|
|
ingmarstein@2632
|
99 |
if (cfstr1)
|
|
ingmarstein@2632
|
100 |
CFStringGetCharacters(cfstr1, CFRangeMake(0, len1), &buf[i]);
|
|
ingmarstein@2632
|
101 |
|
|
ingmarstein@2632
|
102 |
return CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buf, length, /*contentsDeallocator*/ kCFAllocatorMalloc);
|
|
ingmarstein@2632
|
103 |
}
|
|
ingmarstein@2632
|
104 |
|
|
ingmarstein@2598
|
105 |
char *copyCString(STRING_TYPE str, CFStringEncoding encoding) {
|
|
ingmarstein@2598
|
106 |
CFIndex size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), encoding) + 1;
|
|
ingmarstein@2601
|
107 |
char *buffer = calloc(size, 1);
|
|
ingmarstein@2598
|
108 |
CFStringGetCString(str, buffer, size, encoding);
|
|
ingmarstein@2598
|
109 |
return buffer;
|
|
ingmarstein@2598
|
110 |
}
|
|
ingmarstein@2598
|
111 |
|
|
evands@3429
|
112 |
STRING_TYPE copyCurrentProcessName(void) {
|
|
boredzo@1478
|
113 |
ProcessSerialNumber PSN = { 0, kCurrentProcess };
|
|
boredzo@1478
|
114 |
CFStringRef name = NULL;
|
|
boredzo@1478
|
115 |
OSStatus err = CopyProcessName(&PSN, &name);
|
|
boredzo@1478
|
116 |
if (err != noErr) {
|
|
boredzo@1773
|
117 |
NSLog(CFSTR("in copyCurrentProcessName in CFGrowlAdditions: Could not get process name because CopyProcessName returned %li"), (long)err);
|
|
boredzo@1478
|
118 |
name = NULL;
|
|
boredzo@1478
|
119 |
}
|
|
boredzo@1478
|
120 |
return name;
|
|
boredzo@1478
|
121 |
}
|
|
boredzo@1478
|
122 |
|
|
evands@3429
|
123 |
URL_TYPE copyCurrentProcessURL(void) {
|
|
boredzo@1478
|
124 |
ProcessSerialNumber psn = { 0, kCurrentProcess };
|
|
boredzo@1478
|
125 |
FSRef fsref;
|
|
boredzo@1478
|
126 |
CFURLRef URL = NULL;
|
|
boredzo@1478
|
127 |
OSStatus err = GetProcessBundleLocation(&psn, &fsref);
|
|
ingmarstein@1518
|
128 |
if (err != noErr) {
|
|
boredzo@1773
|
129 |
NSLog(CFSTR("in copyCurrentProcessURL in CFGrowlAdditions: Could not get application location, because GetProcessBundleLocation returned %li\n"), (long)err);
|
|
ingmarstein@1518
|
130 |
} else {
|
|
boredzo@1478
|
131 |
URL = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsref);
|
|
ingmarstein@1518
|
132 |
}
|
|
boredzo@1478
|
133 |
return URL;
|
|
boredzo@1478
|
134 |
}
|
|
evands@3429
|
135 |
STRING_TYPE copyCurrentProcessPath(void) {
|
|
boredzo@1773
|
136 |
CFURLRef URL = copyCurrentProcessURL();
|
|
boredzo@1478
|
137 |
CFStringRef path = CFURLCopyFileSystemPath(URL, kCFURLPOSIXPathStyle);
|
|
boredzo@1478
|
138 |
CFRelease(URL);
|
|
boredzo@1478
|
139 |
return path;
|
|
boredzo@1478
|
140 |
}
|
|
boredzo@1478
|
141 |
|
|
evands@3429
|
142 |
URL_TYPE copyTemporaryFolderURL(void) {
|
|
boredzo@2020
|
143 |
FSRef ref;
|
|
boredzo@2020
|
144 |
CFURLRef url = NULL;
|
|
boredzo@2020
|
145 |
|
|
boredzo@2020
|
146 |
OSStatus err = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, kCreateFolder, &ref);
|
|
boredzo@2020
|
147 |
if (err != noErr)
|
|
boredzo@2020
|
148 |
NSLog(CFSTR("in copyTemporaryFolderPath in CFGrowlAdditions: Could not locate temporary folder because FSFindFolder returned %li"), (long)err);
|
|
boredzo@2020
|
149 |
else
|
|
boredzo@2020
|
150 |
url = CFURLCreateFromFSRef(kCFAllocatorDefault, &ref);
|
|
boredzo@2020
|
151 |
|
|
boredzo@2020
|
152 |
return url;
|
|
boredzo@2020
|
153 |
}
|
|
evands@3429
|
154 |
STRING_TYPE copyTemporaryFolderPath(void) {
|
|
boredzo@2020
|
155 |
CFStringRef path = NULL;
|
|
boredzo@2020
|
156 |
|
|
boredzo@2020
|
157 |
CFURLRef url = copyTemporaryFolderURL();
|
|
ingmarstein@2041
|
158 |
if (url) {
|
|
boredzo@2020
|
159 |
path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
|
|
boredzo@1478
|
160 |
CFRelease(url);
|
|
boredzo@1478
|
161 |
}
|
|
boredzo@2020
|
162 |
|
|
boredzo@2020
|
163 |
return path;
|
|
boredzo@1478
|
164 |
}
|
|
boredzo@1478
|
165 |
|
|
evands@3429
|
166 |
DATA_TYPE readFile(const char *filename)
|
|
ingmarstein@3141
|
167 |
{
|
|
ingmarstein@3141
|
168 |
CFDataRef data;
|
|
ingmarstein@3141
|
169 |
// read the file into a CFDataRef
|
|
ingmarstein@3141
|
170 |
FILE *fp = fopen(filename, "r");
|
|
ingmarstein@3141
|
171 |
if (fp) {
|
|
ingmarstein@3141
|
172 |
fseek(fp, 0, SEEK_END);
|
|
ingmarstein@3141
|
173 |
long dataLength = ftell(fp);
|
|
ingmarstein@3141
|
174 |
fseek(fp, 0, SEEK_SET);
|
|
ingmarstein@3141
|
175 |
unsigned char *fileData = malloc(dataLength);
|
|
ingmarstein@3141
|
176 |
fread(fileData, 1, dataLength, fp);
|
|
ingmarstein@3141
|
177 |
fclose(fp);
|
|
ingmarstein@3141
|
178 |
data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, fileData, dataLength, kCFAllocatorMalloc);
|
|
ingmarstein@3141
|
179 |
} else
|
|
ingmarstein@3141
|
180 |
data = NULL;
|
|
ingmarstein@3141
|
181 |
|
|
ingmarstein@3141
|
182 |
return data;
|
|
ingmarstein@3141
|
183 |
}
|
|
ingmarstein@3141
|
184 |
|
|
boredzo@4095
|
185 |
URL_TYPE copyURLForApplication(STRING_TYPE appName)
|
|
boredzo@4095
|
186 |
{
|
|
boredzo@4095
|
187 |
CFURLRef appURL = NULL;
|
|
boredzo@4095
|
188 |
OSStatus err = LSFindApplicationForInfo(/*inCreator*/ kLSUnknownCreator,
|
|
boredzo@4095
|
189 |
/*inBundleID*/ NULL,
|
|
boredzo@4095
|
190 |
/*inName*/ appName,
|
|
boredzo@4095
|
191 |
/*outAppRef*/ NULL,
|
|
boredzo@4095
|
192 |
/*outAppURL*/ &appURL);
|
|
boredzo@4095
|
193 |
return (err == noErr) ? appURL : NULL;
|
|
boredzo@4095
|
194 |
}
|
|
boredzo@4095
|
195 |
|
|
evands@3429
|
196 |
STRING_TYPE createStringWithAddressData(DATA_TYPE aAddressData) {
|
|
ingmarstein@2634
|
197 |
struct sockaddr *socketAddress = (struct sockaddr *)CFDataGetBytePtr(aAddressData);
|
|
ingmarstein@2634
|
198 |
// IPv6 Addresses are "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"
|
|
ingmarstein@2634
|
199 |
// at max, which is 40 bytes (0-terminated)
|
|
ingmarstein@2634
|
200 |
// IPv4 Addresses are "255.255.255.255" at max which is smaller
|
|
ingmarstein@2634
|
201 |
char stringBuffer[40];
|
|
ingmarstein@2634
|
202 |
CFStringRef addressAsString = NULL;
|
|
ingmarstein@2634
|
203 |
if (socketAddress->sa_family == AF_INET) {
|
|
ingmarstein@2634
|
204 |
struct sockaddr_in *ipv4 = (struct sockaddr_in *)socketAddress;
|
|
ingmarstein@2634
|
205 |
if (inet_ntop(AF_INET, &(ipv4->sin_addr), stringBuffer, 40))
|
|
ingmarstein@2634
|
206 |
addressAsString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s:%d"), stringBuffer, ipv4->sin_port);
|
|
ingmarstein@2634
|
207 |
else
|
|
ingmarstein@2634
|
208 |
addressAsString = CFSTR("IPv4 un-ntopable");
|
|
ingmarstein@2634
|
209 |
} else if (socketAddress->sa_family == AF_INET6) {
|
|
ingmarstein@2634
|
210 |
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)socketAddress;
|
|
ingmarstein@2634
|
211 |
if (inet_ntop(AF_INET6, &(ipv6->sin6_addr), stringBuffer, 40))
|
|
ingmarstein@2634
|
212 |
// Suggested IPv6 format (see http://www.faqs.org/rfcs/rfc2732.html)
|
|
ingmarstein@2634
|
213 |
addressAsString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("[%s]:%d"), stringBuffer, ipv6->sin6_port);
|
|
ingmarstein@2634
|
214 |
else
|
|
ingmarstein@2634
|
215 |
addressAsString = CFSTR("IPv6 un-ntopable");
|
|
ingmarstein@2634
|
216 |
} else
|
|
ingmarstein@2634
|
217 |
addressAsString = CFSTR("neither IPv6 nor IPv4");
|
|
ingmarstein@2634
|
218 |
|
|
ingmarstein@2634
|
219 |
return addressAsString;
|
|
ingmarstein@2634
|
220 |
}
|
|
ingmarstein@2634
|
221 |
|
|
evands@3429
|
222 |
STRING_TYPE createHostNameForAddressData(DATA_TYPE aAddressData) {
|
|
ingmarstein@2634
|
223 |
char hostname[NI_MAXHOST];
|
|
ingmarstein@2634
|
224 |
struct sockaddr *socketAddress = (struct sockaddr *)CFDataGetBytePtr(aAddressData);
|
|
ingmarstein@2634
|
225 |
if (getnameinfo(socketAddress, CFDataGetLength(aAddressData),
|
|
ingmarstein@2634
|
226 |
hostname, sizeof(hostname),
|
|
ingmarstein@2634
|
227 |
/*serv*/ NULL, /*servlen*/ 0,
|
|
ingmarstein@2634
|
228 |
NI_NAMEREQD))
|
|
ingmarstein@2634
|
229 |
return NULL;
|
|
ingmarstein@2634
|
230 |
else
|
|
ingmarstein@2634
|
231 |
return CFStringCreateWithCString(kCFAllocatorDefault, hostname, kCFStringEncodingASCII);
|
|
ingmarstein@2634
|
232 |
}
|
|
ingmarstein@2634
|
233 |
|
|
evands@3429
|
234 |
DATA_TYPE copyIconDataForPath(STRING_TYPE path) {
|
|
boredzo@1773
|
235 |
CFDataRef data = NULL;
|
|
boredzo@1773
|
236 |
|
|
boredzo@1773
|
237 |
//false is probably safest, and is harmless when the object really is a directory.
|
|
boredzo@1773
|
238 |
CFURLRef URL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, /*isDirectory*/ false);
|
|
ingmarstein@1777
|
239 |
if (URL) {
|
|
boredzo@1773
|
240 |
data = copyIconDataForURL(URL);
|
|
boredzo@1773
|
241 |
CFRelease(URL);
|
|
boredzo@1773
|
242 |
}
|
|
boredzo@1773
|
243 |
|
|
boredzo@1773
|
244 |
return data;
|
|
boredzo@1773
|
245 |
}
|
|
evands@3429
|
246 |
|
|
evands@3429
|
247 |
DATA_TYPE copyIconDataForURL(URL_TYPE URL)
|
|
evands@3429
|
248 |
{
|
|
boredzo@1773
|
249 |
CFDataRef data = NULL;
|
|
boredzo@1773
|
250 |
|
|
ingmarstein@1777
|
251 |
if (URL) {
|
|
boredzo@1773
|
252 |
FSRef ref;
|
|
ingmarstein@1777
|
253 |
if (CFURLGetFSRef(URL, &ref)) {
|
|
boredzo@1773
|
254 |
IconRef icon = NULL;
|
|
boredzo@1773
|
255 |
SInt16 label_noOneCares;
|
|
boredzo@1773
|
256 |
OSStatus err = GetIconRefFromFileInfo(&ref,
|
|
boredzo@1773
|
257 |
/*inFileNameLength*/ 0U, /*inFileName*/ NULL,
|
|
boredzo@1773
|
258 |
kFSCatInfoNone, /*inCatalogInfo*/ NULL,
|
|
boredzo@1773
|
259 |
kIconServicesNoBadgeFlag | kIconServicesUpdateIfNeededFlag,
|
|
boredzo@1773
|
260 |
&icon,
|
|
boredzo@1773
|
261 |
&label_noOneCares);
|
|
ingmarstein@1777
|
262 |
if (err != noErr) {
|
|
boredzo@1773
|
263 |
NSLog(CFSTR("in copyIconDataForURL in CFGrowlAdditions: could not get icon for %@: GetIconRefFromFileInfo returned %li\n"), URL, (long)err);
|
|
boredzo@1773
|
264 |
} else {
|
|
boredzo@1773
|
265 |
IconFamilyHandle fam = NULL;
|
|
boredzo@1773
|
266 |
err = IconRefToIconFamily(icon, kSelectorAllAvailableData, &fam);
|
|
ingmarstein@1777
|
267 |
if (err != noErr) {
|
|
boredzo@1773
|
268 |
NSLog(CFSTR("in copyIconDataForURL in CFGrowlAdditions: could not get icon for %@: IconRefToIconFamily returned %li\n"), URL, (long)err);
|
|
boredzo@1773
|
269 |
} else {
|
|
boredzo@1773
|
270 |
HLock((Handle)fam);
|
|
ingmarstein@1777
|
271 |
data = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)*(Handle)fam, GetHandleSize((Handle)fam));
|
|
boredzo@1773
|
272 |
HUnlock((Handle)fam);
|
|
boredzo@1773
|
273 |
DisposeHandle((Handle)fam);
|
|
boredzo@1773
|
274 |
}
|
|
boredzo@1773
|
275 |
ReleaseIconRef(icon);
|
|
boredzo@1773
|
276 |
}
|
|
boredzo@1773
|
277 |
}
|
|
boredzo@1773
|
278 |
}
|
|
boredzo@1773
|
279 |
|
|
boredzo@1773
|
280 |
return data;
|
|
boredzo@1773
|
281 |
}
|
|
boredzo@2020
|
282 |
|
|
evands@3429
|
283 |
URL_TYPE createURLByMakingDirectoryAtURLWithName(URL_TYPE parent, STRING_TYPE name)
|
|
evands@3429
|
284 |
{
|
|
boredzo@2020
|
285 |
CFURLRef newDirectory = NULL;
|
|
boredzo@2020
|
286 |
|
|
boredzo@2020
|
287 |
CFAllocatorRef allocator = parent ? CFGetAllocator(parent) : name ? CFGetAllocator(name) : kCFAllocatorDefault;
|
|
boredzo@2020
|
288 |
|
|
ingmarstein@2041
|
289 |
if (parent) parent = CFRetain(parent);
|
|
boredzo@2020
|
290 |
else {
|
|
boredzo@2020
|
291 |
char *cwdBytes = alloca(PATH_MAX);
|
|
boredzo@2020
|
292 |
getcwd(cwdBytes, PATH_MAX);
|
|
boredzo@2020
|
293 |
parent = CFURLCreateFromFileSystemRepresentation(allocator, (const unsigned char *)cwdBytes, strlen(cwdBytes), /*isDirectory*/ true);
|
|
ingmarstein@2041
|
294 |
if (!name) {
|
|
boredzo@2020
|
295 |
newDirectory = parent;
|
|
boredzo@2020
|
296 |
goto end;
|
|
boredzo@2020
|
297 |
}
|
|
boredzo@2020
|
298 |
}
|
|
ingmarstein@2041
|
299 |
if (!parent)
|
|
boredzo@2031
|
300 |
NSLog(CFSTR("in createURLByMakingDirectoryAtURLWithName in CFGrowlAdditions: parent directory URL is NULL (please tell the Growl developers)\n"), parent);
|
|
boredzo@2031
|
301 |
else {
|
|
ingmarstein@2041
|
302 |
if (name)
|
|
boredzo@2020
|
303 |
name = CFRetain(name);
|
|
boredzo@2020
|
304 |
else {
|
|
boredzo@2020
|
305 |
name = CFURLCopyLastPathComponent(parent);
|
|
boredzo@2020
|
306 |
CFURLRef newParent = CFURLCreateCopyDeletingLastPathComponent(allocator, parent);
|
|
boredzo@2020
|
307 |
CFRelease(parent);
|
|
boredzo@2020
|
308 |
parent = newParent;
|
|
boredzo@2020
|
309 |
}
|
|
boredzo@2020
|
310 |
|
|
ingmarstein@2041
|
311 |
if (!name)
|
|
boredzo@2031
|
312 |
NSLog(CFSTR("in createURLByMakingDirectoryAtURLWithName in CFGrowlAdditions: name of directory to create is NULL (please tell the Growl developers)\n"), parent);
|
|
boredzo@2031
|
313 |
else {
|
|
boredzo@2020
|
314 |
FSRef parentRef;
|
|
ingmarstein@2041
|
315 |
if (!CFURLGetFSRef(parent, &parentRef))
|
|
boredzo@2031
|
316 |
NSLog(CFSTR("in createURLByMakingDirectoryAtURLWithName in CFGrowlAdditions: could not create FSRef for parent directory at %@ (please tell the Growl developers)\n"), parent);
|
|
boredzo@2031
|
317 |
else {
|
|
boredzo@2020
|
318 |
FSRef newDirectoryRef;
|
|
boredzo@2020
|
319 |
|
|
boredzo@2020
|
320 |
struct HFSUniStr255 nameUnicode;
|
|
boredzo@2020
|
321 |
CFRange range = { 0, MIN(CFStringGetLength(name), USHRT_MAX) };
|
|
boredzo@2020
|
322 |
CFStringGetCharacters(name, range, nameUnicode.unicode);
|
|
boredzo@2020
|
323 |
nameUnicode.length = range.length;
|
|
boredzo@2020
|
324 |
|
|
boredzo@2020
|
325 |
struct FSRefParam refPB = {
|
|
boredzo@2020
|
326 |
.ref = &parentRef,
|
|
boredzo@2020
|
327 |
.nameLength = nameUnicode.length,
|
|
boredzo@2020
|
328 |
.name = nameUnicode.unicode,
|
|
boredzo@2020
|
329 |
.whichInfo = kFSCatInfoNone,
|
|
boredzo@2020
|
330 |
.catInfo = NULL,
|
|
boredzo@2020
|
331 |
.textEncodingHint = kTextEncodingUnknown,
|
|
boredzo@2020
|
332 |
.newRef = &newDirectoryRef,
|
|
boredzo@2020
|
333 |
};
|
|
ingmarstein@2269
|
334 |
|
|
boredzo@2020
|
335 |
OSStatus err = PBCreateDirectoryUnicodeSync(&refPB);
|
|
ingmarstein@2041
|
336 |
if (err == dupFNErr) {
|
|
boredzo@2020
|
337 |
//dupFNErr == file (or folder) exists already. this is fine.
|
|
boredzo@2020
|
338 |
err = PBMakeFSRefUnicodeSync(&refPB);
|
|
boredzo@2020
|
339 |
}
|
|
ingmarstein@2041
|
340 |
if (err == noErr) {
|
|
boredzo@2031
|
341 |
NSLog(CFSTR("PBCreateDirectoryUnicodeSync or PBMakeFSRefUnicodeSync returned %li; calling CFURLCreateFromFSRef"), (long)err); //XXX
|
|
boredzo@2020
|
342 |
newDirectory = CFURLCreateFromFSRef(allocator, &newDirectoryRef);
|
|
boredzo@2031
|
343 |
NSLog(CFSTR("CFURLCreateFromFSRef returned %@"), newDirectory); //XXX
|
|
boredzo@2020
|
344 |
} else
|
|
boredzo@2031
|
345 |
NSLog(CFSTR("in createURLByMakingDirectoryAtURLWithName in CFGrowlAdditions: could not create directory '%@' in parent directory at %@: FSCreateDirectoryUnicode returned %li (please tell the Growl developers)"), name, parent, (long)err);
|
|
boredzo@2020
|
346 |
}
|
|
boredzo@2020
|
347 |
|
|
Rudy@4229
|
348 |
} //if (name)
|
|
Rudy@4229
|
349 |
if(parent)
|
|
boredzo@2020
|
350 |
CFRelease(parent);
|
|
Rudy@4229
|
351 |
if(name)
|
|
Rudy@4229
|
352 |
CFRelease(name);
|
|
ingmarstein@2041
|
353 |
} //if (parent)
|
|
boredzo@2020
|
354 |
|
|
boredzo@2020
|
355 |
end:
|
|
boredzo@2020
|
356 |
return newDirectory;
|
|
boredzo@2020
|
357 |
}
|
|
boredzo@2020
|
358 |
|
|
boredzo@2020
|
359 |
#ifndef COPYFORK_BUFSIZE
|
|
boredzo@2020
|
360 |
# define COPYFORK_BUFSIZE 5242880U /*5 MiB*/
|
|
boredzo@2020
|
361 |
#endif
|
|
boredzo@2020
|
362 |
|
|
ingmarstein@2041
|
363 |
static OSStatus copyFork(const struct HFSUniStr255 *forkName, const FSRef *srcFile, const FSRef *destDir, const struct HFSUniStr255 *destName, FSRef *outDestFile) {
|
|
boredzo@2020
|
364 |
OSStatus err, closeErr;
|
|
boredzo@2020
|
365 |
struct FSForkIOParam srcPB = {
|
|
boredzo@2020
|
366 |
.ref = srcFile,
|
|
boredzo@2020
|
367 |
.forkNameLength = forkName->length,
|
|
boredzo@2020
|
368 |
.forkName = forkName->unicode,
|
|
boredzo@2020
|
369 |
.permissions = fsRdPerm,
|
|
boredzo@2020
|
370 |
};
|
|
boredzo@2031
|
371 |
unsigned char debuggingPathBuf[PATH_MAX] = "";
|
|
boredzo@2031
|
372 |
OSStatus debuggingPathErr;
|
|
boredzo@2020
|
373 |
|
|
boredzo@2020
|
374 |
err = PBOpenForkSync(&srcPB);
|
|
ingmarstein@2041
|
375 |
if (err != noErr) {
|
|
boredzo@2031
|
376 |
debuggingPathErr = FSRefMakePath(srcFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
377 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
378 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for source file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
379 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBOpenForkSync (source: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
380 |
} else {
|
|
boredzo@2020
|
381 |
FSRef destFile;
|
|
boredzo@2020
|
382 |
|
|
boredzo@2020
|
383 |
/*the first thing to do is get the name of the destination file, if one
|
|
boredzo@2020
|
384 |
* wasn't provided.
|
|
boredzo@2020
|
385 |
*and while we're at it, we get the catalogue info as well.
|
|
boredzo@2020
|
386 |
*/
|
|
boredzo@2020
|
387 |
struct FSCatalogInfo catInfo;
|
|
boredzo@2020
|
388 |
struct FSRefParam refPB = {
|
|
boredzo@2020
|
389 |
.ref = srcFile,
|
|
boredzo@2020
|
390 |
.whichInfo = kFSCatInfoGettableInfo & kFSCatInfoSettableInfo,
|
|
boredzo@2020
|
391 |
.catInfo = &catInfo,
|
|
boredzo@2020
|
392 |
.spec = NULL,
|
|
boredzo@2020
|
393 |
.parentRef = NULL,
|
|
boredzo@2020
|
394 |
.outName = destName ? NULL : (struct HFSUniStr255 *)(destName = alloca(sizeof(struct HFSUniStr255))),
|
|
boredzo@2020
|
395 |
};
|
|
boredzo@2020
|
396 |
|
|
boredzo@2020
|
397 |
err = PBGetCatalogInfoSync(&refPB);
|
|
ingmarstein@2041
|
398 |
if (err != noErr) {
|
|
boredzo@2031
|
399 |
debuggingPathErr = FSRefMakePath(srcFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
400 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
401 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for source file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
402 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBGetCatalogInfoSync (source: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
403 |
} else {
|
|
boredzo@2020
|
404 |
refPB.ref = destDir;
|
|
boredzo@2020
|
405 |
refPB.nameLength = destName->length;
|
|
boredzo@2020
|
406 |
refPB.name = destName->unicode;
|
|
boredzo@2020
|
407 |
refPB.textEncodingHint = kTextEncodingUnknown;
|
|
boredzo@2020
|
408 |
refPB.newRef = &destFile;
|
|
boredzo@2020
|
409 |
|
|
boredzo@2031
|
410 |
const char *functionName = "PBMakeFSRefUnicodeSync"; //for error-reporting message
|
|
boredzo@2031
|
411 |
|
|
boredzo@2020
|
412 |
err = PBMakeFSRefUnicodeSync(&refPB);
|
|
ingmarstein@2041
|
413 |
if ((err != noErr) && (err != fnfErr)) {
|
|
boredzo@2031
|
414 |
handleMakeFSRefError:
|
|
boredzo@2031
|
415 |
debuggingPathErr = FSRefMakePath(destDir, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
416 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
417 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for destination directory: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
418 |
|
|
boredzo@2031
|
419 |
//get filename too
|
|
boredzo@2031
|
420 |
CFStringRef debuggingFilename = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault,
|
|
boredzo@2031
|
421 |
destName->unicode,
|
|
boredzo@2031
|
422 |
destName->length,
|
|
boredzo@2264
|
423 |
/*contentsDeallocator*/ kCFAllocatorNull);
|
|
ingmarstein@2041
|
424 |
if (!debuggingFilename)
|
|
boredzo@2264
|
425 |
debuggingFilename = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, "(could not get filename for destination file: CFStringCreateWithCharactersNoCopy returned NULL)", kCFStringEncodingASCII, /*contentsDeallocator*/ kCFAllocatorNull);
|
|
boredzo@2031
|
426 |
|
|
boredzo@2031
|
427 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: %s (destination: %s/%@) returned %li"), functionName, debuggingPathBuf, debuggingFilename, (long)err);
|
|
boredzo@2031
|
428 |
|
|
ingmarstein@2041
|
429 |
if (debuggingFilename) CFRelease(debuggingFilename);
|
|
boredzo@2031
|
430 |
} else {
|
|
boredzo@2020
|
431 |
//that file doesn't exist in that folder; create it.
|
|
boredzo@2020
|
432 |
err = PBCreateFileUnicodeSync(&refPB);
|
|
boredzo@2264
|
433 |
if (err == noErr) {
|
|
boredzo@2020
|
434 |
/*make sure the Finder knows about the new file.
|
|
boredzo@2020
|
435 |
*FNNotify returns a status code too, but this isn't an
|
|
boredzo@2020
|
436 |
* essential step, so we just ignore it.
|
|
boredzo@2020
|
437 |
*/
|
|
boredzo@2020
|
438 |
FNNotify(destDir, kFNDirectoryModifiedMessage, kNilOptions);
|
|
boredzo@2264
|
439 |
} else if (err == dupFNErr) {
|
|
boredzo@2264
|
440 |
/*dupFNErr: the file already exists.
|
|
boredzo@2264
|
441 |
*we can safely ignore this error.
|
|
boredzo@2264
|
442 |
*/
|
|
boredzo@2264
|
443 |
err = noErr;
|
|
boredzo@2264
|
444 |
} else {
|
|
boredzo@2264
|
445 |
functionName = "PBCreateFileUnicodeSync";
|
|
boredzo@2264
|
446 |
goto handleMakeFSRefError;
|
|
boredzo@2020
|
447 |
}
|
|
boredzo@2020
|
448 |
}
|
|
boredzo@2020
|
449 |
}
|
|
ingmarstein@2041
|
450 |
if (err == noErr) {
|
|
ingmarstein@2041
|
451 |
if (outDestFile)
|
|
boredzo@2020
|
452 |
memcpy(outDestFile, &destFile, sizeof(destFile));
|
|
boredzo@2020
|
453 |
|
|
boredzo@2020
|
454 |
struct FSForkIOParam destPB = {
|
|
boredzo@2020
|
455 |
.ref = &destFile,
|
|
boredzo@2020
|
456 |
.forkNameLength = forkName->length,
|
|
boredzo@2020
|
457 |
.forkName = forkName->unicode,
|
|
boredzo@2020
|
458 |
.permissions = fsWrPerm,
|
|
boredzo@2020
|
459 |
};
|
|
boredzo@2020
|
460 |
err = PBOpenForkSync(&destPB);
|
|
boredzo@2031
|
461 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBOpenForkSync (dest) returned %li"), (long)err);
|
|
ingmarstein@2041
|
462 |
if (err != noErr) {
|
|
boredzo@2031
|
463 |
debuggingPathErr = FSRefMakePath(&destFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
464 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
465 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for dest file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
466 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBOpenForkSync (destination: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
467 |
} else {
|
|
boredzo@2020
|
468 |
void *buf = malloc(COPYFORK_BUFSIZE);
|
|
ingmarstein@2041
|
469 |
if (buf) {
|
|
boredzo@2020
|
470 |
srcPB.buffer = destPB.buffer = buf;
|
|
boredzo@2020
|
471 |
srcPB.requestCount = COPYFORK_BUFSIZE;
|
|
ingmarstein@2041
|
472 |
while (err == noErr) {
|
|
boredzo@2020
|
473 |
err = PBReadForkSync(&srcPB);
|
|
ingmarstein@2041
|
474 |
if (err == eofErr) {
|
|
boredzo@2020
|
475 |
err = noErr;
|
|
ingmarstein@2041
|
476 |
if (srcPB.actualCount == 0)
|
|
boredzo@2020
|
477 |
break;
|
|
boredzo@2020
|
478 |
}
|
|
ingmarstein@2041
|
479 |
if (err != noErr) {
|
|
boredzo@2031
|
480 |
debuggingPathErr = FSRefMakePath(&destFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
481 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
482 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for source file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
483 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBReadForkSync (source: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
484 |
} else {
|
|
boredzo@2020
|
485 |
destPB.requestCount = srcPB.actualCount;
|
|
boredzo@2020
|
486 |
err = PBWriteForkSync(&destPB);
|
|
ingmarstein@2041
|
487 |
if (err != noErr) {
|
|
boredzo@2031
|
488 |
debuggingPathErr = FSRefMakePath(&destFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
489 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
490 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for dest file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
491 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBWriteForkSync (destination: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
492 |
}
|
|
boredzo@2020
|
493 |
}
|
|
boredzo@2020
|
494 |
}
|
|
boredzo@2020
|
495 |
|
|
boredzo@2020
|
496 |
free(buf);
|
|
boredzo@2020
|
497 |
}
|
|
boredzo@2020
|
498 |
|
|
boredzo@2020
|
499 |
closeErr = PBCloseForkSync(&destPB);
|
|
ingmarstein@2041
|
500 |
if (closeErr != noErr) {
|
|
boredzo@2031
|
501 |
debuggingPathErr = FSRefMakePath(&destFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
502 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
503 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for dest file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
504 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBCloseForkSync (destination: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
505 |
}
|
|
ingmarstein@2041
|
506 |
if (err == noErr) err = closeErr;
|
|
boredzo@2020
|
507 |
}
|
|
boredzo@2020
|
508 |
}
|
|
boredzo@2020
|
509 |
|
|
boredzo@2020
|
510 |
closeErr = PBCloseForkSync(&srcPB);
|
|
ingmarstein@2041
|
511 |
if (closeErr != noErr) {
|
|
boredzo@2031
|
512 |
debuggingPathErr = FSRefMakePath(&destFile, debuggingPathBuf, PATH_MAX);
|
|
ingmarstein@2041
|
513 |
if (debuggingPathErr != noErr)
|
|
boredzo@2031
|
514 |
snprintf((char *)debuggingPathBuf, PATH_MAX, "(could not get path for source file: FSRefMakePath returned %li)", (long)debuggingPathErr);
|
|
boredzo@2031
|
515 |
NSLog(CFSTR("in copyFork in CFGrowlAdditions: PBCloseForkSync (source: %s) returned %li"), debuggingPathBuf, (long)err);
|
|
boredzo@2031
|
516 |
}
|
|
ingmarstein@2041
|
517 |
if (err == noErr) err = closeErr;
|
|
ingmarstein@2041
|
518 |
}
|
|
ingmarstein@2041
|
519 |
|
|
ingmarstein@2041
|
520 |
return err;
|
|
ingmarstein@2041
|
521 |
}
|
|
ingmarstein@2041
|
522 |
|
|
ingmarstein@2041
|
523 |
static OSStatus GrowlCopyObjectSync(const FSRef *fileRef, const FSRef *destRef, FSRef *destFileRef) {
|
|
ingmarstein@2041
|
524 |
OSStatus err;
|
|
ingmarstein@2041
|
525 |
struct HFSUniStr255 forkName;
|
|
ingmarstein@2041
|
526 |
struct FSForkIOParam forkPB = {
|
|
ingmarstein@2041
|
527 |
.ref = fileRef,
|
|
ingmarstein@2041
|
528 |
.forkIterator = {
|
|
ingmarstein@2041
|
529 |
.initialize = 0L
|
|
ingmarstein@2041
|
530 |
},
|
|
ingmarstein@2041
|
531 |
.outForkName = &forkName,
|
|
ingmarstein@2041
|
532 |
};
|
|
ingmarstein@2269
|
533 |
|
|
ingmarstein@2041
|
534 |
do {
|
|
ingmarstein@2041
|
535 |
err = PBIterateForksSync(&forkPB);
|
|
ingmarstein@2041
|
536 |
NSLog(CFSTR("PBIterateForksSync returned %li"), (long)err);
|
|
ingmarstein@2041
|
537 |
if (err != noErr) {
|
|
ingmarstein@2041
|
538 |
if (err != errFSNoMoreItems)
|
|
ingmarstein@2041
|
539 |
NSLog(CFSTR("in GrowlCopyObjectSync in CFGrowlAdditions: PBIterateForksSync returned %li"), (long)err);
|
|
ingmarstein@2041
|
540 |
} else {
|
|
ingmarstein@2041
|
541 |
err = copyFork(&forkName, fileRef, destRef, /*destName*/ NULL, /*outDestFile*/ destFileRef);
|
|
ingmarstein@2041
|
542 |
//copyFork prints its own error messages
|
|
ingmarstein@2041
|
543 |
}
|
|
ingmarstein@2041
|
544 |
} while (err == noErr);
|
|
ingmarstein@2041
|
545 |
if (err == errFSNoMoreItems) err = noErr;
|
|
boredzo@2020
|
546 |
|
|
boredzo@2020
|
547 |
return err;
|
|
boredzo@2020
|
548 |
}
|
|
boredzo@2020
|
549 |
|
|
evands@3429
|
550 |
URL_TYPE createURLByCopyingFileFromURLToDirectoryURL(URL_TYPE file, URL_TYPE dest)
|
|
evands@3429
|
551 |
{
|
|
boredzo@2020
|
552 |
CFURLRef destFileURL = NULL;
|
|
boredzo@2020
|
553 |
|
|
boredzo@2020
|
554 |
FSRef fileRef, destRef, destFileRef;
|
|
ingmarstein@2041
|
555 |
Boolean gotFileRef = CFURLGetFSRef(file, &fileRef);
|
|
ingmarstein@2041
|
556 |
Boolean gotDestRef = CFURLGetFSRef(dest, &destRef);
|
|
ingmarstein@2041
|
557 |
if (!gotFileRef)
|
|
boredzo@2031
|
558 |
NSLog(CFSTR("in createURLByCopyingFileFromURLToDirectoryURL in CFGrowlAdditions: CFURLGetFSRef failed with source URL %@"), file);
|
|
ingmarstein@2041
|
559 |
else if (!gotDestRef)
|
|
boredzo@2031
|
560 |
NSLog(CFSTR("in createURLByCopyingFileFromURLToDirectoryURL in CFGrowlAdditions: CFURLGetFSRef failed with destination URL %@"), dest);
|
|
boredzo@2031
|
561 |
else {
|
|
boredzo@2020
|
562 |
OSStatus err;
|
|
boredzo@2020
|
563 |
|
|
ingmarstein@2104
|
564 |
/*
|
|
ingmarstein@2104
|
565 |
* 10.2 has a problem with weak symbols in frameworks so we use
|
|
ingmarstein@2104
|
566 |
* MAC_OS_X_VERSION_MIN_REQUIRED >= 10.3.
|
|
ingmarstein@2104
|
567 |
*/
|
|
ingmarstein@2152
|
568 |
#if defined(NSAppKitVersionNumber10_3) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3
|
|
ingmarstein@2041
|
569 |
if (FSCopyObjectSync) {
|
|
ingmarstein@2041
|
570 |
err = FSCopyObjectSync(&fileRef, &destRef, /*destName*/ NULL, &destFileRef, kFSFileOperationOverwrite);
|
|
ingmarstein@2041
|
571 |
} else {
|
|
ingmarstein@2041
|
572 |
#endif
|
|
ingmarstein@2041
|
573 |
err = GrowlCopyObjectSync(&fileRef, &destRef, &destFileRef);
|
|
ingmarstein@2152
|
574 |
#if defined(NSAppKitVersionNumber10_3) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3
|
|
ingmarstein@2041
|
575 |
}
|
|
ingmarstein@2041
|
576 |
#endif
|
|
ingmarstein@2041
|
577 |
|
|
ingmarstein@2041
|
578 |
if (err == noErr)
|
|
boredzo@2020
|
579 |
destFileURL = CFURLCreateFromFSRef(kCFAllocatorDefault, &destFileRef);
|
|
ingmarstein@2041
|
580 |
else
|
|
ingmarstein@2041
|
581 |
NSLog(CFSTR("in createURLByCopyingFileFromURLToDirectoryURL in CFGrowlAdditions: CopyObjectSync returned %li for source URL %@"), (long)err, file);
|
|
boredzo@2020
|
582 |
}
|
|
boredzo@2020
|
583 |
|
|
boredzo@2020
|
584 |
return destFileURL;
|
|
boredzo@2020
|
585 |
}
|
|
boredzo@2068
|
586 |
|
|
evands@3429
|
587 |
PLIST_TYPE createPropertyListFromURL(URL_TYPE file, u_int32_t mutability, CFPropertyListFormat *outFormat, STRING_TYPE *outErrorString)
|
|
evands@3429
|
588 |
{
|
|
boredzo@2068
|
589 |
CFPropertyListRef plist = NULL;
|
|
boredzo@2068
|
590 |
|
|
ingmarstein@2069
|
591 |
if (!file)
|
|
boredzo@2068
|
592 |
NSLog(CFSTR("in createPropertyListFromURL in CFGrowlAdditions: cannot read from a NULL URL"));
|
|
boredzo@2068
|
593 |
else {
|
|
boredzo@2068
|
594 |
CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, file);
|
|
ingmarstein@2069
|
595 |
if (!stream)
|
|
boredzo@2068
|
596 |
NSLog(CFSTR("in createPropertyListFromURL in CFGrowlAdditions: could not create stream for reading from URL %@"), file);
|
|
boredzo@2068
|
597 |
else {
|
|
ingmarstein@2069
|
598 |
if (!CFReadStreamOpen(stream))
|
|
boredzo@2068
|
599 |
NSLog(CFSTR("in createPropertyListFromURL in CFGrowlAdditions: could not open stream for reading from URL %@"), file);
|
|
boredzo@2068
|
600 |
else {
|
|
boredzo@2068
|
601 |
CFPropertyListFormat format;
|
|
boredzo@2068
|
602 |
CFStringRef errorString = NULL;
|
|
boredzo@2068
|
603 |
|
|
boredzo@2068
|
604 |
plist = CFPropertyListCreateFromStream(kCFAllocatorDefault,
|
|
boredzo@2068
|
605 |
stream,
|
|
boredzo@2068
|
606 |
/*streamLength*/ 0,
|
|
boredzo@2068
|
607 |
mutability,
|
|
boredzo@2068
|
608 |
&format,
|
|
boredzo@2068
|
609 |
&errorString);
|
|
ingmarstein@2069
|
610 |
if (!plist)
|
|
boredzo@2068
|
611 |
NSLog(CFSTR("in createPropertyListFromURL in CFGrowlAdditions: could not read property list from URL %@ (error string: %@)"), file, errorString);
|
|
boredzo@2068
|
612 |
|
|
ingmarstein@2069
|
613 |
if (outFormat) *outFormat = format;
|
|
ingmarstein@2069
|
614 |
if (errorString) {
|
|
ingmarstein@2069
|
615 |
if (outErrorString)
|
|
boredzo@2068
|
616 |
*outErrorString = errorString;
|
|
boredzo@2068
|
617 |
else
|
|
boredzo@2068
|
618 |
CFRelease(errorString);
|
|
boredzo@2068
|
619 |
}
|
|
boredzo@2068
|
620 |
|
|
boredzo@2068
|
621 |
CFReadStreamClose(stream);
|
|
boredzo@2068
|
622 |
}
|
|
boredzo@2068
|
623 |
|
|
boredzo@2068
|
624 |
CFRelease(stream);
|
|
boredzo@2068
|
625 |
}
|
|
boredzo@2068
|
626 |
}
|
|
boredzo@2068
|
627 |
|
|
boredzo@2068
|
628 |
return plist;
|
|
boredzo@2068
|
629 |
}
|