Bug Summary

File:Plugins/Bonjour/libezv/Classes/EKEzvOutgoingFileTransfer.m
Location:line 327, column 4
Description:Memory Leak
Code is compiled without garbage collection.

Annotated Source Code

1//
2// EKEzvOutgoingFileTransfer.m
3// Adium
4//
5// Created by Erich Kreutzer on 8/10/07.
6// Copyright 2007 The Adium Team. All rights reserved.
7//
8
9#import "EKEzvOutgoingFileTransfer.h"
10
11
12#define APPLE_SINGLE_HEADER_LENGTH 26
13#define APPLE_SINGLE_MAGIC_NUMBER 0x00051600
14#define APPLE_SINGLE_VERSION_NUMBER 0x00020000
15
16#define AS_ENTRY_DATA_FORK 1
17#define AS_ENTRY_RESOURCE_FORK 2
18#define AS_ENTRY_REAL_NAME 3
19#define AS_ENTRY_COMMENT 4
20#define AS_ENTRY_ICON_BW 5
21#define AS_ENTRY_ICON_COLOR 6
22#define AS_ENTRY_DATE_INFO 8
23#define AS_ENTRY_FINDER_INFO 9
24#define AS_ENTRY_MACINTOSH_FILE_INFO 10
25#define AS_ENTRY_PRODOS_FILE_INFO 11
26#define AS_ENTRY_MSDOS_FILE_INFO 12
27#define AS_ENTRY_AFP_SHORT_NAME 13
28#define AS_ENTRY_AFP_FILE_INFO 14
29#define AS_ENTRY_AFP_DIRECTORY_ID 15
30
31struct AppleSingleHeader {
32 UInt32 magicNumber;
33 UInt32 versionNumber;
34 char filler[16];
35 UInt16 numberEntries;
36};
37typedef struct AppleSingleHeader AppleSingleHeader;
38
39struct AppleSingleEntry {
40 UInt32 entryID;
41 UInt32 offset;
42 UInt32 length;
43};
44typedef struct AppleSingleEntry AppleSingleEntry;
45
46struct AppleSingleFinderInfo {
47 struct FileInfo finderInfo;
48 struct FXInfo extendedFinderInfo;
49};
50typedef struct AppleSingleFinderInfo AppleSingleFinderInfo;
51
52
53@implementation EKEzvOutgoingFileTransfer
54- (id)init
55{
56 if ((self = [super init])) {
57 urlSizes = [[NSMutableDictionary alloc] initWithCapacity:10];
58 validURLS = [[NSMutableArray alloc] initWithCapacity:10];
59 urlData = [[NSMutableDictionary alloc] initWithCapacity:10];
60 }
61 return self;
62}
63- (void)dealloc
64{
65 [urlSizes release];
66 [validURLS release];
67 [urlData release];
68 [randomString release];
69 [server release];
70
71 [super dealloc];
72}
73
74- (BOOL)isDirectory
75{
76 return isDirectory;
77}
78
79- (NSString *)posixflags
80{
81 return posixflags;
82}
83
84- (void)setContactUID:(NSString *)newUID
85{
86 if (contactUID != newUID) {
87 [contactUID release];
88 contactUID = [newUID retain];
89 }
90}
91
92- (void)startSending
93{
94 bool_Bool success = NO( BOOL ) 0;
95
96 /* Get contact from UID */
97 [self setContact:[[self manager] contactForIdentifier:contactUID]];
98
99 success = [self processTransfer];
100 if (!success) {
101 [[[[self manager] client] client] transferFailed:self];
102 return;
103 }
104
105 success = [self getData];
106 if (!success) {
107 [[[[self manager] client] client] transferFailed:self];
108 return;
109 }
110
111 /* We need to start the server */
112 success = [self startHTTPServer];
113 if (!success) {
114 [[[[self manager] client] client] transferFailed:self];
115 return;
116 }
117
118 /* Now we send the correct information to the contact */
119 [self sendTransferMessage];
120
121 /* Keep ourself around until the transfer is complete or cancelled */
122 [self retain];
123}
124
125- (void)stopSending
126{
127 [server stop];
128
129 /* We called -[self retain] in startSending */
130 [self autorelease];
131}
132
133- (bool_Bool) processTransfer
134{
135 /*Check to see if it is a directory, mimetype, etc... */
136 NSString *path = [self localFilename];
137 BOOL directory = NO( BOOL ) 0;
138 BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&directory];
139 if (!exists) {
140 [self cancelTransfer];
141 return NO( BOOL ) 0;
142 }
143 if (directory) {
144 isDirectory = YES( BOOL ) 1;
145 }
146
147 [self setMimeType:[self mimeTypeForPath:path]];
148 posixflags = [self posixFlagsForPath:path];
149
150 if (posixflags == nil0) {
151 return NO( BOOL ) 0;
152 }
153
154 return YES( BOOL ) 1;
155}
156
157- (bool_Bool)getData
158{
159 /*Let's load the data from disk into the urlData dictionary */
160 if (!isDirectory) {
161 /*Only one file so let's add the path */
162
163 [urlData setObject:[self localFilename] forKey:[[self localFilename] lastPathComponent]];
164
165 } else {
166 /* We will need to update the size of the transfer so let's set it to 0 so we can add to it */
167 [self setSize:0u];
168
169 /*First we need to get the NSData for the xml to describe the directory contents*/
170 directoryXMLData = [[self generateDirectoryXML] retain];
171 /* Now we need to get the NSData for each item in the directory */
172 NSFileManager *fileManager = [NSFileManager defaultManager];
173 NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:[self localFilename]];
174 NSString *file;
175 NSString *basePath = [[self localFilename] stringByAppendingString:@"/"];
176 while (file = [enumerator nextObject]) {
177 NSString *fullPath = [basePath stringByAppendingString:file];
178
179 BOOL exists = NO( BOOL ) 0;
180 BOOL directory = NO( BOOL ) 0;
181 exists = [fileManager fileExistsAtPath:fullPath isDirectory:&directory];
182 if (!exists) {
183 [[[[self manager] client] client] reportError:@"File to transfer no longer exists." ofLevel:AWEzvError];
184
185 return nil0;
186 }
187 if (!directory && ![file hasPrefix:@".DS_Store"]) {
188 NSString *subPath = [[[[self localFilename] lastPathComponent] stringByAppendingString:@"/"] stringByAppendingString: file];
189
190 /*Reset the size */
191 NSNumber *sizeNumber = [self sizeNumberForPath:fullPath];
192 if (sizeNumber) {
193 [urlSizes setObject:sizeNumber forKey:subPath];
194 [self setSize:[self size] + [sizeNumber unsignedLongLongValue]];
195 }
196
197 [urlData setObject:fullPath forKey:subPath];
198 }
199 }
200 }
201 return YES( BOOL ) 1;
202}
203
204- (bool_Bool) startHTTPServer
205{
206 server = [[HTTPServer alloc] init];
207
208 NSError *error;
209 BOOL success = [server start:&error];
210
211 if (!success)
212 {
213 [[[[self manager] client] client] reportError:@"Could not start HTTP Server." ofLevel:AWEzvError];
214 return NO( BOOL ) 0;
215 } else {
216 [server setTransfer: self];
217 return YES( BOOL ) 1;
218 }
219}
220
221- (void)sendTransferMessage
222{
223 [[self contact] sendOutgoingFileTransfer: self];
224}
225
226#pragma mark Support Methods
227
228- (NSData *)generateDirectoryXML
229{
230 /*Example XML:
231 * <dir posixflags="01ED"> <name>untitled folder</name>
232 * <file mimetype="application/rtf" size="318"> <name>blah copy.rtf</name></file>
233 * <file mimetype="application/rtf" size="318"> <name>blah.rtf</name></file>
234 * <dir posixflags="01ED"> <name>folder</name>
235 * </dir>
236 * </dir>
237 **/
238 NSString *newPath = [self localFilename];
239 /*Create the dir */
240 NSXMLElement *root = [[NSXMLElement alloc] initWithName:@"dir"];
241 NSString *posixFlags = [self posixFlagsForPath: newPath];
242 if (posixFlags != nil0) {
243 [root addAttribute:[NSXMLNode attributeWithName:@"posixflags" stringValue:posixFlags]];
244 }
245
246 /*Add the name */
247 NSXMLElement *name = [[NSXMLElement alloc] initWithName:@"name" stringValue:[newPath lastPathComponent]];
248 [root addChild:name];
249 NSArray *children = [self generateXMLFromDirectory:newPath];
250
251 NSEnumerator *enumerator = [children objectEnumerator];
252 NSXMLElement *child;
253 while (child = [enumerator nextObject]) {
254 [root addChild:child];
255 }
256
257 NSString *xmlString = [root XMLString];
258 return [NSData dataWithBytes:[xmlString UTF8String] length:[xmlString length]];
259}
260
261- (NSArray *)generateXMLFromDirectory:(NSString *)basePath
262{
263 /*Example XML:
264 * <dir posixflags="01ED"> <name>untitled folder</name>
265 * <file mimetype="application/rtf" size="318"> <name>blah copy.rtf</name></file>
266 * <file mimetype="application/rtf" size="318"> <name>blah.rtf</name></file>
267 * <dir posixflags="01ED"> <name>folder</name>
268 * </dir>
269 * </dir>
270 **/
271 NSMutableArray *children = [NSMutableArray arrayWithCapacity:10];
272 NSFileManager *fileManager = [NSFileManager defaultManager];
273 NSEnumerator *enumerator = [[fileManager directoryContentsAtPath:basePath] objectEnumerator];
274
275 NSString *file;
[1] Loop condition is true. Entering loop body.
[7] Loop condition is true. Entering loop body.
[13] Loop condition is true. Entering loop body.
276 while (file = [enumerator nextObject]) {
277 NSString *newPath = [basePath stringByAppendingPathComponent:file];
278 bool_Bool exists = NO( BOOL ) 0;
279 bool_Bool directory = NO( BOOL ) 0;
280 exists = [fileManager fileExistsAtPath:newPath isDirectory:&directory];
[2] Taking false branch.
[8] Taking false branch.
[14] Taking false branch.
281 if (!exists) {
282 [[[[self manager] client] client] reportError:@"File to transfer no longer exists." ofLevel:AWEzvError];
283 return nil0;
284 }
[3] Taking false branch.
[9] Taking false branch.
[15] Taking false branch.
285 if ([file hasPrefix:@".DS_Store"]) {
286 continue;
287 }
288
[4] Taking true branch.
[10] Taking true branch.
[16] Taking false branch.
289 if (directory) {
290 // handle the creation of the directory xml
291 NSXMLElement *directory = [[NSXMLElement alloc] initWithName:@"dir"];
292 NSString *posixFlags = [self posixFlagsForPath: newPath];
[5] Taking false branch.
[11] Taking false branch.
293 if (posixFlags != nil0) {
294 [directory addAttribute:[NSXMLNode attributeWithName:@"posixflags" stringValue:posixFlags]];
295 }
296
297 NSXMLElement *name = [[NSXMLElement alloc] initWithName:@"name" stringValue:file];
298 [directory addChild:name];
299
300 NSArray *dirChildren = [self generateXMLFromDirectory:newPath];
301
302 NSEnumerator *dirEnumerator = [dirChildren objectEnumerator];
303 NSXMLElement *child;
[6] Loop condition is false.Execution continues on line 308.
[12] Loop condition is false.Execution continues on line 308.
304 while (child = [dirEnumerator nextObject]) {
305 [directory addChild:child];
306 }
307
308 [children addObject:directory];
309 } else {
310 // create the file xml
311 NSXMLElement *fileXML = [[NSXMLElement alloc] initWithName:@"file"];
312 NSString *mimeTypeString = [self mimeTypeForPath:newPath];
[17] Taking false branch.
313 if (mimeType != nil0) {
314 [fileXML addAttribute:[NSXMLNode attributeWithName:@"mimetype" stringValue:mimeTypeString]];
315 }
316
317 NSString *posixFlags = [self posixFlagsForPath:newPath];
[18] Taking false branch.
318 if (posixFlags != nil0) {
319 [fileXML addAttribute:[NSXMLNode attributeWithName:@"posixflags" stringValue:posixFlags]];
320 }
321 NSString *sizeString = [self sizeForPath:newPath];
[19] Taking false branch.
322 if (size != nil0) {
323 [fileXML addAttribute:[NSXMLNode attributeWithName:@"size" stringValue:sizeString]];
324 }
325
[20] Method returns an object with a +1 retain count (owning reference).
326 NSXMLElement *name = [[NSXMLElement alloc] initWithName:@"name" stringValue:file];
327 [fileXML addChild:name];
[21] Object allocated on line 326 and stored into 'name' is no longer referenced after this point and has a retain count of +1 (object leaked).
328
329 /*Now add this to the array */
330 [children addObject:fileXML];
331 }
332 }
333 return children;
334}
335- (NSString *)baseURL
336{
337
338 NSString *component = [NSString stringWithFormat:@"http://%@:%hu", [server localHost], [server port]];
339
340 NSString *URI = @"/";
341
342 URI = [URI stringByAppendingString:[[NSProcessInfo processInfo] globallyUniqueString]];
343
344 randomString = [[URI stringByAppendingString:@"/"] retain];
345
346 URI = [URI stringByAppendingPathComponent:[[[self localFilename] lastPathComponent] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
347 if (isDirectory)
348 URI = [URI stringByAppendingString:@"/"];
349
350 [validURLS addObject:URI];
351
352 component = [component stringByAppendingString:URI];
353
354 return component;
355}
356- (BOOL)isBaseURIForDirectoryTransfer:(NSString *)URI
357{
358 BOOL isBase = NO( BOOL ) 0;
359 if ([URI hasPrefix:randomString] && ([URI length] > [randomString length])) {
360 NSString *path = [URI substringFromIndex:[randomString length]];
361 if ([path isEqualToString:[[[self localFilename] lastPathComponent] stringByAppendingString:@"/"]]) {
362 isBase = YES( BOOL ) 1;
363 }
364 }
365 return isBase;
366}
367- (BOOL)isValidURI:(NSString *)URI
368{
369 bool_Bool isValid = NO( BOOL ) 0;
370 isValid = [validURLS containsObject:URI];
371 if (!isValid) {
372 [[[[self manager] client] client] reportError:@"Client requested an invalid file." ofLevel:AWEzvError];
373 }
374 return isValid;
375}
376
377- (NSData *)appleSingleDataForURI:(NSString *)URI
378{
379 NSString *filePath = nil0;
380 NSNumber *singleSize = nil0;
381 if ([URI hasPrefix:randomString] && ([URI length] > [randomString length])) {
382 NSString *path = [URI substringFromIndex:[randomString length]];
383 filePath = [[[self localFilename] stringByDeletingLastPathComponent] stringByAppendingPathComponent: path];
384 singleSize = [urlSizes valueForKey:path];
385 }
386
387
388 /*Include the three entries that iChat includes */
389 struct AppleSingleHeader info;
390 memset(&info, 0, sizeof(info));
391 info.magicNumber = htonl( __builtin_constant_p ( 0x00051600 ) ? ( ( uint32_t ) ( ( ( (
uint32_t ) ( 0x00051600 ) & 0xff000000 ) >> 24 ) |
( ( ( uint32_t ) ( 0x00051600 ) & 0x00ff0000 ) >> 8
) | ( ( ( uint32_t ) ( 0x00051600 ) & 0x0000ff00 ) <<
8 ) | ( ( ( uint32_t ) ( 0x00051600 ) & 0x000000ff ) <<
24 ) ) ) : _OSSwapInt32 ( 0x00051600 ) )
(APPLE_SINGLE_MAGIC_NUMBER);
392 info.versionNumber = htonl( __builtin_constant_p ( 0x00020000 ) ? ( ( uint32_t ) ( ( ( (
uint32_t ) ( 0x00020000 ) & 0xff000000 ) >> 24 ) |
( ( ( uint32_t ) ( 0x00020000 ) & 0x00ff0000 ) >> 8
) | ( ( ( uint32_t ) ( 0x00020000 ) & 0x0000ff00 ) <<
8 ) | ( ( ( uint32_t ) ( 0x00020000 ) & 0x000000ff ) <<
24 ) ) ) : _OSSwapInt32 ( 0x00020000 ) )
(APPLE_SINGLE_VERSION_NUMBER);
393 info.numberEntries = htons( __builtin_constant_p ( 3 ) ? ( ( uint16_t ) ( ( ( ( uint16_t
) ( 3 ) & 0xff00 ) >> 8 ) | ( ( ( uint16_t ) ( 3 )
& 0x00ff ) << 8 ) ) ) : _OSSwapInt16 ( 3 ) )
(3);
394
395 /* Setup the three AppleSingleEntrys */
396 struct AppleSingleEntry finderInfoEntry;
397 struct AppleSingleEntry realNameEntry;
398 struct AppleSingleEntry dataEntry;
399
400 memset(&finderInfoEntry, 0, sizeof(finderInfoEntry));
401 memset(&realNameEntry, 0, sizeof(realNameEntry));
402 memset(&dataEntry, 0, sizeof(dataEntry));
403
404 unsigned long long offset = APPLE_SINGLE_HEADER_LENGTH26 + sizeof(finderInfoEntry) * 3;
405 /*Finder info */
406 /*Get the info from the finder */
407 FSRef ref;
408 FSCatalogInfo catalogInfo;
409 OSStatus err;
410 BOOL itemIsDirectory = NO( BOOL ) 0;
411 err = FSPathMakeRef((const UInt8 *)[filePath fileSystemRepresentation], &ref, &itemIsDirectory);
412 if (err != noErr) {
413 [[[[self manager] client] client] reportError:@"AppleSingle: Error creating FSRef" ofLevel:AWEzvError];
414 return nil0;
415 }
416 err = FSGetCatalogInfo (/*const FSRef * ref*/ &ref,
417 /*FSCatalogInfoBitmap whichInfo*/ (kFSCatInfoFinderInfo | kFSCatInfoFinderXInfo),
418 /*FSCatalogInfo * catalogInfo*/ &catalogInfo,
419 /*HFSUniStr255 * outName*/ NULL( ( void * ) 0 ),
420 /*FSSpec * fsSpec*/ NULL( ( void * ) 0 ),
421 /*FSRef * parentRef*/ NULL( ( void * ) 0 ));
422 if (err != noErr) {
423 [[[[self manager] client] client] reportError:@"AppleSingle: Error creating FSRef" ofLevel:AWEzvError];
424 return nil0;
425 }
426
427 /*Use the info from finder to create the AppleSingleFinderInfo struct */
428 struct AppleSingleFinderInfo fileInfo;
429 memset(&fileInfo, 0, sizeof(fileInfo));
430 BlockMoveData(&(catalogInfo.finderInfo), &(fileInfo.finderInfo), sizeof((fileInfo.finderInfo)));
431 BlockMoveData(&(catalogInfo.extFinderInfo), &(fileInfo.extendedFinderInfo), sizeof((fileInfo.extendedFinderInfo)));
432
433 /*Now switch from host to network byte order */
434 fileInfo.finderInfo.finderFlags = htons( __builtin_constant_p ( fileInfo . finderInfo . finderFlags )
? ( ( uint16_t ) ( ( ( ( uint16_t ) ( fileInfo . finderInfo .
finderFlags ) & 0xff00 ) >> 8 ) | ( ( ( uint16_t )
( fileInfo . finderInfo . finderFlags ) & 0x00ff ) <<
8 ) ) ) : _OSSwapInt16 ( fileInfo . finderInfo . finderFlags
) )
(fileInfo.finderInfo.finderFlags);
435
436 /*Create the AppleSingleEntry for this data */
437 finderInfoEntry.entryID = htonl( __builtin_constant_p ( 9 ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( 9 ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t ) (
9 ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t ) ( 9 )
& 0x0000ff00 ) << 8 ) | ( ( ( uint32_t ) ( 9 ) &
0x000000ff ) << 24 ) ) ) : _OSSwapInt32 ( 9 ) )
(AS_ENTRY_FINDER_INFO);
438 finderInfoEntry.length = htonl( __builtin_constant_p ( sizeof ( fileInfo ) ) ? ( ( uint32_t
) ( ( ( ( uint32_t ) ( sizeof ( fileInfo ) ) & 0xff000000
) >> 24 ) | ( ( ( uint32_t ) ( sizeof ( fileInfo ) ) &
0x00ff0000 ) >> 8 ) | ( ( ( uint32_t ) ( sizeof ( fileInfo
) ) & 0x0000ff00 ) << 8 ) | ( ( ( uint32_t ) ( sizeof
( fileInfo ) ) & 0x000000ff ) << 24 ) ) ) : _OSSwapInt32
( sizeof ( fileInfo ) ) )
(sizeof(fileInfo));
439 /*Offset so that it is at the end of the *3* AppleSingleEntries*/
440 finderInfoEntry.offset = htonl( __builtin_constant_p ( offset ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( offset ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t
) ( offset ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t
) ( offset ) & 0x0000ff00 ) << 8 ) | ( ( ( uint32_t
) ( offset ) & 0x000000ff ) << 24 ) ) ) : _OSSwapInt32
( offset ) )
(offset);
441 offset += sizeof(fileInfo);
442
443 /*Real Name*/
444 const char *realName = [[URI lastPathComponent] UTF8String];
445 unsigned nameLength = [[URI lastPathComponent] length];
446
447 realNameEntry.entryID = htonl( __builtin_constant_p ( 3 ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( 3 ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t ) (
3 ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t ) ( 3 )
& 0x0000ff00 ) << 8 ) | ( ( ( uint32_t ) ( 3 ) &
0x000000ff ) << 24 ) ) ) : _OSSwapInt32 ( 3 ) )
(AS_ENTRY_REAL_NAME);
448 realNameEntry.length = htonl( __builtin_constant_p ( nameLength ) ? ( ( uint32_t ) ( ( ( (
uint32_t ) ( nameLength ) & 0xff000000 ) >> 24 ) |
( ( ( uint32_t ) ( nameLength ) & 0x00ff0000 ) >> 8
) | ( ( ( uint32_t ) ( nameLength ) & 0x0000ff00 ) <<
8 ) | ( ( ( uint32_t ) ( nameLength ) & 0x000000ff ) <<
24 ) ) ) : _OSSwapInt32 ( nameLength ) )
(nameLength);
449 /*Offset so that it is at the end of the *3* AppleSingleEntries*/
450 realNameEntry.offset = htonl( __builtin_constant_p ( offset ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( offset ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t
) ( offset ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t
) ( offset ) & 0x0000ff00 ) << 8 ) | ( ( ( uint32_t
) ( offset ) & 0x000000ff ) << 24 ) ) ) : _OSSwapInt32
( offset ) )
(offset);
451
452 offset += nameLength;
453 unsigned long long newSize;
454 if ([self isDirectory]) {
455 newSize = [singleSize unsignedLongLongValue];
456 } else {
457 newSize = [self size];
458 }
459 /*Data resource fork */
460 dataEntry.entryID = htonl( __builtin_constant_p ( 1 ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( 1 ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t ) (
1 ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t ) ( 1 )
& 0x0000ff00 ) << 8 ) | ( ( ( uint32_t ) ( 1 ) &
0x000000ff ) << 24 ) ) ) : _OSSwapInt32 ( 1 ) )
(AS_ENTRY_DATA_FORK);
461 dataEntry.length = htonl( __builtin_constant_p ( newSize ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( newSize ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t
) ( newSize ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t
) ( newSize ) & 0x0000ff00 ) << 8 ) | ( ( ( uint32_t
) ( newSize ) & 0x000000ff ) << 24 ) ) ) : _OSSwapInt32
( newSize ) )
(newSize);
462 dataEntry.offset = htonl( __builtin_constant_p ( offset ) ? ( ( uint32_t ) ( ( ( ( uint32_t
) ( offset ) & 0xff000000 ) >> 24 ) | ( ( ( uint32_t
) ( offset ) & 0x00ff0000 ) >> 8 ) | ( ( ( uint32_t
) ( offset ) & 0x0000ff00 ) << 8 ) | ( ( ( uint32_t
) ( offset ) & 0x000000ff ) << 24 ) ) ) : _OSSwapInt32
( offset ) )
(offset);
463
464 NSMutableData *data = [NSMutableData dataWithBytes:&info length: APPLE_SINGLE_HEADER_LENGTH26];
465 [data appendBytes:&finderInfoEntry length:sizeof(finderInfoEntry)];
466 [data appendBytes:&realNameEntry length:sizeof(realNameEntry)];
467 [data appendBytes:&dataEntry length:sizeof(dataEntry)];
468 [data appendBytes:&fileInfo length:sizeof(fileInfo)];
469 [data appendBytes:realName length:nameLength];
470 /*Data will be appended in the HTTPServer*/
471 return data;
472}
473- (NSString *)fileDataForURI:(NSString *)URI
474{
475 NSString *data = nil0;
476 if ([URI hasPrefix:randomString] && ([URI length] > [randomString length])) {
477 NSString *path = [URI substringFromIndex:[randomString length]];
478 data = [(NSString *)[urlData valueForKey:path] retain];
479 [urlData removeObjectForKey:path];
480 }
481 return data;
482}
483
484- (NSString *)posixFlagsForPath:(NSString *)filePath
485{
486 NSString *posixFlags = nil0;
487 NSDictionary *attributes = [[NSFileManager defaultManager] fileAttributesAtPath:filePath traverseLink:NO( BOOL ) 0];
488 if (attributes && [attributes objectForKey:NSFilePosixPermissions]) {
489 NSNumber *posixInfo = [attributes objectForKey:NSFilePosixPermissions];
490 posixFlags = [NSString stringWithFormat:@"%X", [posixInfo longValue]];
491 }
492
493 return posixFlags;
494}
495
496- (NSString *)mimeTypeForPath:(NSString *)filePath
497{
498 NSString *mime = nil0;
499 NSString *UTI = [(NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
500 (CFStringRef)[filePath pathExtension],
501 NULL( ( void * ) 0 )) autorelease];
502 mime = [(NSString *)UTTypeCopyPreferredTagWithClass((CFStringRef)UTI, kUTTagClassMIMEType) autorelease];
503 if (!mime || [mime length] == 0)
504 {
505 mime = @"application/octet-stream";
506 }
507 return mime;
508}
509
510- (NSString *)sizeForPath:(NSString *)filePath
511{
512 NSString *fileSize = nil0;
513 NSDictionary *attributes = [[NSFileManager defaultManager] fileAttributesAtPath:filePath traverseLink:NO( BOOL ) 0];
514 if (attributes && [attributes objectForKey:NSFileSize]) {
515 NSNumber *fileSizeNumber = [attributes objectForKey:NSFileSize];
516 fileSize = [NSString stringWithFormat:@"%qu", [fileSizeNumber unsignedLongLongValue]];
517 }
518
519 return fileSize;
520}
521
522- (NSNumber *)sizeNumberForPath:(NSString *)filePath
523{
524 NSNumber *fileSize = nil0;
525 NSDictionary *attributes = [[NSFileManager defaultManager] fileAttributesAtPath:filePath traverseLink:NO( BOOL ) 0];
526 if (attributes && [attributes objectForKey:NSFileSize]) {
527 fileSize = [attributes objectForKey:NSFileSize];
528 }
529
530 return fileSize;
531}
532
533- (void)cancelTransfer
534{
535 [self stopSending];
536}
537
538- (void)userFailedDownload
539{
540 [[[[self manager] client] client] remoteCanceledFileTransfer:self];
541}
542- (void)userBeganDownload
543{
544 [[[[self manager] client] client] remoteUserBeganDownload:self];
545}
546
547- (void)userFinishedDownload
548{
549 /* Cleanup the data lying around */
550 [self stopSending];
551
552 [[[[self manager] client] client] remoteUserFinishedDownload:self];
553}
554
555- (void)didSendDataWithLength:(UInt32)length
556{
557 bytesSent = bytesSent+length;
558 percentComplete = ((float)bytesSent/(float)[[self sizeNumber] floatValue]);
559 if (percentComplete < 1.0) {
560 [[[[self manager] client] client] updateProgressForFileTransfer:self
561 percent:[NSNumber numberWithFloat:percentComplete]
562 bytesSent:[NSNumber numberWithLongLong:bytesSent]];
563 }
564}
565
566- (BOOL)moreFilesToDownload
567{
568 BOOL more = NO( BOOL ) 0;
569 if (isDirectory && urlData)
570 more = ([urlData count] > 0);
571 return more;
572}
573
574- (NSData *)directoryXMLData
575{
576 return directoryXMLData;
577}
578@end