├── Classes ├── DetailViewController.h ├── DetailViewController.m ├── FSItem.h ├── FSItem.m ├── FSItemCell.h ├── FSItemCell.m ├── FSWalkerAppDelegate.h ├── FSWalkerAppDelegate.m ├── InfoPanelController.h ├── InfoPanelController.m ├── NSNumber+Bytes.h ├── NSNumber+Bytes.m ├── RootViewController.h └── RootViewController.m ├── CocoaHTTPServer ├── AsyncSocket.h ├── AsyncSocket.m ├── DDData.h ├── DDData.m ├── DDNumber.h ├── DDNumber.m ├── DDRange.h ├── DDRange.m ├── HTTPAuthenticationRequest.h ├── HTTPAuthenticationRequest.m ├── HTTPConnection.h ├── HTTPConnection.m ├── HTTPResponse.h ├── HTTPResponse.m ├── HTTPServer.h └── HTTPServer.m ├── Default.png ├── DetailViewController.xib ├── FSItemCell.xib ├── FSWHTTPConnection.h ├── FSWHTTPConnection.m ├── FSWalker.xcodeproj ├── nst.pbxuser ├── nst.perspectivev3 └── project.pbxproj ├── FSWalker_Prefix.pch ├── GenericDocumentIcon.png ├── GenericFolderIcon.png ├── GenericFolderIcon@2x.png ├── Icon.png ├── Icon@2x.png ├── Info.plist ├── InfoPanelController.xib ├── MainWindow.xib ├── MyIP.h ├── MyIP.m ├── README.md ├── RootViewController.xib ├── Settings.bundle ├── Root.plist └── en.lproj │ └── Root.strings ├── SymLinkIcon.png ├── WebServerIcons ├── back.gif ├── blank.gif ├── folder.gif ├── generic.gif ├── image2.gif ├── pdf.gif └── text.gif ├── art ├── FolderGnuSteps.acorn └── GenericFolder.png ├── main.m └── screenshots ├── screenshot_1.png ├── screenshot_2.png ├── screenshot_3.png └── web_page.png /Classes/DetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 01.02.09. 6 | // Copyright 2009 Sen:te. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FSItem; 12 | 13 | @interface DetailViewController : UIViewController { 14 | FSItem *fsItem; 15 | 16 | IBOutlet UITextView *textView; 17 | IBOutlet UIImageView *imageView; 18 | } 19 | 20 | @property (nonatomic, retain) FSItem *fsItem; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Classes/DetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 01.02.09. 6 | // Copyright 2009 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "DetailViewController.h" 10 | #import "FSItem.h" 11 | #import 12 | 13 | @implementation DetailViewController 14 | 15 | @synthesize fsItem; 16 | 17 | 18 | /* 19 | // The designated initializer. Override to perform setup that is required before the view is loaded. 20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 21 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 22 | // Custom initialization 23 | } 24 | return self; 25 | } 26 | */ 27 | 28 | /* 29 | // Implement loadView to create a view hierarchy programmatically, without using a nib. 30 | - (void)loadView { 31 | } 32 | */ 33 | 34 | /* 35 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 36 | - (void)viewDidLoad { 37 | [super viewDidLoad]; 38 | } 39 | */ 40 | 41 | - (void)viewWillAppear:(BOOL)animated { // Called when the view is about to made visible. Default does nothing 42 | self.title = fsItem.prettyFilename; 43 | } 44 | 45 | 46 | - (void)viewDidAppear:(BOOL)animated { // Called when the view has been fully transitioned onto the screen. Default does nothing 47 | NSArray *imageExt = [NSArray arrayWithObjects:@"png", @"pdf", @"jpg", @"gif", nil]; 48 | NSArray *soundExt = [NSArray arrayWithObjects:@"m4r", @"caf", @"wav", @"aiff", nil]; 49 | 50 | NSString *ext = [[fsItem.filename pathExtension] lowercaseString]; 51 | 52 | if([ext isEqualToString:@"plist"]) { 53 | id plist = [NSDictionary dictionaryWithContentsOfFile:fsItem.path]; 54 | if(!plist) plist = [NSArray arrayWithContentsOfFile:fsItem.path]; 55 | if(!plist) return; 56 | 57 | BOOL txtFormat = ![[NSUserDefaults standardUserDefaults] boolForKey:@"XMLPlist"]; 58 | 59 | if(txtFormat) { 60 | textView.text = [plist description]; 61 | return; 62 | } 63 | 64 | NSString *errorString = nil; 65 | NSData *data = [NSPropertyListSerialization dataFromPropertyList:plist format:kCFPropertyListXMLFormat_v1_0 errorDescription:&errorString]; 66 | if(errorString) { 67 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error: can't open file" 68 | message:errorString 69 | delegate:nil 70 | cancelButtonTitle:@"OK" 71 | otherButtonTitles: nil]; 72 | [alert show]; 73 | [alert release]; 74 | 75 | [errorString release]; 76 | } else { 77 | textView.text = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; 78 | } 79 | } else if([imageExt containsObject:ext]) { 80 | imageView.image = [UIImage imageWithContentsOfFile:fsItem.path]; 81 | } else if ([soundExt containsObject:ext]) { 82 | // TODO: handle sound 83 | // file:///Developer/Platforms/iPhoneOS.platform/Developer/Documentation/DocSets/com.apple.adc.documentation.AppleiPhone2_2.iPhoneLibrary.docset/Contents/Resources/Documents/samplecode/SysSound/listing4.html 84 | NSLog(@"-- TODO: play %@", fsItem.filename); 85 | 86 | SystemSoundID soundFileObject; 87 | CFURLRef urlRef = CFURLCreateWithString(NULL, (CFStringRef) fsItem.path, NULL); 88 | 89 | AudioServicesCreateSystemSoundID (urlRef, &soundFileObject); 90 | AudioServicesPlaySystemSound (soundFileObject); 91 | AudioServicesDisposeSystemSoundID (soundFileObject); 92 | CFRelease (urlRef); 93 | } else { 94 | NSError *e = nil; 95 | NSString *s = [NSString stringWithContentsOfFile:fsItem.path encoding:NSUTF8StringEncoding error:&e]; 96 | if(e) { // try again 97 | e = nil; 98 | s = [NSString stringWithContentsOfFile:fsItem.path encoding:NSISOLatin1StringEncoding error:&e]; 99 | } 100 | 101 | if(!e && s) { 102 | imageView.image = nil; 103 | textView.text = s; 104 | } else if (e) { 105 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error: can't open file" 106 | message:[e localizedDescription] 107 | delegate:nil 108 | cancelButtonTitle:@"OK" 109 | otherButtonTitles: nil]; 110 | [alert show]; 111 | [alert release]; 112 | } 113 | } 114 | } 115 | 116 | - (void)viewDidDisappear:(BOOL)animated { // Called after the view was dismissed, covered or otherwise hidden. Default does nothing 117 | imageView.image = nil; 118 | textView.text = @""; 119 | } 120 | 121 | /* 122 | // Override to allow orientations other than the default portrait orientation. 123 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 124 | // Return YES for supported orientations 125 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 126 | } 127 | */ 128 | 129 | - (void)didReceiveMemoryWarning { 130 | [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview 131 | // Release anything that's not essential, such as cached data 132 | } 133 | 134 | 135 | - (void)dealloc { 136 | [fsItem release]; 137 | [super dealloc]; 138 | } 139 | 140 | 141 | @end 142 | -------------------------------------------------------------------------------- /Classes/FSItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSItem.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface FSItem : NSObject { 13 | NSString *parent; 14 | NSString *filename; 15 | NSDictionary *attributes; 16 | NSArray *children; 17 | NSString *path; 18 | } 19 | 20 | @property(retain) NSString *parent; 21 | @property(retain) NSString *filename; 22 | @property(retain) NSDictionary *attributes; 23 | @property(retain) NSArray *children; 24 | @property(retain) NSString *path; 25 | 26 | @property(readonly) NSString *prettyFilename; 27 | @property(readonly) UIImage *icon; 28 | //@property(readonly) UIImage *image; 29 | @property(readonly) NSDate *modificationDate; 30 | @property(readonly) NSString *ownerName; 31 | @property(readonly) NSString *groupName; 32 | @property(readonly) NSString *posixPermissions; 33 | @property(readonly) NSDate *creationDate; 34 | @property(readonly) NSString *fileSize; 35 | @property(readonly) NSString *ownerAndGroup; 36 | 37 | @property(readonly) BOOL isDirectory; 38 | @property(readonly) BOOL isSymbolicLink; 39 | @property(readonly) BOOL canBeFollowed; 40 | 41 | + (FSItem *)fsItemWithDir:(NSString *)dir fileName:(NSString *)fileName; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Classes/FSItem.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSItem.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "FSItem.h" 10 | 11 | @implementation FSItem 12 | 13 | @synthesize parent; 14 | @synthesize filename; 15 | @synthesize attributes; 16 | @synthesize path; 17 | @dynamic children; 18 | @dynamic prettyFilename; 19 | @dynamic icon; 20 | @dynamic modificationDate; 21 | @dynamic ownerName; 22 | @dynamic groupName; 23 | @dynamic posixPermissions; 24 | @dynamic creationDate; 25 | @dynamic fileSize; 26 | @dynamic ownerAndGroup; 27 | @dynamic isSymbolicLink; 28 | 29 | - (BOOL)canBeFollowed { 30 | 31 | if([[self posixPermissions] intValue] == 0) return NO; 32 | 33 | if(self.isDirectory) return YES; 34 | 35 | if(self.isSymbolicLink) { 36 | NSFileManager *fm = [NSFileManager defaultManager]; 37 | NSError *e = nil; 38 | NSString *destPath = [fm destinationOfSymbolicLinkAtPath:self.path error:&e]; 39 | if(e || !destPath) return NO; 40 | return [fm contentsOfDirectoryAtPath:destPath error:nil] != nil; 41 | } 42 | 43 | return NO; 44 | } 45 | 46 | - (UIImage *)icon { 47 | if(self.isDirectory) { 48 | return [UIImage imageNamed:@"GenericFolderIcon.png"]; 49 | } else if (self.isSymbolicLink) { 50 | return [UIImage imageNamed:@"SymLinkIcon.png"]; 51 | } else { 52 | return [UIImage imageNamed:@"GenericDocumentIcon.png"]; 53 | } 54 | } 55 | /* 56 | - (UIImage *)image { 57 | if(self.isDirectory) { 58 | return [UIImage imageNamed:@"GenericFolder.png"]; 59 | } else if (self.isSymbolicLink) { 60 | return [UIImage imageNamed:@"SymLink.png"]; 61 | } else { 62 | return [UIImage imageNamed:@"GenericDocument.png"]; 63 | } 64 | } 65 | */ 66 | 67 | - (NSArray *)children { 68 | if(children == nil) { 69 | NSArray *childrenFilenames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self.parent stringByAppendingPathComponent:self.filename] error:nil]; 70 | NSMutableArray *a = [[NSMutableArray alloc] init]; 71 | for(NSString *fn in childrenFilenames) { 72 | FSItem *child = [FSItem fsItemWithDir:[parent stringByAppendingPathComponent:filename] fileName:fn]; 73 | [a addObject:child]; 74 | } 75 | self.children = a; 76 | [a release]; 77 | } 78 | return children; 79 | } 80 | 81 | - (void)setChildren:(NSArray *)someChildren { 82 | [children autorelease]; 83 | children = [someChildren retain]; 84 | } 85 | 86 | - (void)dealloc { 87 | [parent release]; 88 | [filename release]; 89 | [attributes release]; 90 | [children release]; 91 | [path release]; 92 | [super dealloc]; 93 | } 94 | 95 | - (BOOL)isDirectory { 96 | return [[attributes objectForKey:NSFileType] isEqualToString:NSFileTypeDirectory]; 97 | } 98 | 99 | - (BOOL)isSymbolicLink { 100 | return [[attributes objectForKey:NSFileType] isEqualToString:NSFileTypeSymbolicLink]; 101 | } 102 | 103 | - (NSString *)prettyFilename { 104 | return [filename isEqualToString:@""] ? @"/" : filename; 105 | } 106 | 107 | + (FSItem *)fsItemWithDir:(NSString *)dir fileName:(NSString *)fileName { 108 | FSItem *i = [[FSItem alloc] init]; 109 | i.parent = dir; 110 | i.filename = fileName; 111 | i.path = [dir stringByAppendingPathComponent:fileName]; 112 | i.attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:i.path error:nil]; 113 | return [i autorelease]; 114 | } 115 | 116 | - (NSDate *)modificationDate { 117 | return [self.attributes objectForKey:NSFileModificationDate]; 118 | } 119 | 120 | - (NSString *)ownerName { 121 | return [self.attributes objectForKey:NSFileOwnerAccountName]; 122 | } 123 | 124 | - (NSString *)groupName { 125 | return [self.attributes objectForKey:NSFileGroupOwnerAccountName]; 126 | } 127 | 128 | - (NSString *)posixPermissions { 129 | NSNumber *n = [self.attributes objectForKey:NSFilePosixPermissions]; 130 | return [NSString stringWithFormat:@"%O", [n unsignedLongValue]]; 131 | } 132 | 133 | - (NSDate *)creationDate { 134 | return [self.attributes objectForKey:NSFileCreationDate]; 135 | } 136 | 137 | - (NSString *)fileSize { 138 | return [self.attributes objectForKey:NSFileSize]; 139 | } 140 | 141 | - (NSString *)ownerAndGroup { 142 | return [NSString stringWithFormat:@"%@ %@", self.ownerName, self.groupName]; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /Classes/FSItemCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSItemCell.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSItem.h" 11 | 12 | @interface FSItemCell : UITableViewCell { 13 | FSItem *fsItem; 14 | IBOutlet UIButton *iconButton; 15 | IBOutlet UILabel *label; 16 | } 17 | 18 | @property(retain) FSItem *fsItem; 19 | @property(retain) UIButton *iconButton; 20 | @property(retain) UILabel *label; 21 | 22 | - (IBAction)showInfo:(id)sender; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Classes/FSItemCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSItemCell.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "FSItemCell.h" 10 | 11 | @implementation FSItemCell 12 | 13 | @synthesize iconButton; 14 | @synthesize label; 15 | @dynamic fsItem; 16 | 17 | - (void)setFsItem:(FSItem *)item { 18 | [item retain]; 19 | [fsItem release]; 20 | fsItem = item; 21 | 22 | label.text = item.filename; 23 | [iconButton setImage:item.icon forState:UIControlStateNormal]; 24 | 25 | self.accessoryType = item.canBeFollowed ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; 26 | 27 | label.textColor = [item.posixPermissions intValue] ? [UIColor blackColor] : [UIColor lightGrayColor]; 28 | } 29 | 30 | - (FSItem *)fsItem { 31 | return fsItem; 32 | } 33 | 34 | - (void)dealloc { 35 | [fsItem release]; 36 | [iconButton release]; 37 | [label release]; 38 | [super dealloc]; 39 | } 40 | 41 | - (IBAction)showInfo:(id)sender { 42 | [[NSNotificationCenter defaultCenter] postNotificationName:@"ShowInfo" object:fsItem]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /Classes/FSWalkerAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSWalkerAppDelegate.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright Sen:te 2008. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RootViewController; 12 | @class HTTPServer; 13 | 14 | @interface FSWalkerAppDelegate : NSObject { 15 | HTTPServer *httpServer; 16 | 17 | IBOutlet UIWindow *window; 18 | IBOutlet UINavigationController *navigationController; 19 | IBOutlet RootViewController *rootViewController; 20 | } 21 | 22 | @property (nonatomic, retain) HTTPServer *httpServer; 23 | @property (nonatomic, retain) UIWindow *window; 24 | @property (nonatomic, retain) UINavigationController *navigationController; 25 | @property (nonatomic, retain) RootViewController *rootViewController; 26 | 27 | @end 28 | 29 | -------------------------------------------------------------------------------- /Classes/FSWalkerAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSWalkerAppDelegate.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright Sen:te 2008. All rights reserved. 7 | // 8 | 9 | #import "FSWalkerAppDelegate.h" 10 | #import "RootViewController.h" 11 | #import "FSItem.h" 12 | #import "HTTPServer.h" 13 | #import "FSWHTTPConnection.h" 14 | #import "MyIP.h" 15 | 16 | @implementation FSWalkerAppDelegate 17 | 18 | @synthesize httpServer; 19 | @synthesize window; 20 | @synthesize navigationController; 21 | @synthesize rootViewController; 22 | 23 | - (NSString *)myIPAddress { 24 | NSString *myIP = [[[MyIP sharedInstance] ipsForInterfaces] objectForKey:@"en0"]; 25 | 26 | #if TARGET_IPHONE_SIMULATOR 27 | if(!myIP) { 28 | myIP = [[[MyIP sharedInstance] ipsForInterfaces] objectForKey:@"en1"]; 29 | } 30 | #endif 31 | 32 | return myIP; 33 | } 34 | 35 | - (id)init { 36 | if (self = [super init]) { 37 | } 38 | return self; 39 | } 40 | 41 | - (void)startHTTPServer { 42 | NSDictionary *ips = [[MyIP sharedInstance] ipsForInterfaces]; 43 | BOOL isConnectedThroughWifi = [ips objectForKey:@"en0"] != nil; 44 | BOOL shouldStartServer = [[NSUserDefaults standardUserDefaults] boolForKey:@"ShouldStartServer"]; 45 | 46 | NSString *myIPAddress = [self myIPAddress]; 47 | 48 | if(shouldStartServer && (isConnectedThroughWifi || TARGET_IPHONE_SIMULATOR) && myIPAddress) { 49 | self.httpServer = [[[HTTPServer alloc] init] autorelease]; 50 | [httpServer setType:@"_http._tcp."]; 51 | [httpServer setDocumentRoot:[NSURL fileURLWithPath:@"/"]]; 52 | [httpServer setName:[NSString stringWithFormat:@"%@ on %@", [[NSProcessInfo processInfo] processName], [[NSProcessInfo processInfo] hostName]]]; 53 | [httpServer setPort:20000]; 54 | [httpServer setConnectionClass:[FSWHTTPConnection class]]; 55 | 56 | NSError *error = nil; 57 | BOOL success = [httpServer start:&error]; 58 | 59 | if(!success) { 60 | NSLog(@"Error starting HTTP Server."); 61 | 62 | if(error) { 63 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error starting HTTP Server" 64 | message:[error localizedDescription] 65 | delegate:nil 66 | cancelButtonTitle:@"OK" 67 | otherButtonTitles: nil]; 68 | [alert show]; 69 | [alert release]; 70 | } 71 | } else { 72 | [UIApplication sharedApplication].idleTimerDisabled = YES; 73 | 74 | BOOL shouldShowAlert = [[NSUserDefaults standardUserDefaults] boolForKey:@"ShowAlertWhenServerStarts"]; 75 | if(shouldShowAlert) { 76 | 77 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"HTTP Server is running!" 78 | message:[NSString stringWithFormat:@"The iPhone files are accessible at http://%@:%u/", myIPAddress, [httpServer port]] 79 | delegate:nil 80 | cancelButtonTitle:@"OK" 81 | otherButtonTitles:nil]; 82 | [alert show]; 83 | [alert release]; 84 | } 85 | } 86 | } 87 | } 88 | 89 | - (void)displayReadableFiles { 90 | 91 | NSFileManager *fm = [[NSFileManager alloc] init]; 92 | NSDirectoryEnumerator *dirEnum = [fm enumeratorAtPath:@"/"]; 93 | 94 | NSString *path = nil; 95 | while (path = [dirEnum nextObject]) { 96 | if([fm isReadableFileAtPath:path]) NSLog(@"-- /%@", path); 97 | } 98 | [fm release]; 99 | } 100 | 101 | - (void)applicationDidFinishLaunching:(UIApplication *)application { 102 | 103 | NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys: 104 | [NSNumber numberWithBool:YES], @"ShouldStartServer", 105 | [NSNumber numberWithBool:YES], @"ShowAlertWhenServerStarts", 106 | [NSNumber numberWithBool:YES], @"XMLPlist", nil]; 107 | [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; 108 | 109 | // Configure and show the window 110 | [window addSubview:[navigationController view]]; 111 | [window makeKeyAndVisible]; 112 | 113 | [self displayReadableFiles]; 114 | 115 | [self startHTTPServer]; 116 | 117 | rootViewController.fsItem = [FSItem fsItemWithDir:@"/" fileName:@""]; 118 | 119 | #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR 120 | RootViewController *rvc; 121 | 122 | rvc = [[RootViewController alloc] init]; 123 | rvc.fsItem = [FSItem fsItemWithDir:@"/" fileName:@"private"]; 124 | [rootViewController.navigationController pushViewController:rvc animated:NO]; 125 | [rvc release]; 126 | 127 | rvc = [[RootViewController alloc] init]; 128 | rvc.fsItem = [FSItem fsItemWithDir:@"/private/" fileName:@"var"]; 129 | [rootViewController.navigationController pushViewController:rvc animated:NO]; 130 | [rvc release]; 131 | 132 | rvc = [[RootViewController alloc] init]; 133 | rvc.fsItem = [FSItem fsItemWithDir:@"/private/var/" fileName:@"mobile"]; 134 | [rootViewController.navigationController pushViewController:rvc animated:NO]; 135 | [rvc release]; 136 | #else 137 | RootViewController *rvc; 138 | 139 | rvc = [[RootViewController alloc] init]; 140 | rvc.fsItem = [FSItem fsItemWithDir:@"/" fileName:@"Users"]; 141 | [rootViewController.navigationController pushViewController:rvc animated:NO]; 142 | [rvc release]; 143 | 144 | rvc = [[RootViewController alloc] init]; 145 | rvc.fsItem = [FSItem fsItemWithDir:@"/Users" fileName:NSUserName()]; 146 | [rootViewController.navigationController pushViewController:rvc animated:NO]; 147 | [rvc release]; 148 | 149 | #endif 150 | } 151 | 152 | - (void)applicationWillTerminate:(UIApplication *)application { 153 | 154 | if(httpServer) { 155 | [httpServer stop]; 156 | } 157 | 158 | // TODO: save path? 159 | } 160 | 161 | - (void)dealloc { 162 | [httpServer release]; 163 | [navigationController release]; 164 | [window release]; 165 | [super dealloc]; 166 | } 167 | 168 | @end 169 | -------------------------------------------------------------------------------- /Classes/InfoPanelController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InfoPanelController.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSItem.h" 11 | 12 | @interface InfoPanelController : UIViewController { 13 | IBOutlet UILabel *modificationDate; 14 | IBOutlet UILabel *ownerAndGroup; 15 | IBOutlet UILabel *posixPermissions; 16 | IBOutlet UILabel *creationDate; 17 | IBOutlet UILabel *fileSize; 18 | FSItem *fsItem; 19 | } 20 | 21 | @property(retain) UILabel *modificationDate; 22 | @property(retain) UILabel *ownerAndGroup; 23 | @property(retain) UILabel *posixPermissions; 24 | @property(retain) UILabel *creationDate; 25 | @property(retain) UILabel *fileSize; 26 | @property(retain) FSItem *fsItem; 27 | 28 | - (IBAction)dismissInfoPanel:(id)sender; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Classes/InfoPanelController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InfoPanelController.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "InfoPanelController.h" 10 | #import "NSNumber+Bytes.h" 11 | 12 | @implementation InfoPanelController 13 | 14 | @synthesize modificationDate; 15 | @synthesize ownerAndGroup; 16 | @synthesize posixPermissions; 17 | @synthesize creationDate; 18 | @synthesize fileSize; 19 | @synthesize fsItem; 20 | 21 | - (IBAction)dismissInfoPanel:(id)sender { 22 | [self dismissModalViewControllerAnimated:YES]; 23 | } 24 | 25 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 26 | if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 27 | // Initialization code 28 | } 29 | return self; 30 | } 31 | 32 | /* 33 | Implement loadView if you want to create a view hierarchy programmatically 34 | - (void)loadView { 35 | } 36 | */ 37 | 38 | - (void)viewDidLoad { 39 | //NSLog(@"-- viewDidLoad, %@", self.view); 40 | } 41 | 42 | 43 | - (void)viewWillAppear:(BOOL)animated { 44 | self.view; // load the view if it hasn't been loaded yet 45 | 46 | self.navigationItem.title = fsItem.filename; 47 | 48 | ownerAndGroup.text = fsItem.ownerAndGroup; 49 | fileSize.text = [[NSNumber numberWithLongLong:[fsItem.fileSize longLongValue]] prettyBytes]; 50 | creationDate.text = [fsItem.creationDate description]; 51 | modificationDate.text = [fsItem.modificationDate description]; 52 | posixPermissions.text = [fsItem.posixPermissions description]; 53 | } 54 | 55 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 56 | // Return YES for supported orientations 57 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 58 | } 59 | 60 | 61 | - (void)didReceiveMemoryWarning { 62 | [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview 63 | // Release anything that's not essential, such as cached data 64 | } 65 | 66 | 67 | - (void)dealloc { 68 | [modificationDate release]; 69 | [ownerAndGroup release]; 70 | [posixPermissions release]; 71 | [creationDate release]; 72 | [fileSize release]; 73 | [fsItem release]; 74 | 75 | [super dealloc]; 76 | } 77 | 78 | 79 | @end 80 | -------------------------------------------------------------------------------- /Classes/NSNumber+Bytes.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | @interface NSNumber (Bytes) 5 | 6 | - (NSString *)prettyBytes; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /Classes/NSNumber+Bytes.m: -------------------------------------------------------------------------------- 1 | #import "NSNumber+Bytes.h" 2 | 3 | 4 | @implementation NSNumber (Bytes) 5 | 6 | - (NSString *)prettyBytes { 7 | float bytes = [self longValue]; 8 | NSUInteger unit = 0; 9 | 10 | if(bytes < 1) return @"-"; 11 | 12 | while(bytes > 1024) { 13 | bytes = bytes / 1024.0; 14 | unit++; 15 | } 16 | 17 | if(unit > 5) return @"HUGE"; 18 | 19 | NSString *unitString = [[NSArray arrayWithObjects:@"Bytes", @"KB", @"MB", @"GB", @"TB", @"PB", nil] objectAtIndex:unit]; 20 | 21 | if(unit == 0) { 22 | return [NSString stringWithFormat:@"%d %@", (int)bytes, unitString]; 23 | } else { 24 | return [NSString stringWithFormat:@"%.2f %@", (float)bytes, unitString]; 25 | } 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /Classes/RootViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RootViewController.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright Sen:te 2008. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FSItem; 12 | 13 | @interface RootViewController : UITableViewController { 14 | FSItem *fsItem; 15 | } 16 | 17 | @property(nonatomic, retain) FSItem *fsItem; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Classes/RootViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RootViewController.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright Sen:te 2008. All rights reserved. 7 | // 8 | 9 | #import "RootViewController.h" 10 | #import "FSItemCell.h" 11 | #import "DetailViewController.h" 12 | #import "InfoPanelController.h" 13 | #import "FSItem.h" 14 | 15 | @implementation RootViewController 16 | 17 | @dynamic fsItem; 18 | 19 | - (void)setFsItem:(FSItem *)item { 20 | if(item != fsItem) { 21 | [item retain]; 22 | [fsItem release]; 23 | fsItem = item; 24 | 25 | self.title = fsItem.prettyFilename; 26 | } 27 | } 28 | 29 | - (FSItem *)fsItem { 30 | return fsItem; 31 | } 32 | 33 | - (void)viewDidLoad { 34 | // Add the following line if you want the list to be editable 35 | //self.navigationItem.rightBarButtonItem = self.editButtonItem; 36 | 37 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showInfo:) name:@"ShowInfo" object:nil]; 38 | } 39 | 40 | - (void)viewDidUnload { 41 | [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ShowInfo" object:nil]; 42 | } 43 | 44 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 45 | return 1; 46 | } 47 | 48 | 49 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 50 | return [fsItem.children count]; 51 | } 52 | 53 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 54 | 55 | static NSString *MyIdentifier = @"FSItemCell"; 56 | 57 | FSItemCell *cell = (FSItemCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 58 | if (cell == nil) { 59 | cell = (FSItemCell *)[[[NSBundle mainBundle] loadNibNamed:@"FSItemCell" owner:self options:nil] lastObject]; 60 | } 61 | 62 | // Set up the cell 63 | FSItem *child = [fsItem.children objectAtIndex:indexPath.row]; 64 | cell.fsItem = child; 65 | return cell; 66 | } 67 | 68 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 69 | 70 | FSItem *child = [fsItem.children objectAtIndex:indexPath.row]; 71 | 72 | if([child.posixPermissions intValue] == 0) return; 73 | 74 | NSString *path = [child.parent stringByAppendingPathComponent:child.filename]; 75 | NSLog(@"did select %@", path); 76 | 77 | if(child.canBeFollowed) { 78 | RootViewController *rvc = [[RootViewController alloc] init]; 79 | rvc.title = fsItem.filename; 80 | rvc.fsItem = child; 81 | [self.navigationController pushViewController:rvc animated:YES]; 82 | [rvc release]; 83 | } else { 84 | DetailViewController *detailVC = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil]; 85 | detailVC.fsItem = child; 86 | [self.navigationController pushViewController:detailVC animated:YES]; 87 | [detailVC release]; 88 | } 89 | } 90 | 91 | - (void)viewWillAppear:(BOOL)animated { 92 | [super viewWillAppear:animated]; 93 | self.title = fsItem.prettyFilename; 94 | } 95 | 96 | - (void)viewDidAppear:(BOOL)animated { 97 | [super viewDidAppear:animated]; 98 | } 99 | 100 | - (void)viewWillDisappear:(BOOL)animated { 101 | } 102 | 103 | - (void)viewDidDisappear:(BOOL)animated { 104 | } 105 | 106 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 107 | // Return YES for supported orientations 108 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 109 | } 110 | 111 | - (void)dealloc { 112 | [fsItem release]; 113 | [super dealloc]; 114 | } 115 | 116 | - (void)showInfo:(NSNotification *)notification { 117 | FSItem *anFSItem = [notification object]; 118 | InfoPanelController *infoPanelVC = [[InfoPanelController alloc] initWithNibName:@"InfoPanelController" bundle:nil]; 119 | infoPanelVC.fsItem = anFSItem; 120 | [self.navigationController presentModalViewController:infoPanelVC animated:YES]; 121 | [infoPanelVC release]; 122 | } 123 | 124 | @end 125 | 126 | -------------------------------------------------------------------------------- /CocoaHTTPServer/AsyncSocket.h: -------------------------------------------------------------------------------- 1 | // 2 | // AsyncSocket.h 3 | // 4 | // This class is in the public domain. 5 | // Originally created by Dustin Voss on Wed Jan 29 2003. 6 | // Updated and maintained by Deusty Designs and the Mac development community. 7 | // 8 | // http://code.google.com/p/cocoaasyncsocket/ 9 | // 10 | 11 | #import 12 | 13 | @class AsyncSocket; 14 | @class AsyncReadPacket; 15 | @class AsyncWritePacket; 16 | 17 | extern NSString *const AsyncSocketException; 18 | extern NSString *const AsyncSocketErrorDomain; 19 | 20 | enum AsyncSocketError 21 | { 22 | AsyncSocketCFSocketError = kCFSocketError, // From CFSocketError enum. 23 | AsyncSocketNoError = 0, // Never used. 24 | AsyncSocketCanceledError, // onSocketWillConnect: returned NO. 25 | AsyncSocketReadMaxedOutError, // Reached set maxLength without completing 26 | AsyncSocketReadTimeoutError, 27 | AsyncSocketWriteTimeoutError 28 | }; 29 | typedef enum AsyncSocketError AsyncSocketError; 30 | 31 | @interface NSObject (AsyncSocketDelegate) 32 | 33 | /** 34 | * In the event of an error, the socket is closed. 35 | * You may call "unreadData" during this call-back to get the last bit of data off the socket. 36 | * When connecting, this delegate method may be called 37 | * before"onSocket:didAcceptNewSocket:" or "onSocket:didConnectToHost:". 38 | **/ 39 | - (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err; 40 | 41 | /** 42 | * Called when a socket disconnects with or without error. If you want to release a socket after it disconnects, 43 | * do so here. It is not safe to do that during "onSocket:willDisconnectWithError:". 44 | **/ 45 | - (void)onSocketDidDisconnect:(AsyncSocket *)sock; 46 | 47 | /** 48 | * Called when a socket accepts a connection. Another socket is spawned to handle it. The new socket will have 49 | * the same delegate and will call "onSocket:didConnectToHost:port:". 50 | **/ 51 | - (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket; 52 | 53 | /** 54 | * Called when a new socket is spawned to handle a connection. This method should return the run-loop of the 55 | * thread on which the new socket and its delegate should operate. If omitted, [NSRunLoop currentRunLoop] is used. 56 | **/ 57 | - (NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket; 58 | 59 | /** 60 | * Called when a socket is about to connect. This method should return YES to continue, or NO to abort. 61 | * If aborted, will result in AsyncSocketCanceledError. 62 | * 63 | * If the connectToHost:onPort:error: method was called, the delegate will be able to access and configure the 64 | * CFReadStream and CFWriteStream as desired prior to connection. 65 | * 66 | * If the connectToAddress:error: method was called, the delegate will be able to access and configure the 67 | * CFSocket and CFSocketNativeHandle (BSD socket) as desired prior to connection. You will be able to access and 68 | * configure the CFReadStream and CFWriteStream in the onSocket:didConnectToHost:port: method. 69 | **/ 70 | - (BOOL)onSocketWillConnect:(AsyncSocket *)sock; 71 | 72 | /** 73 | * Called when a socket connects and is ready for reading and writing. 74 | * The host parameter will be an IP address, not a DNS name. 75 | **/ 76 | - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port; 77 | 78 | /** 79 | * Called when a socket has completed reading the requested data into memory. 80 | * Not called if there is an error. 81 | **/ 82 | - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag; 83 | 84 | /** 85 | * Called when a socket has read in data, but has not yet completed the read. 86 | * This would occur if using readToData: or readToLength: methods. 87 | * It may be used to for things such as updating progress bars. 88 | **/ 89 | - (void)onSocket:(AsyncSocket *)sock didReadPartialDataOfLength:(CFIndex)partialLength tag:(long)tag; 90 | 91 | /** 92 | * Called when a socket has completed writing the requested data. Not called if there is an error. 93 | **/ 94 | - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag; 95 | 96 | /** 97 | * Called after the socket has completed SSL/TLS negotiation. 98 | * This method is not called unless you use the provided startTLS method. 99 | **/ 100 | - (void)onSocket:(AsyncSocket *)sock didSecure:(BOOL)flag; 101 | 102 | @end 103 | 104 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 105 | #pragma mark - 106 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 107 | 108 | @interface AsyncSocket : NSObject 109 | { 110 | CFSocketRef theSocket; // IPv4 accept or connect socket 111 | CFSocketRef theSocket6; // IPv6 accept or connect socket 112 | CFReadStreamRef theReadStream; 113 | CFWriteStreamRef theWriteStream; 114 | 115 | CFRunLoopSourceRef theSource; // For theSocket 116 | CFRunLoopSourceRef theSource6; // For theSocket6 117 | CFRunLoopRef theRunLoop; 118 | CFSocketContext theContext; 119 | NSArray *theRunLoopModes; 120 | 121 | NSMutableArray *theReadQueue; 122 | AsyncReadPacket *theCurrentRead; 123 | NSTimer *theReadTimer; 124 | NSMutableData *partialReadBuffer; 125 | 126 | NSMutableArray *theWriteQueue; 127 | AsyncWritePacket *theCurrentWrite; 128 | NSTimer *theWriteTimer; 129 | 130 | id theDelegate; 131 | Byte theFlags; 132 | 133 | long theUserData; 134 | } 135 | 136 | - (id)init; 137 | - (id)initWithDelegate:(id)delegate; 138 | - (id)initWithDelegate:(id)delegate userData:(long)userData; 139 | 140 | /* String representation is long but has no "\n". */ 141 | - (NSString *)description; 142 | 143 | /** 144 | * Use "canSafelySetDelegate" to see if there is any pending business (reads and writes) with the current delegate 145 | * before changing it. It is, of course, safe to change the delegate before connecting or accepting connections. 146 | **/ 147 | - (id)delegate; 148 | - (BOOL)canSafelySetDelegate; 149 | - (void)setDelegate:(id)delegate; 150 | 151 | /* User data can be a long, or an id or void * cast to a long. */ 152 | - (long)userData; 153 | - (void)setUserData:(long)userData; 154 | 155 | /* Don't use these to read or write. And don't close them, either! */ 156 | - (CFSocketRef)getCFSocket; 157 | - (CFReadStreamRef)getCFReadStream; 158 | - (CFWriteStreamRef)getCFWriteStream; 159 | 160 | /** 161 | * Once one of these methods is called, the AsyncSocket instance is locked in, and the rest can't be called without 162 | * disconnecting the socket first. If the attempt times out or fails, these methods either return NO or 163 | * call "onSocket:willDisconnectWithError:" and "onSockedDidDisconnect:". 164 | **/ 165 | - (BOOL)acceptOnPort:(UInt16)port error:(NSError **)errPtr; 166 | - (BOOL)acceptOnAddress:(NSString *)hostaddr port:(UInt16)port error:(NSError **)errPtr; 167 | - (BOOL)connectToHost:(NSString *)hostname onPort:(UInt16)port error:(NSError **)errPtr; 168 | - (BOOL)connectToAddress:(NSData *)remoteAddr error:(NSError **)errPtr; 169 | 170 | /** 171 | * Disconnects immediately. Any pending reads or writes are dropped. 172 | **/ 173 | - (void)disconnect; 174 | 175 | /** 176 | * Disconnects after all pending reads have completed. 177 | * After calling this, the read and write methods will do nothing. 178 | * The socket will disconnect even if there are still pending writes. 179 | **/ 180 | - (void)disconnectAfterReading; 181 | 182 | /** 183 | * Disconnects after all pending writes have completed. 184 | * After calling this, the read and write methods will do nothing. 185 | * The socket will disconnect even if there are still pending reads. 186 | **/ 187 | - (void)disconnectAfterWriting; 188 | 189 | /** 190 | * Disconnects after all pending reads and writes have completed. 191 | * After calling this, the read and write methods will do nothing. 192 | **/ 193 | - (void)disconnectAfterReadingAndWriting; 194 | 195 | /* Returns YES if the socket and streams are open, connected, and ready for reading and writing. */ 196 | - (BOOL)isConnected; 197 | 198 | /** 199 | * Returns the local or remote host and port to which this socket is connected, or nil and 0 if not connected. 200 | * The host will be an IP address. 201 | **/ 202 | - (NSString *)connectedHost; 203 | - (UInt16)connectedPort; 204 | 205 | - (NSString *)localHost; 206 | - (UInt16)localPort; 207 | 208 | - (BOOL)isIPv4; 209 | - (BOOL)isIPv6; 210 | 211 | // The readData and writeData methods won't block. To not time out, use a negative time interval. 212 | // If they time out, "onSocket:disconnectWithError:" is called. The tag is for your convenience. 213 | // You can use it as an array index, step number, state id, pointer, etc., just like the socket's user data. 214 | 215 | /** 216 | * This will read a certain number of bytes into memory, and call the delegate method when those bytes have been read. 217 | * If there is an error, partially read data is lost. 218 | * If the length is 0, this method does nothing and the delegate is not called. 219 | **/ 220 | - (void)readDataToLength:(CFIndex)length withTimeout:(NSTimeInterval)timeout tag:(long)tag; 221 | 222 | /** 223 | * This reads bytes until (and including) the passed "data" parameter, which acts as a separator. 224 | * The bytes and the separator are returned by the delegate method. 225 | * 226 | * If you pass nil or zero-length data as the "data" parameter, 227 | * the method will do nothing, and the delegate will not be called. 228 | * 229 | * To read a line from the socket, use the line separator (e.g. CRLF for HTTP, see below) as the "data" parameter. 230 | * Note that this method is not character-set aware, so if a separator can occur naturally as part of the encoding for 231 | * a character, the read will prematurely end. 232 | **/ 233 | - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; 234 | 235 | /** 236 | * Same as readDataToData:withTimeout:tag, with the additional restriction that the amount of data read 237 | * may not surpass the given maxLength (specified in bytes). 238 | * 239 | * If you pass a maxLength parameter that is less than the length of the data parameter, 240 | * the method will do nothing, and the delegate will not be called. 241 | * 242 | * If the max length is surpassed, it is treated the same as a timeout - the socket is closed. 243 | * 244 | * Pass -1 as maxLength if no length restriction is desired, or simply use the readDataToData:withTimeout:tag method. 245 | **/ 246 | - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout maxLength:(CFIndex)length tag:(long)tag; 247 | 248 | /** 249 | * Reads the first available bytes that become available on the socket. 250 | **/ 251 | - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag; 252 | 253 | /** 254 | * Writes data to the socket, and calls the delegate when finished. 255 | * 256 | * If you pass in nil or zero-length data, this method does nothing and the delegate will not be called. 257 | **/ 258 | - (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag; 259 | 260 | /** 261 | * Returns progress of current read or write, from 0.0 to 1.0, or NaN if no read/write (use isnan() to check). 262 | * "tag", "done" and "total" will be filled in if they aren't NULL. 263 | **/ 264 | - (float)progressOfReadReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total; 265 | - (float)progressOfWriteReturningTag:(long *)tag bytesDone:(CFIndex *)done total:(CFIndex *)total; 266 | 267 | /** 268 | * Secures the connection using SSL/TLS. 269 | * 270 | * This method may be called at any time, and the TLS handshake will occur after all pending reads and writes 271 | * are finished. This allows one the option of sending a protocol dependent StartTLS message, and queuing 272 | * the upgrade to TLS at the same time, without having to wait for the write to finish. 273 | * Any reads or writes scheduled after this method is called will occur over the secured connection. 274 | * 275 | * The possible keys and values for the TLS settings are well documented. 276 | * Some possible keys are: 277 | * - kCFStreamSSLLevel 278 | * - kCFStreamSSLAllowsExpiredCertificates 279 | * - kCFStreamSSLAllowsExpiredRoots 280 | * - kCFStreamSSLAllowsAnyRoot 281 | * - kCFStreamSSLValidatesCertificateChain 282 | * - kCFStreamSSLPeerName 283 | * - kCFStreamSSLCertificates 284 | * - kCFStreamSSLIsServer 285 | * 286 | * Please refer to Apple's documentation for associated values, as well as other possible keys. 287 | * 288 | * If you pass in nil or an empty dictionary, this method does nothing and the delegate will not be called. 289 | **/ 290 | - (void)startTLS:(NSDictionary *)tlsSettings; 291 | 292 | /** 293 | * For handling readDataToData requests, data is necessarily read from the socket in small increments. 294 | * The performance can be much improved by allowing AsyncSocket to read larger chunks at a time and 295 | * store any overflow in a small internal buffer. 296 | * This is termed pre-buffering, as some data may be read for you before you ask for it. 297 | * If you use readDataToData a lot, enabling pre-buffering will result in better performance, especially on the iPhone. 298 | * 299 | * The default pre-buffering state is controlled by the DEFAULT_PREBUFFERING definition. 300 | * It is highly recommended one leave this set to YES. 301 | * 302 | * This method exists in case pre-buffering needs to be disabled by default for some reason. 303 | * In that case, this method exists to allow one to easily enable pre-buffering when ready. 304 | **/ 305 | - (void)enablePreBuffering; 306 | 307 | /** 308 | * When you create an AsyncSocket, it is added to the runloop of the current thread. 309 | * So for manually created sockets, it is easiest to simply create the socket on the thread you intend to use it. 310 | * 311 | * If a new socket is accepted, the delegate method onSocket:wantsRunLoopForNewSocket: is called to 312 | * allow you to place the socket on a separate thread. This works best in conjunction with a thread pool design. 313 | * 314 | * If, however, you need to move the socket to a separate thread at a later time, this 315 | * method may be used to accomplish the task. 316 | * 317 | * This method must be called from the thread/runloop the socket is currently running on. 318 | * 319 | * Note: After calling this method, all further method calls to this object should be done from the given runloop. 320 | * Also, all delegate calls will be sent on the given runloop. 321 | **/ 322 | - (BOOL)moveToRunLoop:(NSRunLoop *)runLoop; 323 | 324 | /** 325 | * Allows you to configure which run loop modes the socket uses. 326 | * The default set of run loop modes is NSDefaultRunLoopMode. 327 | * 328 | * If you'd like your socket to continue operation during other modes, you may want to add modes such as 329 | * NSModalPanelRunLoopMode or NSEventTrackingRunLoopMode. Or you may simply want to use NSRunLoopCommonModes. 330 | * 331 | * Accepted sockets will automatically inherit the same run loop modes as the listening socket. 332 | * 333 | * Note: NSRunLoopCommonModes is defined in 10.5. For previous versions one can use kCFRunLoopCommonModes. 334 | **/ 335 | - (BOOL)setRunLoopModes:(NSArray *)runLoopModes; 336 | 337 | /** 338 | * In the event of an error, this method may be called during onSocket:willDisconnectWithError: to read 339 | * any data that's left on the socket. 340 | **/ 341 | - (NSData *)unreadData; 342 | 343 | /* A few common line separators, for use with the readDataToData:... methods. */ 344 | + (NSData *)CRLFData; // 0x0D0A 345 | + (NSData *)CRData; // 0x0D 346 | + (NSData *)LFData; // 0x0A 347 | + (NSData *)ZeroData; // 0x00 348 | 349 | @end 350 | -------------------------------------------------------------------------------- /CocoaHTTPServer/DDData.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface NSData (DDData) 4 | 5 | - (NSData *)md5Digest; 6 | 7 | - (NSData *)sha1Digest; 8 | 9 | - (NSString *)hexStringValue; 10 | 11 | - (NSString *)base64Encoded; 12 | - (NSData *)base64Decoded; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /CocoaHTTPServer/DDData.m: -------------------------------------------------------------------------------- 1 | #import "DDData.h" 2 | 3 | #if TARGET_OS_IPHONE 4 | #import 5 | #else 6 | #import "SSCrypto.h" 7 | #endif 8 | 9 | @implementation NSData (DDData) 10 | 11 | #if TARGET_OS_IPHONE 12 | static char encodingTable[64] = { 13 | 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 14 | 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 15 | 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 16 | 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; 17 | #endif 18 | 19 | - (NSData *)md5Digest 20 | { 21 | #if TARGET_OS_IPHONE 22 | 23 | unsigned char result[CC_MD5_DIGEST_LENGTH]; 24 | 25 | CC_MD5([self bytes], [self length], result); 26 | return [NSData dataWithBytes:result length:CC_MD5_DIGEST_LENGTH]; 27 | 28 | #else 29 | 30 | return [SSCrypto getMD5ForData:self]; 31 | 32 | #endif 33 | } 34 | 35 | - (NSData *)sha1Digest 36 | { 37 | #if TARGET_OS_IPHONE 38 | 39 | unsigned char result[CC_SHA1_DIGEST_LENGTH]; 40 | 41 | CC_SHA1([self bytes], [self length], result); 42 | return [NSData dataWithBytes:result length:CC_SHA1_DIGEST_LENGTH]; 43 | 44 | #else 45 | 46 | return [SSCrypto getSHA1ForData:self]; 47 | 48 | #endif 49 | } 50 | 51 | - (NSString *)hexStringValue 52 | { 53 | #if TARGET_OS_IPHONE 54 | 55 | NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:([self length] * 2)]; 56 | 57 | const unsigned char *dataBuffer = [self bytes]; 58 | int i; 59 | 60 | for (i = 0; i < [self length]; ++i) 61 | { 62 | [stringBuffer appendFormat:@"%02x", (unsigned long)dataBuffer[i]]; 63 | } 64 | 65 | return [[stringBuffer copy] autorelease]; 66 | 67 | #else 68 | 69 | return [self hexval]; 70 | 71 | #endif 72 | } 73 | 74 | - (NSString *)base64Encoded 75 | { 76 | #if TARGET_OS_IPHONE 77 | 78 | const unsigned char *bytes = [self bytes]; 79 | NSMutableString *result = [NSMutableString stringWithCapacity:[self length]]; 80 | unsigned long ixtext = 0; 81 | unsigned long lentext = [self length]; 82 | long ctremaining = 0; 83 | unsigned char inbuf[3], outbuf[4]; 84 | unsigned short i = 0; 85 | unsigned short charsonline = 0, ctcopy = 0; 86 | unsigned long ix = 0; 87 | 88 | while( YES ) 89 | { 90 | ctremaining = lentext - ixtext; 91 | if( ctremaining <= 0 ) break; 92 | 93 | for( i = 0; i < 3; i++ ) { 94 | ix = ixtext + i; 95 | if( ix < lentext ) inbuf[i] = bytes[ix]; 96 | else inbuf [i] = 0; 97 | } 98 | 99 | outbuf [0] = (inbuf [0] & 0xFC) >> 2; 100 | outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); 101 | outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); 102 | outbuf [3] = inbuf [2] & 0x3F; 103 | ctcopy = 4; 104 | 105 | switch( ctremaining ) 106 | { 107 | case 1: 108 | ctcopy = 2; 109 | break; 110 | case 2: 111 | ctcopy = 3; 112 | break; 113 | } 114 | 115 | for( i = 0; i < ctcopy; i++ ) 116 | [result appendFormat:@"%c", encodingTable[outbuf[i]]]; 117 | 118 | for( i = ctcopy; i < 4; i++ ) 119 | [result appendString:@"="]; 120 | 121 | ixtext += 3; 122 | charsonline += 4; 123 | } 124 | 125 | return [NSString stringWithString:result]; 126 | 127 | #else 128 | 129 | return [self encodeBase64WithNewlines:NO]; 130 | 131 | #endif 132 | } 133 | 134 | - (NSData *)base64Decoded 135 | { 136 | #if TARGET_OS_IPHONE 137 | 138 | const unsigned char *bytes = [self bytes]; 139 | NSMutableData *result = [NSMutableData dataWithCapacity:[self length]]; 140 | 141 | unsigned long ixtext = 0; 142 | unsigned long lentext = [self length]; 143 | unsigned char ch = 0; 144 | unsigned char inbuf[4], outbuf[3]; 145 | short i = 0, ixinbuf = 0; 146 | BOOL flignore = NO; 147 | BOOL flendtext = NO; 148 | 149 | while( YES ) 150 | { 151 | if( ixtext >= lentext ) break; 152 | ch = bytes[ixtext++]; 153 | flignore = NO; 154 | 155 | if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A'; 156 | else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26; 157 | else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52; 158 | else if( ch == '+' ) ch = 62; 159 | else if( ch == '=' ) flendtext = YES; 160 | else if( ch == '/' ) ch = 63; 161 | else flignore = YES; 162 | 163 | if( ! flignore ) 164 | { 165 | short ctcharsinbuf = 3; 166 | BOOL flbreak = NO; 167 | 168 | if( flendtext ) 169 | { 170 | if( ! ixinbuf ) break; 171 | if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1; 172 | else ctcharsinbuf = 2; 173 | ixinbuf = 3; 174 | flbreak = YES; 175 | } 176 | 177 | inbuf [ixinbuf++] = ch; 178 | 179 | if( ixinbuf == 4 ) 180 | { 181 | ixinbuf = 0; 182 | outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 ); 183 | outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 ); 184 | outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F ); 185 | 186 | for( i = 0; i < ctcharsinbuf; i++ ) 187 | [result appendBytes:&outbuf[i] length:1]; 188 | } 189 | 190 | if( flbreak ) break; 191 | } 192 | } 193 | 194 | return [NSData dataWithData:result]; 195 | 196 | #else 197 | 198 | return [self decodeBase64WithNewLines:NO]; 199 | 200 | #endif 201 | } 202 | 203 | @end 204 | -------------------------------------------------------------------------------- /CocoaHTTPServer/DDNumber.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | @interface NSNumber (DDNumber) 5 | 6 | + (BOOL)parseString:(NSString *)str intoSInt64:(SInt64 *)pNum; 7 | + (BOOL)parseString:(NSString *)str intoUInt64:(UInt64 *)pNum; 8 | 9 | + (BOOL)parseString:(NSString *)str intoNSInteger:(NSInteger *)pNum; 10 | + (BOOL)parseString:(NSString *)str intoNSUInteger:(NSUInteger *)pNum; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /CocoaHTTPServer/DDNumber.m: -------------------------------------------------------------------------------- 1 | #import "DDNumber.h" 2 | 3 | 4 | @implementation NSNumber (DDNumber) 5 | 6 | + (BOOL)parseString:(NSString *)str intoSInt64:(SInt64 *)pNum 7 | { 8 | errno = 0; 9 | 10 | #if __LP64__ 11 | // long = 64 bit 12 | *pNum = strtol([str UTF8String], NULL, 10); 13 | #else 14 | // long = 32 bit 15 | // long long = 64 bit 16 | *pNum = strtoll([str UTF8String], NULL, 10); 17 | #endif 18 | 19 | if(errno != 0) 20 | return NO; 21 | else 22 | return YES; 23 | } 24 | 25 | + (BOOL)parseString:(NSString *)str intoUInt64:(UInt64 *)pNum 26 | { 27 | errno = 0; 28 | 29 | #if __LP64__ 30 | // unsigned long = 64 bit 31 | *pNum = strtoul([str UTF8String], NULL, 10); 32 | #else 33 | // unsigned long = 32 bit 34 | // unsigned long long = 64 bit 35 | *pNum = strtoull([str UTF8String], NULL, 10); 36 | #endif 37 | 38 | if(errno != 0) 39 | return NO; 40 | else 41 | return YES; 42 | } 43 | 44 | + (BOOL)parseString:(NSString *)str intoNSInteger:(NSInteger *)pNum 45 | { 46 | errno = 0; 47 | 48 | // On LP64, NSInteger = long = 64 bit 49 | // Otherwise, NSInteger = int = long = 32 bit 50 | 51 | *pNum = strtol([str UTF8String], NULL, 10); 52 | 53 | if(errno != 0) 54 | return NO; 55 | else 56 | return YES; 57 | } 58 | 59 | + (BOOL)parseString:(NSString *)str intoNSUInteger:(NSUInteger *)pNum 60 | { 61 | errno = 0; 62 | 63 | // On LP64, NSUInteger = unsigned long = 64 bit 64 | // Otherwise, NSUInteger = unsigned int = unsigned long = 32 bit 65 | 66 | *pNum = strtoul([str UTF8String], NULL, 10); 67 | 68 | if(errno != 0) 69 | return NO; 70 | else 71 | return YES; 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /CocoaHTTPServer/DDRange.h: -------------------------------------------------------------------------------- 1 | /** 2 | * DDRange is the functional equivalent of a 64 bit NSRange. 3 | * The HTTP Server is designed to support very large files. 4 | * On 32 bit architectures (ppc, i386) NSRange uses unsigned 32 bit integers. 5 | * This only supports a range of up to 4 gigabytes. 6 | * By defining our own variant, we can support a range up to 16 exabytes. 7 | * 8 | * All effort is given such that DDRange functions EXACTLY the same as NSRange. 9 | **/ 10 | 11 | #import 12 | #import 13 | 14 | @class NSString; 15 | 16 | typedef struct _DDRange { 17 | UInt64 location; 18 | UInt64 length; 19 | } DDRange; 20 | 21 | typedef DDRange *DDRangePointer; 22 | 23 | NS_INLINE DDRange DDMakeRange(UInt64 loc, UInt64 len) { 24 | DDRange r; 25 | r.location = loc; 26 | r.length = len; 27 | return r; 28 | } 29 | 30 | NS_INLINE UInt64 DDMaxRange(DDRange range) { 31 | return (range.location + range.length); 32 | } 33 | 34 | NS_INLINE BOOL DDLocationInRange(UInt64 loc, DDRange range) { 35 | return (loc - range.location < range.length); 36 | } 37 | 38 | NS_INLINE BOOL DDEqualRanges(DDRange range1, DDRange range2) { 39 | return ((range1.location == range2.location) && (range1.length == range2.length)); 40 | } 41 | 42 | FOUNDATION_EXPORT DDRange DDUnionRange(DDRange range1, DDRange range2); 43 | FOUNDATION_EXPORT DDRange DDIntersectionRange(DDRange range1, DDRange range2); 44 | FOUNDATION_EXPORT NSString *DDStringFromRange(DDRange range); 45 | FOUNDATION_EXPORT DDRange DDRangeFromString(NSString *aString); 46 | 47 | @interface NSValue (NSValueDDRangeExtensions) 48 | 49 | + (NSValue *)valueWithDDRange:(DDRange)range; 50 | - (DDRange)ddrangeValue; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /CocoaHTTPServer/DDRange.m: -------------------------------------------------------------------------------- 1 | #import "DDRange.h" 2 | #import "DDNumber.h" 3 | 4 | DDRange DDUnionRange(DDRange range1, DDRange range2) 5 | { 6 | DDRange result; 7 | 8 | result.location = MIN(range1.location, range2.location); 9 | result.length = MAX(DDMaxRange(range1), DDMaxRange(range2)) - result.location; 10 | 11 | return result; 12 | } 13 | 14 | DDRange DDIntersectionRange(DDRange range1, DDRange range2) 15 | { 16 | DDRange result; 17 | 18 | if((DDMaxRange(range1) < range2.location) || (DDMaxRange(range2) < range1.location)) 19 | { 20 | return DDMakeRange(0, 0); 21 | } 22 | 23 | result.location = MAX(range1.location, range2.location); 24 | result.length = MIN(DDMaxRange(range1), DDMaxRange(range2)) - result.location; 25 | 26 | return result; 27 | } 28 | 29 | NSString *DDStringFromRange(DDRange range) 30 | { 31 | return [NSString stringWithFormat:@"{%qu, %qu}", range.location, range.length]; 32 | } 33 | 34 | DDRange DDRangeFromString(NSString *aString) 35 | { 36 | DDRange result = DDMakeRange(0, 0); 37 | 38 | // NSRange will ignore '-' characters, but not '+' characters 39 | NSCharacterSet *cset = [NSCharacterSet characterSetWithCharactersInString:@"+0123456789"]; 40 | 41 | NSScanner *scanner = [NSScanner scannerWithString:aString]; 42 | [scanner setCharactersToBeSkipped:[cset invertedSet]]; 43 | 44 | NSString *str1 = nil; 45 | NSString *str2 = nil; 46 | 47 | BOOL found1 = [scanner scanCharactersFromSet:cset intoString:&str1]; 48 | BOOL found2 = [scanner scanCharactersFromSet:cset intoString:&str2]; 49 | 50 | if(found1) [NSNumber parseString:str1 intoUInt64:&result.location]; 51 | if(found2) [NSNumber parseString:str2 intoUInt64:&result.length]; 52 | 53 | return result; 54 | } 55 | 56 | @implementation NSValue (NSValueDDRangeExtensions) 57 | 58 | + (NSValue *)valueWithDDRange:(DDRange)range 59 | { 60 | return [NSValue valueWithBytes:&range objCType:@encode(DDRange)]; 61 | } 62 | 63 | - (DDRange)ddrangeValue 64 | { 65 | DDRange result; 66 | [self getValue:&result]; 67 | return result; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPAuthenticationRequest.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if TARGET_OS_IPHONE 4 | // Note: You may need to add the CFNetwork Framework to your project 5 | #import 6 | #endif 7 | 8 | 9 | @interface HTTPAuthenticationRequest : NSObject 10 | { 11 | BOOL isBasic; 12 | BOOL isDigest; 13 | 14 | NSString *base64Credentials; 15 | 16 | NSString *username; 17 | NSString *realm; 18 | NSString *nonce; 19 | NSString *uri; 20 | NSString *qop; 21 | NSString *nc; 22 | NSString *cnonce; 23 | NSString *response; 24 | } 25 | - (id)initWithRequest:(CFHTTPMessageRef)request; 26 | 27 | - (BOOL)isBasic; 28 | - (BOOL)isDigest; 29 | 30 | // Basic 31 | - (NSString *)base64Credentials; 32 | 33 | // Digest 34 | - (NSString *)username; 35 | - (NSString *)realm; 36 | - (NSString *)nonce; 37 | - (NSString *)uri; 38 | - (NSString *)qop; 39 | - (NSString *)nc; 40 | - (NSString *)cnonce; 41 | - (NSString *)response; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPAuthenticationRequest.m: -------------------------------------------------------------------------------- 1 | #import "HTTPAuthenticationRequest.h" 2 | 3 | @interface HTTPAuthenticationRequest (PrivateAPI) 4 | - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header; 5 | - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header; 6 | @end 7 | 8 | 9 | @implementation HTTPAuthenticationRequest 10 | 11 | - (id)initWithRequest:(CFHTTPMessageRef)request 12 | { 13 | if(self = [super init]) 14 | { 15 | NSString *authInfo = (NSString *)CFHTTPMessageCopyHeaderFieldValue(request, CFSTR("Authorization")); 16 | 17 | isBasic = NO; 18 | if([authInfo length] >= 6) 19 | { 20 | isBasic = [[authInfo substringToIndex:6] caseInsensitiveCompare:@"Basic "] == NSOrderedSame; 21 | } 22 | 23 | isDigest = NO; 24 | if([authInfo length] >= 7) 25 | { 26 | isDigest = [[authInfo substringToIndex:7] caseInsensitiveCompare:@"Digest "] == NSOrderedSame; 27 | } 28 | 29 | if(isBasic) 30 | { 31 | NSMutableString *temp = [[[authInfo substringFromIndex:6] mutableCopy] autorelease]; 32 | CFStringTrimWhitespace((CFMutableStringRef)temp); 33 | 34 | base64Credentials = [temp copy]; 35 | } 36 | 37 | if(isDigest) 38 | { 39 | username = [[self quotedSubHeaderFieldValue:@"username" fromHeaderFieldValue:authInfo] retain]; 40 | realm = [[self quotedSubHeaderFieldValue:@"realm" fromHeaderFieldValue:authInfo] retain]; 41 | nonce = [[self quotedSubHeaderFieldValue:@"nonce" fromHeaderFieldValue:authInfo] retain]; 42 | uri = [[self quotedSubHeaderFieldValue:@"uri" fromHeaderFieldValue:authInfo] retain]; 43 | 44 | // It appears from RFC 2617 that the qop is to be given unquoted 45 | // Tests show that Firefox performs this way, but Safari does not 46 | // Thus we'll attempt to retrieve the value as nonquoted, but we'll verify it doesn't start with a quote 47 | qop = [self nonquotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo]; 48 | if(qop && ([qop characterAtIndex:0] == '"')) 49 | { 50 | qop = [self quotedSubHeaderFieldValue:@"qop" fromHeaderFieldValue:authInfo]; 51 | } 52 | [qop retain]; 53 | 54 | nc = [[self nonquotedSubHeaderFieldValue:@"nc" fromHeaderFieldValue:authInfo] retain]; 55 | cnonce = [[self quotedSubHeaderFieldValue:@"cnonce" fromHeaderFieldValue:authInfo] retain]; 56 | response = [[self quotedSubHeaderFieldValue:@"response" fromHeaderFieldValue:authInfo] retain]; 57 | } 58 | 59 | // Remember, if using garbage collection: 60 | // Core foundation objects must be released using CFRelease, as [id release] is a no-op. 61 | if(authInfo) CFRelease((CFStringRef)authInfo); 62 | } 63 | return self; 64 | } 65 | 66 | - (void)dealloc 67 | { 68 | [base64Credentials release]; 69 | [username release]; 70 | [realm release]; 71 | [nonce release]; 72 | [uri release]; 73 | [qop release]; 74 | [nc release]; 75 | [cnonce release]; 76 | [response release]; 77 | [super dealloc]; 78 | } 79 | 80 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 81 | #pragma mark Accessors: 82 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 83 | 84 | - (BOOL)isBasic { 85 | return isBasic; 86 | } 87 | 88 | - (BOOL)isDigest { 89 | return isDigest; 90 | } 91 | 92 | - (NSString *)base64Credentials { 93 | return base64Credentials; 94 | } 95 | 96 | - (NSString *)username { 97 | return username; 98 | } 99 | 100 | - (NSString *)realm { 101 | return realm; 102 | } 103 | 104 | - (NSString *)nonce { 105 | return nonce; 106 | } 107 | 108 | - (NSString *)uri { 109 | return uri; 110 | } 111 | 112 | - (NSString *)qop { 113 | return qop; 114 | } 115 | 116 | - (NSString *)nc { 117 | return nc; 118 | } 119 | 120 | - (NSString *)cnonce { 121 | return cnonce; 122 | } 123 | 124 | - (NSString *)response { 125 | return response; 126 | } 127 | 128 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 129 | #pragma mark Private API: 130 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 131 | 132 | /** 133 | * Retrieves a "Sub Header Field Value" from a given header field value. 134 | * The sub header field is expected to be quoted. 135 | * 136 | * In the following header field: 137 | * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939" 138 | * The sub header field titled 'username' is quoted, and this method would return the value @"Mufasa". 139 | **/ 140 | - (NSString *)quotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header 141 | { 142 | NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=\"", param]]; 143 | if(startRange.location == NSNotFound) 144 | { 145 | // The param was not found anywhere in the header 146 | return nil; 147 | } 148 | 149 | int postStartRangeLocation = startRange.location + startRange.length; 150 | int postStartRangeLength = [header length] - postStartRangeLocation; 151 | NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength); 152 | 153 | NSRange endRange = [header rangeOfString:@"\"" options:0 range:postStartRange]; 154 | if(endRange.location == NSNotFound) 155 | { 156 | // The ending double-quote was not found anywhere in the header 157 | return nil; 158 | } 159 | 160 | NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation); 161 | return [header substringWithRange:subHeaderRange]; 162 | } 163 | 164 | /** 165 | * Retrieves a "Sub Header Field Value" from a given header field value. 166 | * The sub header field is expected to not be quoted. 167 | * 168 | * In the following header field: 169 | * Authorization: Digest username="Mufasa", qop=auth, response="6629fae4939" 170 | * The sub header field titled 'qop' is nonquoted, and this method would return the value @"auth". 171 | **/ 172 | - (NSString *)nonquotedSubHeaderFieldValue:(NSString *)param fromHeaderFieldValue:(NSString *)header 173 | { 174 | NSRange startRange = [header rangeOfString:[NSString stringWithFormat:@"%@=", param]]; 175 | if(startRange.location == NSNotFound) 176 | { 177 | // The param was not found anywhere in the header 178 | return nil; 179 | } 180 | 181 | int postStartRangeLocation = startRange.location + startRange.length; 182 | int postStartRangeLength = [header length] - postStartRangeLocation; 183 | NSRange postStartRange = NSMakeRange(postStartRangeLocation, postStartRangeLength); 184 | 185 | NSRange endRange = [header rangeOfString:@"," options:0 range:postStartRange]; 186 | if(endRange.location == NSNotFound) 187 | { 188 | // The ending comma was not found anywhere in the header 189 | // However, if the nonquoted param is at the end of the string, there would be no comma 190 | // This is only possible if there are no spaces anywhere 191 | NSRange endRange2 = [header rangeOfString:@" " options:0 range:postStartRange]; 192 | if(endRange2.location != NSNotFound) 193 | { 194 | return nil; 195 | } 196 | else 197 | { 198 | return [header substringWithRange:postStartRange]; 199 | } 200 | } 201 | else 202 | { 203 | NSRange subHeaderRange = NSMakeRange(postStartRangeLocation, endRange.location - postStartRangeLocation); 204 | return [header substringWithRange:subHeaderRange]; 205 | } 206 | } 207 | 208 | @end 209 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPConnection.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #if TARGET_OS_IPHONE 4 | // Note: You may need to add the CFNetwork Framework to your project 5 | #import 6 | #endif 7 | 8 | @class AsyncSocket; 9 | @class HTTPServer; 10 | @protocol HTTPResponse; 11 | 12 | 13 | #define HTTPConnectionDidDieNotification @"HTTPConnectionDidDie" 14 | 15 | @interface HTTPConnection : NSObject 16 | { 17 | AsyncSocket *asyncSocket; 18 | HTTPServer *server; 19 | 20 | CFHTTPMessageRef request; 21 | int numHeaderLines; 22 | 23 | NSString *nonce; 24 | long lastNC; 25 | 26 | NSObject *httpResponse; 27 | 28 | NSMutableArray *ranges; 29 | NSMutableArray *ranges_headers; 30 | NSString *ranges_boundry; 31 | int rangeIndex; 32 | 33 | UInt64 requestContentLength; 34 | UInt64 requestContentLengthReceived; 35 | } 36 | 37 | - (id)initWithAsyncSocket:(AsyncSocket *)newSocket forServer:(HTTPServer *)myServer; 38 | 39 | - (BOOL)supportsMethod:(NSString *)method atPath:(NSString *)path; 40 | 41 | - (BOOL)isSecureServer; 42 | - (NSArray *)sslIdentityAndCertificates; 43 | 44 | - (BOOL)isPasswordProtected:(NSString *)path; 45 | - (BOOL)useDigestAccessAuthentication; 46 | - (NSString *)realm; 47 | - (NSString *)passwordForUser:(NSString *)username; 48 | 49 | - (NSString *)filePathForURI:(NSString *)path; 50 | 51 | - (NSObject *)httpResponseForMethod:(NSString *)method URI:(NSString *)path; 52 | 53 | - (void)prepareForBodyWithSize:(UInt64)contentLength; 54 | - (void)processDataChunk:(NSData *)postDataChunk; 55 | 56 | - (void)handleVersionNotSupported:(NSString *)version; 57 | - (void)handleAuthenticationFailed; 58 | - (void)handleResourceNotFound; 59 | - (void)handleInvalidRequest:(NSData *)data; 60 | - (void)handleUnknownMethod:(NSString *)method; 61 | 62 | - (NSData *)preprocessResponse:(CFHTTPMessageRef)response; 63 | - (NSData *)preprocessErrorResponse:(CFHTTPMessageRef)response; 64 | 65 | - (void)die; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPResponse.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | @protocol HTTPResponse 5 | 6 | - (UInt64)contentLength; 7 | 8 | - (UInt64)offset; 9 | - (void)setOffset:(UInt64)offset; 10 | 11 | - (NSData *)readDataOfLength:(unsigned int)length; 12 | 13 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 14 | 15 | @optional 16 | - (NSDictionary *)httpHeaders; 17 | 18 | #endif 19 | 20 | @end 21 | 22 | @interface HTTPFileResponse : NSObject 23 | { 24 | NSString *filePath; 25 | NSFileHandle *fileHandle; 26 | } 27 | 28 | - (id)initWithFilePath:(NSString *)filePath; 29 | - (NSString *)filePath; 30 | 31 | @end 32 | 33 | @interface HTTPDataResponse : NSObject 34 | { 35 | unsigned offset; 36 | NSData *data; 37 | } 38 | 39 | - (id)initWithData:(NSData *)data; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPResponse.m: -------------------------------------------------------------------------------- 1 | #import "HTTPResponse.h" 2 | 3 | 4 | @implementation HTTPFileResponse 5 | 6 | - (id)initWithFilePath:(NSString *)filePathParam 7 | { 8 | if(self = [super init]) 9 | { 10 | filePath = [filePathParam copy]; 11 | fileHandle = [[NSFileHandle fileHandleForReadingAtPath:filePath] retain]; 12 | } 13 | return self; 14 | } 15 | 16 | - (void)dealloc 17 | { 18 | [filePath release]; 19 | [fileHandle closeFile]; 20 | [fileHandle release]; 21 | [super dealloc]; 22 | } 23 | 24 | - (UInt64)contentLength 25 | { 26 | NSError *error = nil; 27 | NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error]; 28 | if(!fileAttributes) { 29 | NSLog(@"-- can't get file attributes at path:%@ error:%@", filePath, error); 30 | } 31 | 32 | NSNumber *fileSize = [fileAttributes objectForKey:NSFileSize]; 33 | 34 | return (UInt64)[fileSize unsignedLongLongValue]; 35 | } 36 | 37 | - (UInt64)offset 38 | { 39 | return (UInt64)[fileHandle offsetInFile]; 40 | } 41 | 42 | - (void)setOffset:(UInt64)offset 43 | { 44 | [fileHandle seekToFileOffset:offset]; 45 | } 46 | 47 | - (NSData *)readDataOfLength:(unsigned int)length 48 | { 49 | return [fileHandle readDataOfLength:length]; 50 | } 51 | 52 | - (NSString *)filePath 53 | { 54 | return filePath; 55 | } 56 | 57 | @end 58 | 59 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 60 | #pragma mark - 61 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 62 | 63 | @implementation HTTPDataResponse 64 | 65 | - (id)initWithData:(NSData *)dataParam 66 | { 67 | if(self = [super init]) 68 | { 69 | offset = 0; 70 | data = [dataParam retain]; 71 | } 72 | return self; 73 | } 74 | 75 | - (void)dealloc 76 | { 77 | [data release]; 78 | [super dealloc]; 79 | } 80 | 81 | - (UInt64)contentLength 82 | { 83 | return (UInt64)[data length]; 84 | } 85 | 86 | - (UInt64)offset 87 | { 88 | return offset; 89 | } 90 | 91 | - (void)setOffset:(UInt64)offsetParam 92 | { 93 | offset = offsetParam; 94 | } 95 | 96 | - (NSData *)readDataOfLength:(unsigned int)lengthParameter 97 | { 98 | unsigned int remaining = [data length] - offset; 99 | unsigned int length = lengthParameter < remaining ? lengthParameter : remaining; 100 | 101 | void *bytes = (void *)([data bytes] + offset); 102 | 103 | offset += length; 104 | 105 | return [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:NO]; 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPServer.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class AsyncSocket; 4 | 5 | 6 | @interface HTTPServer : NSObject 7 | { 8 | // Underlying asynchronous TCP/IP socket 9 | AsyncSocket *asyncSocket; 10 | 11 | // Standard delegate 12 | id delegate; 13 | 14 | // HTTP server configuration 15 | NSURL *documentRoot; 16 | Class connectionClass; 17 | 18 | // NSNetService and related variables 19 | NSNetService *netService; 20 | NSString *domain; 21 | NSString *type; 22 | NSString *name; 23 | UInt16 port; 24 | NSDictionary *txtRecordDictionary; 25 | 26 | NSMutableArray *connections; 27 | } 28 | 29 | - (id)delegate; 30 | - (void)setDelegate:(id)newDelegate; 31 | 32 | - (NSURL *)documentRoot; 33 | - (void)setDocumentRoot:(NSURL *)value; 34 | 35 | - (Class)connectionClass; 36 | - (void)setConnectionClass:(Class)value; 37 | 38 | - (NSString *)domain; 39 | - (void)setDomain:(NSString *)value; 40 | 41 | - (NSString *)type; 42 | - (void)setType:(NSString *)value; 43 | 44 | - (NSString *)name; 45 | - (NSString *)publishedName; 46 | - (void)setName:(NSString *)value; 47 | 48 | - (UInt16)port; 49 | - (void)setPort:(UInt16)value; 50 | 51 | - (NSDictionary *)TXTRecordDictionary; 52 | - (void)setTXTRecordDictionary:(NSDictionary *)dict; 53 | 54 | - (BOOL)start:(NSError **)error; 55 | - (BOOL)stop; 56 | 57 | - (uint)numberOfHTTPConnections; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /CocoaHTTPServer/HTTPServer.m: -------------------------------------------------------------------------------- 1 | #import "AsyncSocket.h" 2 | #import "HTTPServer.h" 3 | #import "HTTPConnection.h" 4 | 5 | 6 | @implementation HTTPServer 7 | 8 | /** 9 | * Standard Constructor. 10 | * Instantiates an HTTP server, but does not start it. 11 | **/ 12 | - (id)init 13 | { 14 | if(self = [super init]) 15 | { 16 | // Initialize underlying asynchronous tcp/ip socket 17 | asyncSocket = [[AsyncSocket alloc] initWithDelegate:self]; 18 | 19 | // Use default connection class of HTTPConnection 20 | connectionClass = [HTTPConnection self]; 21 | 22 | // Configure default values for bonjour service 23 | 24 | // Use a default port of 0 25 | // This will allow the kernel to automatically pick an open port for us 26 | port = 0; 27 | 28 | // Bonjour domain. Use the local domain by default 29 | domain = @"local."; 30 | 31 | // If using an empty string ("") for the service name when registering, 32 | // the system will automatically use the "Computer Name". 33 | // Passing in an empty string will also handle name conflicts 34 | // by automatically appending a digit to the end of the name. 35 | name = @""; 36 | 37 | // Initialize an array to hold all the HTTP connections 38 | connections = [[NSMutableArray alloc] init]; 39 | 40 | // And register for notifications of closed connections 41 | [[NSNotificationCenter defaultCenter] addObserver:self 42 | selector:@selector(connectionDidDie:) 43 | name:HTTPConnectionDidDieNotification 44 | object:nil]; 45 | } 46 | return self; 47 | } 48 | 49 | /** 50 | * Standard Deconstructor. 51 | * Stops the server, and clients, and releases any resources connected with this instance. 52 | **/ 53 | - (void)dealloc 54 | { 55 | // Remove notification observer 56 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 57 | 58 | // Stop the server if it's running 59 | [self stop]; 60 | 61 | // Release all instance variables 62 | [documentRoot release]; 63 | [netService release]; 64 | [domain release]; 65 | [name release]; 66 | [type release]; 67 | [txtRecordDictionary release]; 68 | [asyncSocket release]; 69 | [connections release]; 70 | 71 | [super dealloc]; 72 | } 73 | 74 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 75 | #pragma mark Server Configuration: 76 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 77 | 78 | /** 79 | * Returns the delegate connected with this instance. 80 | **/ 81 | - (id)delegate 82 | { 83 | return delegate; 84 | } 85 | 86 | /** 87 | * Sets the delegate connected with this instance. 88 | **/ 89 | - (void)setDelegate:(id)newDelegate 90 | { 91 | delegate = newDelegate; 92 | } 93 | 94 | /** 95 | * The document root is filesystem root for the webserver. 96 | * Thus requests for /index.html will be referencing the index.html file within the document root directory. 97 | * All file requests are relative to this document root. 98 | **/ 99 | - (NSURL *)documentRoot { 100 | return documentRoot; 101 | } 102 | - (void)setDocumentRoot:(NSURL *)value 103 | { 104 | if(![documentRoot isEqual:value]) 105 | { 106 | [documentRoot release]; 107 | documentRoot = [value copy]; 108 | } 109 | } 110 | 111 | /** 112 | * The connection class is the class that will be used to handle connections. 113 | * That is, when a new connection is created, an instance of this class will be intialized. 114 | * The default connection class is HTTPConnection. 115 | * If you use a different connection class, it is assumed that the class extends HTTPConnection 116 | **/ 117 | - (Class)connectionClass { 118 | return connectionClass; 119 | } 120 | - (void)setConnectionClass:(Class)value 121 | { 122 | connectionClass = value; 123 | } 124 | 125 | /** 126 | * Domain on which to broadcast this service via Bonjour. 127 | * The default domain is @"local". 128 | **/ 129 | - (NSString *)domain { 130 | return domain; 131 | } 132 | - (void)setDomain:(NSString *)value 133 | { 134 | if(![domain isEqualToString:value]) 135 | { 136 | [domain release]; 137 | domain = [value copy]; 138 | } 139 | } 140 | 141 | /** 142 | * The type of service to publish via Bonjour. 143 | * No type is set by default, and one must be set in order for the service to be published. 144 | **/ 145 | - (NSString *)type { 146 | return type; 147 | } 148 | - (void)setType:(NSString *)value 149 | { 150 | if(![type isEqualToString:value]) 151 | { 152 | [type release]; 153 | type = [value copy]; 154 | } 155 | } 156 | 157 | /** 158 | * The name to use for this service via Bonjour. 159 | * The default name is an empty string, 160 | * which should result in the published name being the host name of the computer. 161 | **/ 162 | - (NSString *)name { 163 | return name; 164 | } 165 | - (NSString *)publishedName { 166 | return [netService name]; 167 | } 168 | - (void)setName:(NSString *)value 169 | { 170 | if(![name isEqualToString:value]) 171 | { 172 | [name release]; 173 | name = [value copy]; 174 | } 175 | } 176 | 177 | /** 178 | * The port to listen for connections on. 179 | * By default this port is initially set to zero, which allows the kernel to pick an available port for us. 180 | * After the HTTP server has started, the port being used may be obtained by this method. 181 | **/ 182 | - (UInt16)port { 183 | return port; 184 | } 185 | - (void)setPort:(UInt16)value { 186 | port = value; 187 | } 188 | 189 | /** 190 | * The extra data to use for this service via Bonjour. 191 | **/ 192 | - (NSDictionary *)TXTRecordDictionary { 193 | return txtRecordDictionary; 194 | } 195 | - (void)setTXTRecordDictionary:(NSDictionary *)value 196 | { 197 | if(![txtRecordDictionary isEqualToDictionary:value]) 198 | { 199 | [txtRecordDictionary release]; 200 | txtRecordDictionary = [value copy]; 201 | 202 | // And update the txtRecord of the netService if it has already been published 203 | if(netService) 204 | { 205 | [netService setTXTRecordData:[NSNetService dataFromTXTRecordDictionary:txtRecordDictionary]]; 206 | } 207 | } 208 | } 209 | 210 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 211 | #pragma mark Server Control: 212 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 213 | 214 | - (BOOL)start:(NSError **)error 215 | { 216 | BOOL success = [asyncSocket acceptOnPort:port error:error]; 217 | 218 | if(success) 219 | { 220 | // Update our port number 221 | [self setPort:[asyncSocket localPort]]; 222 | 223 | // Output console message for debugging purposes 224 | NSLog(@"Started HTTP server on port %hu", port); 225 | 226 | // We can only publish our bonjour service if a type has been set 227 | if(type != nil) 228 | { 229 | // Create the NSNetService with our basic parameters 230 | netService = [[NSNetService alloc] initWithDomain:domain type:type name:name port:port]; 231 | 232 | [netService setDelegate:self]; 233 | [netService publish]; 234 | 235 | // Do not set the txtRecordDictionary prior to publishing!!! 236 | // This will cause the OS to crash!!! 237 | 238 | // Set the txtRecordDictionary if we have one 239 | if(txtRecordDictionary != nil) 240 | { 241 | [netService setTXTRecordData:[NSNetService dataFromTXTRecordDictionary:txtRecordDictionary]]; 242 | } 243 | } 244 | } 245 | else 246 | { 247 | NSLog(@"Failed to start HTTP Server: %@", *error); 248 | } 249 | 250 | return success; 251 | } 252 | 253 | - (BOOL)stop 254 | { 255 | // First stop publishing the service via bonjour 256 | if(netService) 257 | { 258 | [netService stop]; 259 | [netService release]; 260 | netService = nil; 261 | } 262 | 263 | // Now stop the asynchronouse tcp server 264 | // This will prevent it from accepting any more connections 265 | [asyncSocket disconnect]; 266 | 267 | // Now stop all HTTP connections the server owns 268 | @synchronized(connections) 269 | { 270 | [connections removeAllObjects]; 271 | } 272 | 273 | return YES; 274 | } 275 | 276 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 277 | #pragma mark Server Status: 278 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 279 | 280 | /** 281 | * Returns the number of clients that are currently connected to the server. 282 | **/ 283 | - (uint)numberOfHTTPConnections 284 | { 285 | uint result = 0; 286 | 287 | @synchronized(connections) 288 | { 289 | result = [connections count]; 290 | } 291 | return result; 292 | } 293 | 294 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 295 | #pragma mark AsyncSocket Delegate Methods: 296 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 297 | 298 | -(void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket 299 | { 300 | id newConnection = [[connectionClass alloc] initWithAsyncSocket:newSocket forServer:self]; 301 | 302 | @synchronized(connections) 303 | { 304 | [connections addObject:newConnection]; 305 | } 306 | [newConnection release]; 307 | } 308 | 309 | /** 310 | * This method is automatically called when a notification of type HTTPConnectionDidDieNotification is posted. 311 | * It allows us to remove the connection from our array. 312 | **/ 313 | - (void)connectionDidDie:(NSNotification *)notification 314 | { 315 | // Note: This method is called on the thread/runloop that posted the notification 316 | 317 | @synchronized(connections) 318 | { 319 | [connections removeObject:[notification object]]; 320 | } 321 | } 322 | 323 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 324 | #pragma mark Bonjour Delegate Methods: 325 | //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 326 | 327 | /** 328 | * Called when our bonjour service has been successfully published. 329 | * This method does nothing but output a log message telling us about the published service. 330 | **/ 331 | - (void)netServiceDidPublish:(NSNetService *)ns 332 | { 333 | // Override me to do something here... 334 | 335 | NSLog(@"Bonjour Service Published: domain(%@) type(%@) name(%@)", [ns domain], [ns type], [ns name]); 336 | } 337 | 338 | /** 339 | * Called if our bonjour service failed to publish itself. 340 | * This method does nothing but output a log message telling us about the published service. 341 | **/ 342 | - (void)netService:(NSNetService *)ns didNotPublish:(NSDictionary *)errorDict 343 | { 344 | // Override me to do something here... 345 | 346 | NSLog(@"Failed to Publish Service: domain(%@) type(%@) name(%@)", [ns domain], [ns type], [ns name]); 347 | NSLog(@"Error Dict: %@", errorDict); 348 | } 349 | 350 | @end 351 | -------------------------------------------------------------------------------- /Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/Default.png -------------------------------------------------------------------------------- /DetailViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 528 5 | 9G55 6 | 677 7 | 949.43 8 | 353.00 9 | 10 | YES 11 | 12 | 13 | 14 | YES 15 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 16 | 17 | 18 | YES 19 | 20 | YES 21 | 22 | 23 | YES 24 | 25 | 26 | 27 | YES 28 | 29 | IBFilesOwner 30 | 31 | 32 | IBFirstResponder 33 | 34 | 35 | 36 | 292 37 | 38 | YES 39 | 40 | 41 | 292 42 | {320, 416} 43 | 44 | NO 45 | YES 46 | 1 47 | YES 48 | NO 49 | NO 50 | NO 51 | NO 52 | 0.000000e+00 53 | 0.000000e+00 54 | NO 55 | NO 56 | 57 | 58 | Courier 59 | 1.200000e+01 60 | 16 61 | 62 | 63 | 64 | 65 | 292 66 | {320, 416} 67 | 68 | NO 69 | NO 70 | 1 71 | NO 72 | 73 | 74 | {320, 416} 75 | 76 | 77 | 3 78 | MQA 79 | 80 | 2 81 | 82 | 83 | NO 84 | 85 | 86 | 87 | 88 | YES 89 | 90 | 91 | textView 92 | 93 | 94 | 95 | 9 96 | 97 | 98 | 99 | imageView 100 | 101 | 102 | 103 | 10 104 | 105 | 106 | 107 | view 108 | 109 | 110 | 111 | 11 112 | 113 | 114 | 115 | 116 | YES 117 | 118 | 0 119 | 120 | YES 121 | 122 | 123 | 124 | 125 | 126 | -1 127 | 128 | 129 | RmlsZSdzIE93bmVyA 130 | 131 | 132 | -2 133 | 134 | 135 | 136 | 137 | 2 138 | 139 | 140 | YES 141 | 142 | 143 | 144 | 145 | 146 | 147 | 4 148 | 149 | 150 | 151 | 152 | 5 153 | 154 | 155 | 156 | 157 | 158 | 159 | YES 160 | 161 | YES 162 | -1.CustomClassName 163 | -2.CustomClassName 164 | 2.IBEditorWindowLastContentRect 165 | 2.IBPluginDependency 166 | 4.IBPluginDependency 167 | 5.IBPluginDependency 168 | 169 | 170 | YES 171 | DetailViewController 172 | UIResponder 173 | {{62, 440}, {320, 416}} 174 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 175 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 176 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 177 | 178 | 179 | 180 | YES 181 | 182 | YES 183 | 184 | 185 | YES 186 | 187 | 188 | 189 | 190 | YES 191 | 192 | YES 193 | 194 | 195 | YES 196 | 197 | 198 | 199 | 17 200 | 201 | 202 | 203 | YES 204 | 205 | DetailViewController 206 | UIViewController 207 | 208 | YES 209 | 210 | YES 211 | imageView 212 | textView 213 | 214 | 215 | YES 216 | UIImageView 217 | UITextView 218 | 219 | 220 | 221 | IBProjectSource 222 | Classes/DetailViewController.h 223 | 224 | 225 | 226 | NSObject 227 | 228 | IBProjectSource 229 | CocoaHTTPServer/AsyncSocket.h 230 | 231 | 232 | 233 | 234 | 0 235 | FSWalker.xcodeproj 236 | 3 237 | 238 | 239 | -------------------------------------------------------------------------------- /FSItemCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 512 5 | 9G55 6 | 677 7 | 949.43 8 | 353.00 9 | 10 | YES 11 | 12 | 13 | 14 | YES 15 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 16 | 17 | 18 | YES 19 | 20 | YES 21 | 22 | 23 | YES 24 | 25 | 26 | 27 | YES 28 | 29 | IBFilesOwner 30 | 31 | 32 | IBFirstResponder 33 | 34 | 35 | 36 | 292 37 | 38 | YES 39 | 40 | 41 | 256 42 | 43 | YES 44 | 45 | 46 | 292 47 | {{60, 11}, {237, 21}} 48 | 49 | NO 50 | YES 51 | NO 52 | Label 53 | 54 | 1 55 | MCAwIDAAA 56 | 57 | 58 | 1 59 | 1.000000e+01 60 | 61 | 62 | 63 | 292 64 | {{20, 6}, {32, 32}} 65 | 66 | NO 67 | 0 68 | 0 69 | 70 | Helvetica-Bold 71 | 1.500000e+01 72 | 16 73 | 74 | 75 | 76 | 77 | 78 | 79 | 1 80 | MSAxIDEAA 81 | 82 | 83 | 1 84 | MC4xOTYwNzg0MyAwLjMwOTgwMzkzIDAuNTIxNTY4NjYAA 85 | 86 | 87 | 88 | {297, 44} 89 | 90 | 91 | 3 92 | MCAwAA 93 | 94 | NO 95 | YES 96 | 4 97 | YES 98 | 99 | 100 | {320, 44} 101 | 102 | 103 | 3 104 | MSAwAA 105 | 106 | NO 107 | NO 108 | 1 109 | 110 | FSItemCell 111 | 112 | 113 | 114 | 115 | YES 116 | 117 | 118 | iconButton 119 | 120 | 121 | 122 | 11 123 | 124 | 125 | 126 | label 127 | 128 | 129 | 130 | 12 131 | 132 | 133 | 134 | showInfo: 135 | 136 | 137 | 7 138 | 139 | 16 140 | 141 | 142 | 143 | 144 | YES 145 | 146 | 0 147 | 148 | YES 149 | 150 | 151 | 152 | 153 | 154 | -1 155 | 156 | 157 | RmlsZSdzIE93bmVyA 158 | 159 | 160 | -2 161 | 162 | 163 | 164 | 165 | 2 166 | 167 | 168 | YES 169 | 170 | 171 | 172 | 173 | 174 | 175 | 5 176 | 177 | 178 | 179 | 180 | 10 181 | 182 | 183 | 184 | 185 | 186 | 187 | YES 188 | 189 | YES 190 | -1.CustomClassName 191 | -2.CustomClassName 192 | 10.IBPluginDependency 193 | 2.CustomClassName 194 | 2.IBEditorWindowLastContentRect 195 | 2.IBPluginDependency 196 | 5.IBPluginDependency 197 | 198 | 199 | YES 200 | RootViewController 201 | UIResponder 202 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 203 | FSItemCell 204 | {{21, 778}, {320, 44}} 205 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 206 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 207 | 208 | 209 | 210 | YES 211 | 212 | YES 213 | 214 | 215 | YES 216 | 217 | 218 | 219 | 220 | YES 221 | 222 | YES 223 | 224 | 225 | YES 226 | 227 | 228 | 229 | 16 230 | 231 | 232 | 233 | YES 234 | 235 | FSItemCell 236 | UITableViewCell 237 | 238 | showInfo: 239 | id 240 | 241 | 242 | YES 243 | 244 | YES 245 | iconButton 246 | label 247 | 248 | 249 | YES 250 | UIButton 251 | UILabel 252 | 253 | 254 | 255 | IBProjectSource 256 | Classes/FSItemCell.h 257 | 258 | 259 | 260 | RootViewController 261 | UITableViewController 262 | 263 | IBProjectSource 264 | Classes/RootViewController.h 265 | 266 | 267 | 268 | 269 | 0 270 | FSWalker.xcodeproj 271 | 3 272 | 273 | 274 | -------------------------------------------------------------------------------- /FSWHTTPConnection.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSWHTTPConnection.h 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 01.02.09. 6 | // Copyright 2009 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "HTTPConnection.h" 10 | 11 | @interface FSWHTTPConnection : HTTPConnection { 12 | 13 | } 14 | 15 | @end 16 | 17 | @interface NSString (FSWalker) 18 | - (BOOL)isDirectory; 19 | @end 20 | -------------------------------------------------------------------------------- /FSWHTTPConnection.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSWHTTPConnection.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 01.02.09. 6 | // Copyright 2009 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "FSWHTTPConnection.h" 10 | #import "HTTPResponse.h" 11 | #import "NSNumber+Bytes.h" 12 | #import "MyIP.h" 13 | 14 | @implementation NSString (FSWalker) 15 | 16 | - (BOOL)isDirectory { 17 | BOOL isDir = NO; 18 | return [[NSFileManager defaultManager] fileExistsAtPath:self isDirectory:&isDir] && isDir; 19 | } 20 | 21 | - (NSString *)lastChange { 22 | NSDictionary *d = [[NSFileManager defaultManager] attributesOfItemAtPath:self error:nil]; 23 | NSString *s = [[d objectForKey:NSFileModificationDate] description]; 24 | return s ? s : @"-"; 25 | } 26 | 27 | - (NSString *)prettySize { 28 | if([self isDirectory]) return @"-"; 29 | 30 | NSDictionary *d = [[NSFileManager defaultManager] attributesOfItemAtPath:self error:nil]; 31 | NSNumber *n = [NSNumber numberWithLongLong:[[d objectForKey:NSFileSize] longLongValue]]; 32 | NSString *s = [n prettyBytes]; 33 | return s ? s : @"-"; 34 | } 35 | 36 | @end 37 | 38 | @implementation FSWHTTPConnection 39 | 40 | - (NSString *)myIP { 41 | NSString *myIP = [[[MyIP sharedInstance] ipsForInterfaces] objectForKey:@"en0"]; 42 | 43 | #if TARGET_IPHONE_SIMULATOR 44 | if(!myIP) { 45 | myIP = [[[MyIP sharedInstance] ipsForInterfaces] objectForKey:@"en1"]; 46 | } 47 | #endif 48 | 49 | return myIP; 50 | } 51 | 52 | /** 53 | * Converts relative URI path into full file-system path. 54 | **/ 55 | - (NSString *)filePathForURI:(NSString *)path 56 | { 57 | 58 | // Convert path to a relative path. 59 | // This essentially means trimming beginning '/' characters. 60 | // Beware of a bug in the Cocoa framework: 61 | // 62 | // [NSURL URLWithString:@"/foo" relativeToURL:baseURL] == @"/baseURL/foo" 63 | // [NSURL URLWithString:@"/foo%20bar" relativeToURL:baseURL] == @"/foo bar" 64 | // [NSURL URLWithString:@"/foo" relativeToURL:baseURL] == @"/foo" 65 | 66 | NSString *relativePath = path; 67 | 68 | while([relativePath hasPrefix:@"/"] && [relativePath length] > 1) { 69 | relativePath = [relativePath substringFromIndex:1]; 70 | } 71 | 72 | NSURL *url = [NSURL URLWithString:relativePath relativeToURL:[NSURL URLWithString:@"/"]]; 73 | 74 | // Watch out for sneaky requests with ".." in the path 75 | // For example, the following request: "../Documents/TopSecret.doc" 76 | if(![[url path] hasPrefix:@"/"]) return nil; 77 | 78 | return [[url path] stringByStandardizingPath]; 79 | } 80 | 81 | /** 82 | * This method is called to get a response for a request. 83 | * You may return any object that adopts the HTTPResponse protocol. 84 | * The HTTPServer comes with two such classes: HTTPFileResponse and HTTPDataResponse. 85 | * HTTPFileResponse is a wrapper for an NSFileHandle object, and is the preferred way to send a file response. 86 | * HTTPDataResponse is a wrapper for an NSData object, and may be used to send a custom response. 87 | **/ 88 | - (NSObject *)httpResponseForMethod:(NSString *)method URI:(NSString *)path 89 | { 90 | // Override me to provide custom responses. 91 | 92 | NSString *filePath = [self filePathForURI:path]; 93 | 94 | BOOL isDir = NO; 95 | 96 | if([[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDir]) { 97 | if(isDir) { 98 | NSMutableString *html = [[NSMutableString alloc] init]; 99 | [html appendString:@"\n"]; 100 | [html appendFormat:@"\n\nIndex of %@\n\n\n", filePath]; 101 | [html appendFormat:@"

Index of %@

\n
\n", filePath];
102 | 
103 | 			NSString *iconFolder = [[NSBundle mainBundle] pathForResource:@"folder" ofType:@"gif"];
104 | 			NSString *iconGeneric = [[NSBundle mainBundle] pathForResource:@"generic" ofType:@"gif"];
105 | 			NSString *iconBack = [[NSBundle mainBundle] pathForResource:@"back" ofType:@"gif"];
106 | 			NSString *iconImage = [[NSBundle mainBundle] pathForResource:@"image2" ofType:@"gif"];
107 | 			NSString *iconPdf = [[NSBundle mainBundle] pathForResource:@"image2" ofType:@"gif"];
108 | 			NSString *iconBlank = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"gif"];
109 | 			
110 | 			NSString *parentDirPad = [@"Name" stringByPaddingToLength:48 withString:@" " startingAtIndex:0];
111 | 			NSString *lastChangePad = [@"Last modified" stringByPaddingToLength:28 withString:@" " startingAtIndex:0];
112 | 			NSString *sizePad = [@"Size" stringByPaddingToLength:28 withString:@" " startingAtIndex:0];
113 | 			
114 | 			[html appendFormat:@" %@    %@  %@
", iconBlank, parentDirPad, lastChangePad, sizePad]; 115 | 116 | [html appendFormat:@" Parent Directory\n", iconBack, [filePath stringByDeletingLastPathComponent]]; 117 | 118 | NSError *error = nil; 119 | NSArray *a = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePath error:&error]; 120 | if(!error && a) { 121 | for(NSString *s in a) { 122 | NSString *dest = [filePath stringByAppendingPathComponent:s]; 123 | NSString *ext = [[s pathExtension] lowercaseString]; 124 | NSString *iconPath = iconGeneric; 125 | if([dest isDirectory]) { 126 | iconPath = iconFolder; 127 | } else if ([[NSArray arrayWithObjects:@"png", @"gif", @"jpg", nil] containsObject:ext]) { 128 | iconPath = iconImage; 129 | } else if ([ext isEqualToString:@"pdf"]) { 130 | iconPath = iconPdf; 131 | } 132 | 133 | NSString *lastChange = [[dest lastChange] stringByPaddingToLength:28 withString:@" " startingAtIndex:0]; 134 | NSString *prettySize = [[dest prettySize] stringByPaddingToLength:28 withString:@" " startingAtIndex:0]; 135 | 136 | NSString *pad = @" "; 137 | int padLength = 48-[[s lastPathComponent] length]; 138 | if (padLength > 0) 139 | pad = [@"" stringByPaddingToLength:padLength withString:@" " startingAtIndex:0]; 140 | 141 | [html appendFormat:@" %@ %@ %@ %@\n", iconPath, dest, [s lastPathComponent], pad, lastChange, prettySize]; 142 | } 143 | } 144 | 145 | [html appendFormat:@"
\n
%@/CocoaHTTPServer on %@ %@, at %@ (%@) Port %u
\n\n\n", 146 | [[NSProcessInfo processInfo] processName], [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion], [self myIP], [[NSProcessInfo processInfo] hostName], [server port]]; 147 | 148 | NSData *data = [html dataUsingEncoding:NSUTF8StringEncoding]; 149 | [html release]; 150 | 151 | HTTPDataResponse *r = [[HTTPDataResponse alloc] initWithData:data]; 152 | return [r autorelease]; 153 | 154 | } else { 155 | if([[filePath pathExtension] isEqualToString:@"plist"]) { 156 | id plist = [NSDictionary dictionaryWithContentsOfFile:filePath]; 157 | if(!plist) plist = [NSArray arrayWithContentsOfFile:filePath]; 158 | if(!plist) return [[[HTTPDataResponse alloc] initWithData:nil] autorelease]; 159 | 160 | NSString *errorString = nil; 161 | NSData *data = [NSPropertyListSerialization dataFromPropertyList:plist format:kCFPropertyListXMLFormat_v1_0 errorDescription:&errorString]; 162 | if(errorString) { 163 | data = [errorString dataUsingEncoding:NSUTF8StringEncoding]; 164 | return [[[HTTPDataResponse alloc] initWithData:data] autorelease]; 165 | } else { 166 | return [[[HTTPDataResponse alloc] initWithData:data] autorelease]; // FIXME: return HTTP header Content-Type: text/plain 167 | } 168 | } 169 | 170 | return [[[HTTPFileResponse alloc] initWithFilePath:filePath] autorelease]; 171 | } 172 | } 173 | 174 | return nil; 175 | } 176 | 177 | 178 | @end 179 | -------------------------------------------------------------------------------- /FSWalker.xcodeproj/nst.pbxuser: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | 031AA8620E57D08E009DD8A4 /* FSWalker */ = { 4 | isa = PBXExecutable; 5 | activeArgIndices = ( 6 | ); 7 | argumentStrings = ( 8 | ); 9 | autoAttachOnCrash = 1; 10 | breakpointsEnabled = 1; 11 | configStateDict = { 12 | }; 13 | customDataFormattersEnabled = 1; 14 | dataTipCustomDataFormattersEnabled = 1; 15 | dataTipShowTypeColumn = 1; 16 | dataTipSortType = 0; 17 | debuggerPlugin = GDBDebugging; 18 | disassemblyDisplayState = 0; 19 | dylibVariantSuffix = ""; 20 | enableDebugStr = 1; 21 | environmentEntries = ( 22 | ); 23 | executableSystemSymbolLevel = 0; 24 | executableUserSymbolLevel = 0; 25 | libgmallocEnabled = 0; 26 | name = FSWalker; 27 | savedGlobals = { 28 | }; 29 | showTypeColumn = 0; 30 | sourceDirectories = ( 31 | ); 32 | variableFormatDictionary = { 33 | }; 34 | }; 35 | 031AA86C0E57D0AD009DD8A4 /* Source Control */ = { 36 | isa = PBXSourceControlManager; 37 | fallbackIsa = XCSourceControlManager; 38 | isSCMEnabled = 0; 39 | scmConfiguration = { 40 | repositoryNamesForRoots = { 41 | "" = ""; 42 | }; 43 | }; 44 | }; 45 | 031AA86D0E57D0AD009DD8A4 /* Code sense */ = { 46 | isa = PBXCodeSenseManager; 47 | indexTemplatePath = ""; 48 | }; 49 | 031AA86F0E57D185009DD8A4 /* FSItem.h */ = { 50 | uiCtxt = { 51 | sepNavIntBoundsRect = "{{0, 0}, {1167, 572}}"; 52 | sepNavSelRange = "{223, 0}"; 53 | sepNavVisRange = "{0, 904}"; 54 | }; 55 | }; 56 | 031AA8700E57D185009DD8A4 /* FSItem.m */ = { 57 | uiCtxt = { 58 | sepNavIntBoundsRect = "{{0, 0}, {1167, 1781}}"; 59 | sepNavSelRange = "{2592, 0}"; 60 | sepNavVisRange = "{2090, 1082}"; 61 | sepNavWindowFrame = "{{38, 33}, {1355, 819}}"; 62 | }; 63 | }; 64 | 0381F76F12EC93850011341E /* PBXTextBookmark */ = { 65 | isa = PBXTextBookmark; 66 | fRef = 1D3623250D0F684500981E51 /* FSWalkerAppDelegate.m */; 67 | name = "FSWalkerAppDelegate.m: 13"; 68 | rLen = 0; 69 | rLoc = 274; 70 | rType = 0; 71 | vrLen = 728; 72 | vrLoc = 29; 73 | }; 74 | 0381F77512EC93BC0011341E /* PBXTextBookmark */ = { 75 | isa = PBXTextBookmark; 76 | fRef = 03EE3C120F3622A200DF5A2D /* HTTPServer.h */; 77 | name = "HTTPServer.h: 6"; 78 | rLen = 0; 79 | rLoc = 112; 80 | rType = 0; 81 | vrLen = 694; 82 | vrLoc = 0; 83 | }; 84 | 0381F77612EC93BC0011341E /* PBXTextBookmark */ = { 85 | isa = PBXTextBookmark; 86 | fRef = 03EE3C130F3622A200DF5A2D /* HTTPServer.m */; 87 | name = "HTTPServer.m: 14"; 88 | rLen = 0; 89 | rLoc = 229; 90 | rType = 0; 91 | vrLen = 1035; 92 | vrLoc = 0; 93 | }; 94 | 0381F77712EC93BC0011341E /* PBXTextBookmark */ = { 95 | isa = PBXTextBookmark; 96 | fRef = 03EE3C0E0F3622A200DF5A2D /* HTTPConnection.h */; 97 | name = "HTTPConnection.h: 8"; 98 | rLen = 0; 99 | rLoc = 184; 100 | rType = 0; 101 | vrLen = 771; 102 | vrLoc = 0; 103 | }; 104 | 039205100E5869A600F128FF /* GenericDocumentIcon.png */ = { 105 | uiCtxt = { 106 | sepNavWindowFrame = "{{15, 54}, {1355, 819}}"; 107 | }; 108 | }; 109 | 039205650E586B8000F128FF /* FSItemCell.h */ = { 110 | uiCtxt = { 111 | sepNavIntBoundsRect = "{{0, 0}, {1167, 458}}"; 112 | sepNavSelRange = "{156, 14}"; 113 | sepNavVisRange = "{0, 443}"; 114 | }; 115 | }; 116 | 039205660E586B8000F128FF /* FSItemCell.m */ = { 117 | uiCtxt = { 118 | sepNavIntBoundsRect = "{{0, 0}, {1109, 819}}"; 119 | sepNavSelRange = "{774, 0}"; 120 | sepNavVisRange = "{425, 884}"; 121 | }; 122 | }; 123 | 03E0571D12E9AA0D00800058 /* PBXTextBookmark */ = { 124 | isa = PBXTextBookmark; 125 | fRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; 126 | name = "RootViewController.m: 84"; 127 | rLen = 0; 128 | rLoc = 2198; 129 | rType = 0; 130 | vrLen = 605; 131 | vrLoc = 1124; 132 | }; 133 | 03E0574612E9AC2D00800058 /* PBXTextBookmark */ = { 134 | isa = PBXTextBookmark; 135 | fRef = 03EE3C7A0F36253100DF5A2D /* FSWHTTPConnection.m */; 136 | name = "FSWHTTPConnection.m: 30"; 137 | rLen = 0; 138 | rLoc = 694; 139 | rType = 0; 140 | vrLen = 948; 141 | vrLoc = 134; 142 | }; 143 | 03E0574712E9AC2D00800058 /* PBXTextBookmark */ = { 144 | isa = PBXTextBookmark; 145 | fRef = 1D3623240D0F684500981E51 /* FSWalkerAppDelegate.h */; 146 | name = "FSWalkerAppDelegate.h: 22"; 147 | rLen = 10; 148 | rLoc = 486; 149 | rType = 0; 150 | vrLen = 699; 151 | vrLoc = 0; 152 | }; 153 | 03E75D1E0E58B0110044A3C8 /* InfoPanelController.h */ = { 154 | uiCtxt = { 155 | sepNavIntBoundsRect = "{{0, 0}, {1167, 458}}"; 156 | sepNavSelRange = "{165, 14}"; 157 | sepNavVisRange = "{0, 718}"; 158 | }; 159 | }; 160 | 03E75D1F0E58B0110044A3C8 /* InfoPanelController.m */ = { 161 | uiCtxt = { 162 | sepNavIntBoundsRect = "{{0, 0}, {751, 1204}}"; 163 | sepNavSelRange = "{485, 0}"; 164 | sepNavVisRange = "{45, 748}"; 165 | }; 166 | }; 167 | 03EE37B60F35E8C600DF5A2D /* DetailViewController.h */ = { 168 | uiCtxt = { 169 | sepNavIntBoundsRect = "{{0, 0}, {1379, 322}}"; 170 | sepNavSelRange = "{254, 0}"; 171 | sepNavVisRange = "{43, 326}"; 172 | }; 173 | }; 174 | 03EE37B70F35E8C600DF5A2D /* DetailViewController.m */ = { 175 | uiCtxt = { 176 | sepNavIntBoundsRect = "{{0, 0}, {1517, 1794}}"; 177 | sepNavSelRange = "{175, 14}"; 178 | sepNavVisRange = "{737, 1461}"; 179 | }; 180 | }; 181 | 03EE3A0D0F360F1E00DF5A2D /* NSNumber+Bytes.h */ = { 182 | uiCtxt = { 183 | sepNavIntBoundsRect = "{{0, 0}, {1109, 458}}"; 184 | sepNavSelRange = "{22, 0}"; 185 | sepNavVisRange = "{0, 98}"; 186 | }; 187 | }; 188 | 03EE3A0E0F360F1E00DF5A2D /* NSNumber+Bytes.m */ = { 189 | uiCtxt = { 190 | sepNavIntBoundsRect = "{{0, 0}, {1109, 458}}"; 191 | sepNavSelRange = "{395, 0}"; 192 | sepNavVisRange = "{0, 580}"; 193 | }; 194 | }; 195 | 03EE3BF90F36220900DF5A2D /* MyIP.h */ = { 196 | uiCtxt = { 197 | sepNavIntBoundsRect = "{{0, 0}, {1167, 489}}"; 198 | sepNavSelRange = "{187, 0}"; 199 | sepNavVisRange = "{0, 256}"; 200 | }; 201 | }; 202 | 03EE3BFA0F36220900DF5A2D /* MyIP.m */ = { 203 | uiCtxt = { 204 | sepNavIntBoundsRect = "{{0, 0}, {1109, 676}}"; 205 | sepNavSelRange = "{66, 0}"; 206 | sepNavVisRange = "{229, 834}"; 207 | }; 208 | }; 209 | 03EE3C040F3622A200DF5A2D /* AsyncSocket.h */ = { 210 | uiCtxt = { 211 | sepNavIntBoundsRect = "{{0, 0}, {739, 5082}}"; 212 | sepNavSelRange = "{0, 0}"; 213 | sepNavVisRange = "{0, 866}"; 214 | }; 215 | }; 216 | 03EE3C050F3622A200DF5A2D /* AsyncSocket.m */ = { 217 | uiCtxt = { 218 | sepNavIntBoundsRect = "{{0, 0}, {1109, 36218}}"; 219 | sepNavSelRange = "{28817, 0}"; 220 | sepNavVisRange = "{27959, 1512}"; 221 | }; 222 | }; 223 | 03EE3C060F3622A200DF5A2D /* DDData.h */ = { 224 | uiCtxt = { 225 | sepNavIntBoundsRect = "{{0, 0}, {1167, 489}}"; 226 | sepNavSelRange = "{204, 1}"; 227 | sepNavVisRange = "{0, 205}"; 228 | }; 229 | }; 230 | 03EE3C070F3622A200DF5A2D /* DDData.m */ = { 231 | uiCtxt = { 232 | sepNavIntBoundsRect = "{{0, 0}, {739, 2828}}"; 233 | sepNavSelRange = "{1460, 27}"; 234 | sepNavVisRange = "{0, 974}"; 235 | }; 236 | }; 237 | 03EE3C080F3622A200DF5A2D /* DDNumber.h */ = { 238 | uiCtxt = { 239 | sepNavIntBoundsRect = "{{0, 0}, {1167, 489}}"; 240 | sepNavSelRange = "{67, 210}"; 241 | sepNavVisRange = "{0, 341}"; 242 | }; 243 | }; 244 | 03EE3C090F3622A200DF5A2D /* DDNumber.m */ = { 245 | uiCtxt = { 246 | sepNavIntBoundsRect = "{{0, 0}, {739, 1078}}"; 247 | sepNavSelRange = "{0, 0}"; 248 | sepNavVisRange = "{0, 773}"; 249 | }; 250 | }; 251 | 03EE3C0A0F3622A200DF5A2D /* DDRange.h */ = { 252 | uiCtxt = { 253 | sepNavIntBoundsRect = "{{0, 0}, {1167, 689}}"; 254 | sepNavSelRange = "{0, 0}"; 255 | sepNavVisRange = "{505, 1004}"; 256 | }; 257 | }; 258 | 03EE3C0C0F3622A200DF5A2D /* HTTPAuthenticationRequest.h */ = { 259 | uiCtxt = { 260 | sepNavIntBoundsRect = "{{0, 0}, {739, 616}}"; 261 | sepNavSelRange = "{0, 0}"; 262 | sepNavVisRange = "{0, 740}"; 263 | }; 264 | }; 265 | 03EE3C0E0F3622A200DF5A2D /* HTTPConnection.h */ = { 266 | uiCtxt = { 267 | sepNavIntBoundsRect = "{{0, 0}, {1109, 962}}"; 268 | sepNavSelRange = "{184, 0}"; 269 | sepNavVisRange = "{0, 771}"; 270 | }; 271 | }; 272 | 03EE3C0F0F3622A200DF5A2D /* HTTPConnection.m */ = { 273 | uiCtxt = { 274 | sepNavIntBoundsRect = "{{0, 0}, {1109, 19799}}"; 275 | sepNavSelRange = "{22369, 0}"; 276 | sepNavVisRange = "{1392, 1744}"; 277 | }; 278 | }; 279 | 03EE3C100F3622A200DF5A2D /* HTTPResponse.h */ = { 280 | uiCtxt = { 281 | sepNavIntBoundsRect = "{{0, 0}, {1153, 588}}"; 282 | sepNavSelRange = "{587, 12}"; 283 | sepNavVisRange = "{138, 484}"; 284 | }; 285 | }; 286 | 03EE3C110F3622A200DF5A2D /* HTTPResponse.m */ = { 287 | uiCtxt = { 288 | sepNavIntBoundsRect = "{{0, 0}, {1109, 1378}}"; 289 | sepNavSelRange = "{405, 0}"; 290 | sepNavVisRange = "{0, 702}"; 291 | }; 292 | }; 293 | 03EE3C120F3622A200DF5A2D /* HTTPServer.h */ = { 294 | uiCtxt = { 295 | sepNavIntBoundsRect = "{{0, 0}, {1109, 780}}"; 296 | sepNavSelRange = "{112, 0}"; 297 | sepNavVisRange = "{0, 694}"; 298 | }; 299 | }; 300 | 03EE3C130F3622A200DF5A2D /* HTTPServer.m */ = { 301 | uiCtxt = { 302 | sepNavIntBoundsRect = "{{0, 0}, {1109, 4537}}"; 303 | sepNavSelRange = "{229, 0}"; 304 | sepNavVisRange = "{0, 1035}"; 305 | }; 306 | }; 307 | 03EE3C790F36253100DF5A2D /* FSWHTTPConnection.h */ = { 308 | uiCtxt = { 309 | sepNavIntBoundsRect = "{{0, 0}, {739, 609}}"; 310 | sepNavSelRange = "{197, 14}"; 311 | sepNavVisRange = "{0, 282}"; 312 | }; 313 | }; 314 | 03EE3C7A0F36253100DF5A2D /* FSWHTTPConnection.m */ = { 315 | uiCtxt = { 316 | sepNavIntBoundsRect = "{{0, 0}, {1391, 2522}}"; 317 | sepNavSelRange = "{694, 0}"; 318 | sepNavVisRange = "{410, 469}"; 319 | }; 320 | }; 321 | 1D3623240D0F684500981E51 /* FSWalkerAppDelegate.h */ = { 322 | uiCtxt = { 323 | sepNavIntBoundsRect = "{{0, 0}, {1109, 458}}"; 324 | sepNavSelRange = "{486, 10}"; 325 | sepNavVisRange = "{0, 699}"; 326 | }; 327 | }; 328 | 1D3623250D0F684500981E51 /* FSWalkerAppDelegate.m */ = { 329 | uiCtxt = { 330 | sepNavIntBoundsRect = "{{0, 0}, {1109, 2158}}"; 331 | sepNavSelRange = "{274, 0}"; 332 | sepNavVisRange = "{29, 728}"; 333 | }; 334 | }; 335 | 1D6058900D05DD3D006BFB54 /* FSWalker */ = { 336 | activeExec = 0; 337 | executables = ( 338 | 031AA8620E57D08E009DD8A4 /* FSWalker */, 339 | ); 340 | }; 341 | 28A0AAE50D9B0CCF005BE974 /* FSWalker_Prefix.pch */ = { 342 | uiCtxt = { 343 | sepNavIntBoundsRect = "{{0, 0}, {1153, 509}}"; 344 | sepNavSelRange = "{65, 4}"; 345 | sepNavVisRange = "{0, 179}"; 346 | }; 347 | }; 348 | 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = { 349 | uiCtxt = { 350 | sepNavIntBoundsRect = "{{0, 0}, {1109, 458}}"; 351 | sepNavSelRange = "{163, 0}"; 352 | sepNavVisRange = "{0, 307}"; 353 | }; 354 | }; 355 | 28C286E00D94DF7D0034E888 /* RootViewController.m */ = { 356 | uiCtxt = { 357 | sepNavIntBoundsRect = "{{0, 0}, {1391, 1703}}"; 358 | sepNavSelRange = "{2198, 0}"; 359 | sepNavVisRange = "{1124, 605}"; 360 | }; 361 | }; 362 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 363 | activeBuildConfigurationName = Debug; 364 | activeExecutable = 031AA8620E57D08E009DD8A4 /* FSWalker */; 365 | activeSDKPreference = iphoneos4.3; 366 | activeTarget = 1D6058900D05DD3D006BFB54 /* FSWalker */; 367 | addToTargets = ( 368 | 1D6058900D05DD3D006BFB54 /* FSWalker */, 369 | ); 370 | breakpoints = ( 371 | ); 372 | codeSenseManager = 031AA86D0E57D0AD009DD8A4 /* Code sense */; 373 | executables = ( 374 | 031AA8620E57D08E009DD8A4 /* FSWalker */, 375 | ); 376 | perUserDictionary = { 377 | "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = { 378 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 379 | PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID; 380 | PBXFileTableDataSourceColumnWidthsKey = ( 381 | 20, 382 | 20, 383 | 198, 384 | 20, 385 | 99, 386 | 99, 387 | 29, 388 | 20, 389 | ); 390 | PBXFileTableDataSourceColumnsKey = ( 391 | PBXBreakpointsDataSource_ActionID, 392 | PBXBreakpointsDataSource_TypeID, 393 | PBXBreakpointsDataSource_BreakpointID, 394 | PBXBreakpointsDataSource_UseID, 395 | PBXBreakpointsDataSource_LocationID, 396 | PBXBreakpointsDataSource_ConditionID, 397 | PBXBreakpointsDataSource_IgnoreCountID, 398 | PBXBreakpointsDataSource_ContinueID, 399 | ); 400 | }; 401 | PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { 402 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 403 | PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; 404 | PBXFileTableDataSourceColumnWidthsKey = ( 405 | 200, 406 | 200, 407 | 649.58349609375, 408 | ); 409 | PBXFileTableDataSourceColumnsKey = ( 410 | PBXBookmarksDataSource_LocationID, 411 | PBXBookmarksDataSource_NameID, 412 | PBXBookmarksDataSource_CommentsID, 413 | ); 414 | }; 415 | PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = { 416 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 417 | PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID; 418 | PBXFileTableDataSourceColumnWidthsKey = ( 419 | 20, 420 | 300, 421 | 865, 422 | ); 423 | PBXFileTableDataSourceColumnsKey = ( 424 | PBXErrorsWarningsDataSource_TypeID, 425 | PBXErrorsWarningsDataSource_MessageID, 426 | PBXErrorsWarningsDataSource_LocationID, 427 | ); 428 | }; 429 | PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { 430 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 431 | PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; 432 | PBXFileTableDataSourceColumnWidthsKey = ( 433 | 22, 434 | 300, 435 | 864.58349609375, 436 | ); 437 | PBXFileTableDataSourceColumnsKey = ( 438 | PBXExecutablesDataSource_ActiveFlagID, 439 | PBXExecutablesDataSource_NameID, 440 | PBXExecutablesDataSource_CommentsID, 441 | ); 442 | }; 443 | PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { 444 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 445 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 446 | PBXFileTableDataSourceColumnWidthsKey = ( 447 | 20, 448 | 919, 449 | 20, 450 | 48, 451 | 43, 452 | 43, 453 | 20, 454 | ); 455 | PBXFileTableDataSourceColumnsKey = ( 456 | PBXFileDataSource_FiletypeID, 457 | PBXFileDataSource_Filename_ColumnID, 458 | PBXFileDataSource_Built_ColumnID, 459 | PBXFileDataSource_ObjectSize_ColumnID, 460 | PBXFileDataSource_Errors_ColumnID, 461 | PBXFileDataSource_Warnings_ColumnID, 462 | PBXFileDataSource_Target_ColumnID, 463 | ); 464 | }; 465 | PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = { 466 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 467 | PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_MessageID; 468 | PBXFileTableDataSourceColumnWidthsKey = ( 469 | 485, 470 | 648, 471 | ); 472 | PBXFileTableDataSourceColumnsKey = ( 473 | PBXFindDataSource_MessageID, 474 | PBXFindDataSource_LocationID, 475 | ); 476 | }; 477 | PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { 478 | PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; 479 | PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; 480 | PBXFileTableDataSourceColumnWidthsKey = ( 481 | 20, 482 | 879, 483 | 60, 484 | 20, 485 | 48, 486 | 43, 487 | 43, 488 | ); 489 | PBXFileTableDataSourceColumnsKey = ( 490 | PBXFileDataSource_FiletypeID, 491 | PBXFileDataSource_Filename_ColumnID, 492 | PBXTargetDataSource_PrimaryAttribute, 493 | PBXFileDataSource_Built_ColumnID, 494 | PBXFileDataSource_ObjectSize_ColumnID, 495 | PBXFileDataSource_Errors_ColumnID, 496 | PBXFileDataSource_Warnings_ColumnID, 497 | ); 498 | }; 499 | PBXPerProjectTemplateStateSaveDate = 325019922; 500 | PBXWorkspaceStateSaveDate = 325019922; 501 | }; 502 | perUserProjectItems = { 503 | 0381F76F12EC93850011341E /* PBXTextBookmark */ = 0381F76F12EC93850011341E /* PBXTextBookmark */; 504 | 0381F77512EC93BC0011341E /* PBXTextBookmark */ = 0381F77512EC93BC0011341E /* PBXTextBookmark */; 505 | 0381F77612EC93BC0011341E /* PBXTextBookmark */ = 0381F77612EC93BC0011341E /* PBXTextBookmark */; 506 | 0381F77712EC93BC0011341E /* PBXTextBookmark */ = 0381F77712EC93BC0011341E /* PBXTextBookmark */; 507 | 03E0571D12E9AA0D00800058 /* PBXTextBookmark */ = 03E0571D12E9AA0D00800058 /* PBXTextBookmark */; 508 | 03E0574612E9AC2D00800058 /* PBXTextBookmark */ = 03E0574612E9AC2D00800058 /* PBXTextBookmark */; 509 | 03E0574712E9AC2D00800058 /* PBXTextBookmark */ = 03E0574712E9AC2D00800058 /* PBXTextBookmark */; 510 | }; 511 | sourceControlManager = 031AA86C0E57D0AD009DD8A4 /* Source Control */; 512 | userBuildSettings = { 513 | }; 514 | }; 515 | 29B97316FDCFA39411CA2CEA /* main.m */ = { 516 | uiCtxt = { 517 | sepNavIntBoundsRect = "{{0, 0}, {1030, 528}}"; 518 | sepNavSelRange = "{383, 0}"; 519 | sepNavVisRange = "{0, 474}"; 520 | }; 521 | }; 522 | 8D1107310486CEB800E47090 /* Info.plist */ = { 523 | uiCtxt = { 524 | sepNavWindowFrame = "{{38, 4}, {942, 848}}"; 525 | }; 526 | }; 527 | } 528 | -------------------------------------------------------------------------------- /FSWalker.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 031AA8710E57D185009DD8A4 /* FSItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 031AA8700E57D185009DD8A4 /* FSItem.m */; }; 11 | 031E5E350F2E81BE002EB490 /* SymLinkIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 031E5E340F2E81BE002EB490 /* SymLinkIcon.png */; }; 12 | 039205120E5869A600F128FF /* GenericDocumentIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 039205100E5869A600F128FF /* GenericDocumentIcon.png */; }; 13 | 039205130E5869A600F128FF /* GenericFolderIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 039205110E5869A600F128FF /* GenericFolderIcon.png */; }; 14 | 039205670E586B8000F128FF /* FSItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 039205660E586B8000F128FF /* FSItemCell.m */; }; 15 | 039205690E586BBD00F128FF /* FSItemCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 039205680E586BBD00F128FF /* FSItemCell.xib */; }; 16 | 03987A990E58EC600013D995 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 03987A980E58EC600013D995 /* Default.png */; }; 17 | 03E4429A0F38DA10007601D2 /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 03E442990F38DA10007601D2 /* Icon.png */; }; 18 | 03E75D1B0E58ADC30044A3C8 /* InfoPanelController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 03E75D1A0E58ADC30044A3C8 /* InfoPanelController.xib */; }; 19 | 03E75D200E58B0110044A3C8 /* InfoPanelController.m in Sources */ = {isa = PBXBuildFile; fileRef = 03E75D1F0E58B0110044A3C8 /* InfoPanelController.m */; }; 20 | 03EE37B40F35E89700DF5A2D /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 03EE37B30F35E89700DF5A2D /* DetailViewController.xib */; }; 21 | 03EE37B80F35E8C600DF5A2D /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE37B70F35E8C600DF5A2D /* DetailViewController.m */; }; 22 | 03EE39D80F360C6600DF5A2D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03EE39D70F360C6600DF5A2D /* AudioToolbox.framework */; }; 23 | 03EE3A0F0F360F1E00DF5A2D /* NSNumber+Bytes.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3A0E0F360F1E00DF5A2D /* NSNumber+Bytes.m */; }; 24 | 03EE3BFB0F36220900DF5A2D /* MyIP.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3BFA0F36220900DF5A2D /* MyIP.m */; }; 25 | 03EE3C160F3622A200DF5A2D /* AsyncSocket.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C050F3622A200DF5A2D /* AsyncSocket.m */; }; 26 | 03EE3C170F3622A200DF5A2D /* DDData.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C070F3622A200DF5A2D /* DDData.m */; }; 27 | 03EE3C180F3622A200DF5A2D /* DDNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C090F3622A200DF5A2D /* DDNumber.m */; }; 28 | 03EE3C190F3622A200DF5A2D /* DDRange.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C0B0F3622A200DF5A2D /* DDRange.m */; }; 29 | 03EE3C1A0F3622A200DF5A2D /* HTTPAuthenticationRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C0D0F3622A200DF5A2D /* HTTPAuthenticationRequest.m */; }; 30 | 03EE3C1B0F3622A200DF5A2D /* HTTPConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C0F0F3622A200DF5A2D /* HTTPConnection.m */; }; 31 | 03EE3C1C0F3622A200DF5A2D /* HTTPResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C110F3622A200DF5A2D /* HTTPResponse.m */; }; 32 | 03EE3C1D0F3622A200DF5A2D /* HTTPServer.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C130F3622A200DF5A2D /* HTTPServer.m */; }; 33 | 03EE3C340F36238800DF5A2D /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03EE3C330F36238800DF5A2D /* CFNetwork.framework */; }; 34 | 03EE3C7B0F36253100DF5A2D /* FSWHTTPConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 03EE3C7A0F36253100DF5A2D /* FSWHTTPConnection.m */; }; 35 | 03EE3D580F3639AB00DF5A2D /* text.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3D520F3639AB00DF5A2D /* text.gif */; }; 36 | 03EE3D590F3639AB00DF5A2D /* folder.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3D530F3639AB00DF5A2D /* folder.gif */; }; 37 | 03EE3D5A0F3639AB00DF5A2D /* generic.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3D540F3639AB00DF5A2D /* generic.gif */; }; 38 | 03EE3D5B0F3639AB00DF5A2D /* image2.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3D550F3639AB00DF5A2D /* image2.gif */; }; 39 | 03EE3D5C0F3639AB00DF5A2D /* pdf.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3D560F3639AB00DF5A2D /* pdf.gif */; }; 40 | 03EE3D5D0F3639AB00DF5A2D /* back.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3D570F3639AB00DF5A2D /* back.gif */; }; 41 | 03EE3FBE0F3661C000DF5A2D /* blank.gif in Resources */ = {isa = PBXBuildFile; fileRef = 03EE3FBD0F3661C000DF5A2D /* blank.gif */; }; 42 | 03EE400D0F3672EA00DF5A2D /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 03EE400C0F3672EA00DF5A2D /* Settings.bundle */; }; 43 | 1D3623260D0F684500981E51 /* FSWalkerAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* FSWalkerAppDelegate.m */; }; 44 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 45 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 46 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 47 | 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; 48 | 2899E5600DE3E45000AC0155 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2899E55F0DE3E45000AC0155 /* RootViewController.xib */; }; 49 | 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD735F0D9D9599002E5188 /* MainWindow.xib */; }; 50 | 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28C286E00D94DF7D0034E888 /* RootViewController.m */; }; 51 | /* End PBXBuildFile section */ 52 | 53 | /* Begin PBXFileReference section */ 54 | 031AA86F0E57D185009DD8A4 /* FSItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSItem.h; sourceTree = ""; }; 55 | 031AA8700E57D185009DD8A4 /* FSItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSItem.m; sourceTree = ""; }; 56 | 031E5E340F2E81BE002EB490 /* SymLinkIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SymLinkIcon.png; sourceTree = ""; }; 57 | 039205100E5869A600F128FF /* GenericDocumentIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = GenericDocumentIcon.png; sourceTree = ""; }; 58 | 039205110E5869A600F128FF /* GenericFolderIcon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = GenericFolderIcon.png; sourceTree = ""; }; 59 | 039205650E586B8000F128FF /* FSItemCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSItemCell.h; sourceTree = ""; }; 60 | 039205660E586B8000F128FF /* FSItemCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSItemCell.m; sourceTree = ""; }; 61 | 039205680E586BBD00F128FF /* FSItemCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FSItemCell.xib; sourceTree = ""; }; 62 | 03987A980E58EC600013D995 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 63 | 03E442990F38DA10007601D2 /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 64 | 03E75D1A0E58ADC30044A3C8 /* InfoPanelController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InfoPanelController.xib; sourceTree = ""; }; 65 | 03E75D1E0E58B0110044A3C8 /* InfoPanelController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoPanelController.h; sourceTree = ""; }; 66 | 03E75D1F0E58B0110044A3C8 /* InfoPanelController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InfoPanelController.m; sourceTree = ""; }; 67 | 03EE37B30F35E89700DF5A2D /* DetailViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DetailViewController.xib; sourceTree = ""; }; 68 | 03EE37B60F35E8C600DF5A2D /* DetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; 69 | 03EE37B70F35E8C600DF5A2D /* DetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; 70 | 03EE39D70F360C6600DF5A2D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 71 | 03EE3A0D0F360F1E00DF5A2D /* NSNumber+Bytes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNumber+Bytes.h"; sourceTree = ""; }; 72 | 03EE3A0E0F360F1E00DF5A2D /* NSNumber+Bytes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNumber+Bytes.m"; sourceTree = ""; }; 73 | 03EE3BF90F36220900DF5A2D /* MyIP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyIP.h; sourceTree = ""; }; 74 | 03EE3BFA0F36220900DF5A2D /* MyIP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyIP.m; sourceTree = ""; }; 75 | 03EE3C040F3622A200DF5A2D /* AsyncSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AsyncSocket.h; path = CocoaHTTPServer/AsyncSocket.h; sourceTree = ""; }; 76 | 03EE3C050F3622A200DF5A2D /* AsyncSocket.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AsyncSocket.m; path = CocoaHTTPServer/AsyncSocket.m; sourceTree = ""; }; 77 | 03EE3C060F3622A200DF5A2D /* DDData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDData.h; path = CocoaHTTPServer/DDData.h; sourceTree = ""; }; 78 | 03EE3C070F3622A200DF5A2D /* DDData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DDData.m; path = CocoaHTTPServer/DDData.m; sourceTree = ""; }; 79 | 03EE3C080F3622A200DF5A2D /* DDNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDNumber.h; path = CocoaHTTPServer/DDNumber.h; sourceTree = ""; }; 80 | 03EE3C090F3622A200DF5A2D /* DDNumber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DDNumber.m; path = CocoaHTTPServer/DDNumber.m; sourceTree = ""; }; 81 | 03EE3C0A0F3622A200DF5A2D /* DDRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DDRange.h; path = CocoaHTTPServer/DDRange.h; sourceTree = ""; }; 82 | 03EE3C0B0F3622A200DF5A2D /* DDRange.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DDRange.m; path = CocoaHTTPServer/DDRange.m; sourceTree = ""; }; 83 | 03EE3C0C0F3622A200DF5A2D /* HTTPAuthenticationRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPAuthenticationRequest.h; path = CocoaHTTPServer/HTTPAuthenticationRequest.h; sourceTree = ""; }; 84 | 03EE3C0D0F3622A200DF5A2D /* HTTPAuthenticationRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPAuthenticationRequest.m; path = CocoaHTTPServer/HTTPAuthenticationRequest.m; sourceTree = ""; }; 85 | 03EE3C0E0F3622A200DF5A2D /* HTTPConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPConnection.h; path = CocoaHTTPServer/HTTPConnection.h; sourceTree = ""; }; 86 | 03EE3C0F0F3622A200DF5A2D /* HTTPConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPConnection.m; path = CocoaHTTPServer/HTTPConnection.m; sourceTree = ""; }; 87 | 03EE3C100F3622A200DF5A2D /* HTTPResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPResponse.h; path = CocoaHTTPServer/HTTPResponse.h; sourceTree = ""; }; 88 | 03EE3C110F3622A200DF5A2D /* HTTPResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPResponse.m; path = CocoaHTTPServer/HTTPResponse.m; sourceTree = ""; }; 89 | 03EE3C120F3622A200DF5A2D /* HTTPServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPServer.h; path = CocoaHTTPServer/HTTPServer.h; sourceTree = ""; }; 90 | 03EE3C130F3622A200DF5A2D /* HTTPServer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HTTPServer.m; path = CocoaHTTPServer/HTTPServer.m; sourceTree = ""; }; 91 | 03EE3C330F36238800DF5A2D /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; 92 | 03EE3C790F36253100DF5A2D /* FSWHTTPConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSWHTTPConnection.h; sourceTree = ""; }; 93 | 03EE3C7A0F36253100DF5A2D /* FSWHTTPConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSWHTTPConnection.m; sourceTree = ""; }; 94 | 03EE3D520F3639AB00DF5A2D /* text.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = text.gif; path = WebServerIcons/text.gif; sourceTree = ""; }; 95 | 03EE3D530F3639AB00DF5A2D /* folder.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = folder.gif; path = WebServerIcons/folder.gif; sourceTree = ""; }; 96 | 03EE3D540F3639AB00DF5A2D /* generic.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = generic.gif; path = WebServerIcons/generic.gif; sourceTree = ""; }; 97 | 03EE3D550F3639AB00DF5A2D /* image2.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = image2.gif; path = WebServerIcons/image2.gif; sourceTree = ""; }; 98 | 03EE3D560F3639AB00DF5A2D /* pdf.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = pdf.gif; path = WebServerIcons/pdf.gif; sourceTree = ""; }; 99 | 03EE3D570F3639AB00DF5A2D /* back.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = back.gif; path = WebServerIcons/back.gif; sourceTree = ""; }; 100 | 03EE3FBD0F3661C000DF5A2D /* blank.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; name = blank.gif; path = WebServerIcons/blank.gif; sourceTree = ""; }; 101 | 03EE400C0F3672EA00DF5A2D /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 102 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 103 | 1D3623240D0F684500981E51 /* FSWalkerAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSWalkerAppDelegate.h; sourceTree = ""; }; 104 | 1D3623250D0F684500981E51 /* FSWalkerAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSWalkerAppDelegate.m; sourceTree = ""; }; 105 | 1D6058910D05DD3D006BFB54 /* FSWalker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FSWalker.app; sourceTree = BUILT_PRODUCTS_DIR; }; 106 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 107 | 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 108 | 2899E55F0DE3E45000AC0155 /* RootViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RootViewController.xib; sourceTree = ""; }; 109 | 28A0AAE50D9B0CCF005BE974 /* FSWalker_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSWalker_Prefix.pch; sourceTree = ""; }; 110 | 28AD735F0D9D9599002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 111 | 28C286DF0D94DF7D0034E888 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = ""; }; 112 | 28C286E00D94DF7D0034E888 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = ""; }; 113 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 114 | 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 115 | /* End PBXFileReference section */ 116 | 117 | /* Begin PBXFrameworksBuildPhase section */ 118 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 119 | isa = PBXFrameworksBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 123 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 124 | 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, 125 | 03EE39D80F360C6600DF5A2D /* AudioToolbox.framework in Frameworks */, 126 | 03EE3C340F36238800DF5A2D /* CFNetwork.framework in Frameworks */, 127 | ); 128 | runOnlyForDeploymentPostprocessing = 0; 129 | }; 130 | /* End PBXFrameworksBuildPhase section */ 131 | 132 | /* Begin PBXGroup section */ 133 | 03EE3BC90F3621DE00DF5A2D /* CocoaHTTPServer */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 03EE3C040F3622A200DF5A2D /* AsyncSocket.h */, 137 | 03EE3C050F3622A200DF5A2D /* AsyncSocket.m */, 138 | 03EE3C060F3622A200DF5A2D /* DDData.h */, 139 | 03EE3C070F3622A200DF5A2D /* DDData.m */, 140 | 03EE3C080F3622A200DF5A2D /* DDNumber.h */, 141 | 03EE3C090F3622A200DF5A2D /* DDNumber.m */, 142 | 03EE3C0A0F3622A200DF5A2D /* DDRange.h */, 143 | 03EE3C0B0F3622A200DF5A2D /* DDRange.m */, 144 | 03EE3C0C0F3622A200DF5A2D /* HTTPAuthenticationRequest.h */, 145 | 03EE3C0D0F3622A200DF5A2D /* HTTPAuthenticationRequest.m */, 146 | 03EE3C0E0F3622A200DF5A2D /* HTTPConnection.h */, 147 | 03EE3C0F0F3622A200DF5A2D /* HTTPConnection.m */, 148 | 03EE3C100F3622A200DF5A2D /* HTTPResponse.h */, 149 | 03EE3C110F3622A200DF5A2D /* HTTPResponse.m */, 150 | 03EE3C120F3622A200DF5A2D /* HTTPServer.h */, 151 | 03EE3C130F3622A200DF5A2D /* HTTPServer.m */, 152 | ); 153 | name = CocoaHTTPServer; 154 | sourceTree = ""; 155 | }; 156 | 03EE3D500F3639A000DF5A2D /* WebServerIcons */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 03EE3FBD0F3661C000DF5A2D /* blank.gif */, 160 | 03EE3D520F3639AB00DF5A2D /* text.gif */, 161 | 03EE3D530F3639AB00DF5A2D /* folder.gif */, 162 | 03EE3D540F3639AB00DF5A2D /* generic.gif */, 163 | 03EE3D550F3639AB00DF5A2D /* image2.gif */, 164 | 03EE3D560F3639AB00DF5A2D /* pdf.gif */, 165 | 03EE3D570F3639AB00DF5A2D /* back.gif */, 166 | ); 167 | name = WebServerIcons; 168 | sourceTree = ""; 169 | }; 170 | 080E96DDFE201D6D7F000001 /* Classes */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 031AA86F0E57D185009DD8A4 /* FSItem.h */, 174 | 031AA8700E57D185009DD8A4 /* FSItem.m */, 175 | 039205650E586B8000F128FF /* FSItemCell.h */, 176 | 039205660E586B8000F128FF /* FSItemCell.m */, 177 | 28C286DF0D94DF7D0034E888 /* RootViewController.h */, 178 | 28C286E00D94DF7D0034E888 /* RootViewController.m */, 179 | 1D3623240D0F684500981E51 /* FSWalkerAppDelegate.h */, 180 | 1D3623250D0F684500981E51 /* FSWalkerAppDelegate.m */, 181 | 03E75D1E0E58B0110044A3C8 /* InfoPanelController.h */, 182 | 03E75D1F0E58B0110044A3C8 /* InfoPanelController.m */, 183 | 03EE37B60F35E8C600DF5A2D /* DetailViewController.h */, 184 | 03EE37B70F35E8C600DF5A2D /* DetailViewController.m */, 185 | 03EE3A0D0F360F1E00DF5A2D /* NSNumber+Bytes.h */, 186 | 03EE3A0E0F360F1E00DF5A2D /* NSNumber+Bytes.m */, 187 | ); 188 | path = Classes; 189 | sourceTree = ""; 190 | }; 191 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 1D6058910D05DD3D006BFB54 /* FSWalker.app */, 195 | ); 196 | name = Products; 197 | sourceTree = ""; 198 | }; 199 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | 03EE3BF90F36220900DF5A2D /* MyIP.h */, 203 | 03EE3BFA0F36220900DF5A2D /* MyIP.m */, 204 | 03EE3BC90F3621DE00DF5A2D /* CocoaHTTPServer */, 205 | 03EE3C790F36253100DF5A2D /* FSWHTTPConnection.h */, 206 | 03EE3C7A0F36253100DF5A2D /* FSWHTTPConnection.m */, 207 | 080E96DDFE201D6D7F000001 /* Classes */, 208 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 209 | 29B97317FDCFA39411CA2CEA /* Resources */, 210 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 211 | 19C28FACFE9D520D11CA2CBB /* Products */, 212 | ); 213 | name = CustomTemplate; 214 | sourceTree = ""; 215 | }; 216 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 217 | isa = PBXGroup; 218 | children = ( 219 | 28A0AAE50D9B0CCF005BE974 /* FSWalker_Prefix.pch */, 220 | 29B97316FDCFA39411CA2CEA /* main.m */, 221 | ); 222 | name = "Other Sources"; 223 | sourceTree = ""; 224 | }; 225 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 03EE3D500F3639A000DF5A2D /* WebServerIcons */, 229 | 03E442990F38DA10007601D2 /* Icon.png */, 230 | 03987A980E58EC600013D995 /* Default.png */, 231 | 039205100E5869A600F128FF /* GenericDocumentIcon.png */, 232 | 039205110E5869A600F128FF /* GenericFolderIcon.png */, 233 | 031E5E340F2E81BE002EB490 /* SymLinkIcon.png */, 234 | 2899E55F0DE3E45000AC0155 /* RootViewController.xib */, 235 | 28AD735F0D9D9599002E5188 /* MainWindow.xib */, 236 | 8D1107310486CEB800E47090 /* Info.plist */, 237 | 039205680E586BBD00F128FF /* FSItemCell.xib */, 238 | 03E75D1A0E58ADC30044A3C8 /* InfoPanelController.xib */, 239 | 03EE37B30F35E89700DF5A2D /* DetailViewController.xib */, 240 | 03EE400C0F3672EA00DF5A2D /* Settings.bundle */, 241 | ); 242 | name = Resources; 243 | sourceTree = ""; 244 | }; 245 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 246 | isa = PBXGroup; 247 | children = ( 248 | 03EE3C330F36238800DF5A2D /* CFNetwork.framework */, 249 | 03EE39D70F360C6600DF5A2D /* AudioToolbox.framework */, 250 | 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, 251 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 252 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 253 | ); 254 | name = Frameworks; 255 | sourceTree = ""; 256 | }; 257 | /* End PBXGroup section */ 258 | 259 | /* Begin PBXNativeTarget section */ 260 | 1D6058900D05DD3D006BFB54 /* FSWalker */ = { 261 | isa = PBXNativeTarget; 262 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "FSWalker" */; 263 | buildPhases = ( 264 | 1D60588D0D05DD3D006BFB54 /* Resources */, 265 | 1D60588E0D05DD3D006BFB54 /* Sources */, 266 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 267 | ); 268 | buildRules = ( 269 | ); 270 | dependencies = ( 271 | ); 272 | name = FSWalker; 273 | productName = FSWalker; 274 | productReference = 1D6058910D05DD3D006BFB54 /* FSWalker.app */; 275 | productType = "com.apple.product-type.application"; 276 | }; 277 | /* End PBXNativeTarget section */ 278 | 279 | /* Begin PBXProject section */ 280 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 281 | isa = PBXProject; 282 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "FSWalker" */; 283 | compatibilityVersion = "Xcode 3.1"; 284 | developmentRegion = English; 285 | hasScannedForEncodings = 1; 286 | knownRegions = ( 287 | English, 288 | Japanese, 289 | French, 290 | German, 291 | en, 292 | ); 293 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 294 | projectDirPath = ""; 295 | projectRoot = ""; 296 | targets = ( 297 | 1D6058900D05DD3D006BFB54 /* FSWalker */, 298 | ); 299 | }; 300 | /* End PBXProject section */ 301 | 302 | /* Begin PBXResourcesBuildPhase section */ 303 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 304 | isa = PBXResourcesBuildPhase; 305 | buildActionMask = 2147483647; 306 | files = ( 307 | 28AD73600D9D9599002E5188 /* MainWindow.xib in Resources */, 308 | 2899E5600DE3E45000AC0155 /* RootViewController.xib in Resources */, 309 | 039205120E5869A600F128FF /* GenericDocumentIcon.png in Resources */, 310 | 039205130E5869A600F128FF /* GenericFolderIcon.png in Resources */, 311 | 039205690E586BBD00F128FF /* FSItemCell.xib in Resources */, 312 | 03E75D1B0E58ADC30044A3C8 /* InfoPanelController.xib in Resources */, 313 | 03987A990E58EC600013D995 /* Default.png in Resources */, 314 | 031E5E350F2E81BE002EB490 /* SymLinkIcon.png in Resources */, 315 | 03EE37B40F35E89700DF5A2D /* DetailViewController.xib in Resources */, 316 | 03EE3D580F3639AB00DF5A2D /* text.gif in Resources */, 317 | 03EE3D590F3639AB00DF5A2D /* folder.gif in Resources */, 318 | 03EE3D5A0F3639AB00DF5A2D /* generic.gif in Resources */, 319 | 03EE3D5B0F3639AB00DF5A2D /* image2.gif in Resources */, 320 | 03EE3D5C0F3639AB00DF5A2D /* pdf.gif in Resources */, 321 | 03EE3D5D0F3639AB00DF5A2D /* back.gif in Resources */, 322 | 03EE3FBE0F3661C000DF5A2D /* blank.gif in Resources */, 323 | 03EE400D0F3672EA00DF5A2D /* Settings.bundle in Resources */, 324 | 03E4429A0F38DA10007601D2 /* Icon.png in Resources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | /* End PBXResourcesBuildPhase section */ 329 | 330 | /* Begin PBXSourcesBuildPhase section */ 331 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 332 | isa = PBXSourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 336 | 1D3623260D0F684500981E51 /* FSWalkerAppDelegate.m in Sources */, 337 | 28C286E10D94DF7D0034E888 /* RootViewController.m in Sources */, 338 | 031AA8710E57D185009DD8A4 /* FSItem.m in Sources */, 339 | 039205670E586B8000F128FF /* FSItemCell.m in Sources */, 340 | 03E75D200E58B0110044A3C8 /* InfoPanelController.m in Sources */, 341 | 03EE37B80F35E8C600DF5A2D /* DetailViewController.m in Sources */, 342 | 03EE3A0F0F360F1E00DF5A2D /* NSNumber+Bytes.m in Sources */, 343 | 03EE3BFB0F36220900DF5A2D /* MyIP.m in Sources */, 344 | 03EE3C160F3622A200DF5A2D /* AsyncSocket.m in Sources */, 345 | 03EE3C170F3622A200DF5A2D /* DDData.m in Sources */, 346 | 03EE3C180F3622A200DF5A2D /* DDNumber.m in Sources */, 347 | 03EE3C190F3622A200DF5A2D /* DDRange.m in Sources */, 348 | 03EE3C1A0F3622A200DF5A2D /* HTTPAuthenticationRequest.m in Sources */, 349 | 03EE3C1B0F3622A200DF5A2D /* HTTPConnection.m in Sources */, 350 | 03EE3C1C0F3622A200DF5A2D /* HTTPResponse.m in Sources */, 351 | 03EE3C1D0F3622A200DF5A2D /* HTTPServer.m in Sources */, 352 | 03EE3C7B0F36253100DF5A2D /* FSWHTTPConnection.m in Sources */, 353 | ); 354 | runOnlyForDeploymentPostprocessing = 0; 355 | }; 356 | /* End PBXSourcesBuildPhase section */ 357 | 358 | /* Begin XCBuildConfiguration section */ 359 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 360 | isa = XCBuildConfiguration; 361 | buildSettings = { 362 | ALWAYS_SEARCH_USER_PATHS = NO; 363 | CODE_SIGN_IDENTITY = "iPhone Developer"; 364 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 365 | COPY_PHASE_STRIP = NO; 366 | GCC_DYNAMIC_NO_PIC = NO; 367 | GCC_OPTIMIZATION_LEVEL = 0; 368 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 369 | GCC_PREFIX_HEADER = FSWalker_Prefix.pch; 370 | GCC_VERSION = ""; 371 | INFOPLIST_FILE = Info.plist; 372 | PRODUCT_NAME = FSWalker; 373 | PROVISIONING_PROFILE = ""; 374 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; 375 | }; 376 | name = Debug; 377 | }; 378 | 1D6058950D05DD3E006BFB54 /* Release */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | ALWAYS_SEARCH_USER_PATHS = NO; 382 | CODE_SIGN_IDENTITY = "iPhone Developer"; 383 | COPY_PHASE_STRIP = YES; 384 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 385 | GCC_PREFIX_HEADER = FSWalker_Prefix.pch; 386 | INFOPLIST_FILE = Info.plist; 387 | PRODUCT_NAME = FSWalker; 388 | PROVISIONING_PROFILE = ""; 389 | }; 390 | name = Release; 391 | }; 392 | C01FCF4F08A954540054247B /* Debug */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 396 | CODE_SIGN_IDENTITY = "iPhone Developer"; 397 | GCC_C_LANGUAGE_STANDARD = c99; 398 | GCC_VERSION = 4.2; 399 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 400 | GCC_WARN_UNUSED_VARIABLE = YES; 401 | ONLY_ACTIVE_ARCH = YES; 402 | PREBINDING = NO; 403 | PROVISIONING_PROFILE = ""; 404 | SDKROOT = iphoneos; 405 | }; 406 | name = Debug; 407 | }; 408 | C01FCF5008A954540054247B /* Release */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 412 | CODE_SIGN_IDENTITY = "iPhone Developer"; 413 | GCC_C_LANGUAGE_STANDARD = c99; 414 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 415 | GCC_WARN_UNUSED_VARIABLE = YES; 416 | PREBINDING = NO; 417 | PROVISIONING_PROFILE = ""; 418 | SDKROOT = iphoneos; 419 | }; 420 | name = Release; 421 | }; 422 | /* End XCBuildConfiguration section */ 423 | 424 | /* Begin XCConfigurationList section */ 425 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "FSWalker" */ = { 426 | isa = XCConfigurationList; 427 | buildConfigurations = ( 428 | 1D6058940D05DD3E006BFB54 /* Debug */, 429 | 1D6058950D05DD3E006BFB54 /* Release */, 430 | ); 431 | defaultConfigurationIsVisible = 0; 432 | defaultConfigurationName = Release; 433 | }; 434 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "FSWalker" */ = { 435 | isa = XCConfigurationList; 436 | buildConfigurations = ( 437 | C01FCF4F08A954540054247B /* Debug */, 438 | C01FCF5008A954540054247B /* Release */, 439 | ); 440 | defaultConfigurationIsVisible = 0; 441 | defaultConfigurationName = Release; 442 | }; 443 | /* End XCConfigurationList section */ 444 | }; 445 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 446 | } 447 | -------------------------------------------------------------------------------- /FSWalker_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'FSWalker' target in the 'FSWalker' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /GenericDocumentIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/GenericDocumentIcon.png -------------------------------------------------------------------------------- /GenericFolderIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/GenericFolderIcon.png -------------------------------------------------------------------------------- /GenericFolderIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/GenericFolderIcon@2x.png -------------------------------------------------------------------------------- /Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/Icon.png -------------------------------------------------------------------------------- /Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/Icon@2x.png -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | Icon.png 13 | CFBundleIdentifier 14 | ch.seriot.FSWalker 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | NSMainNibFile 28 | MainWindow 29 | UIPrerenderedIcon 30 | YES 31 | 32 | 33 | -------------------------------------------------------------------------------- /MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 512 5 | 10J567 6 | 823 7 | 1038.35 8 | 462.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 132 12 | 13 | 14 | YES 15 | 16 | 17 | YES 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | YES 22 | 23 | YES 24 | 25 | 26 | YES 27 | 28 | 29 | 30 | YES 31 | 32 | IBFilesOwner 33 | IBCocoaTouchFramework 34 | 35 | 36 | IBFirstResponder 37 | IBCocoaTouchFramework 38 | 39 | 40 | IBCocoaTouchFramework 41 | 42 | 43 | 44 | 1316 45 | 46 | {320, 480} 47 | 48 | 1 49 | MSAxIDEAA 50 | 51 | NO 52 | NO 53 | 54 | IBCocoaTouchFramework 55 | 56 | 57 | 58 | 59 | 1 60 | 61 | IBCocoaTouchFramework 62 | NO 63 | 64 | 65 | 256 66 | {0, 0} 67 | NO 68 | YES 69 | YES 70 | IBCocoaTouchFramework 71 | 72 | 73 | YES 74 | 75 | 76 | Title 77 | IBCocoaTouchFramework 78 | 79 | 80 | RootViewController 81 | 82 | 83 | 1 84 | 85 | IBCocoaTouchFramework 86 | NO 87 | 88 | 89 | 90 | 91 | 92 | 93 | YES 94 | 95 | 96 | delegate 97 | 98 | 99 | 100 | 4 101 | 102 | 103 | 104 | window 105 | 106 | 107 | 108 | 5 109 | 110 | 111 | 112 | rootViewController 113 | 114 | 115 | 116 | 16 117 | 118 | 119 | 120 | navigationController 121 | 122 | 123 | 124 | 26 125 | 126 | 127 | 128 | 129 | YES 130 | 131 | 0 132 | 133 | 134 | 135 | 136 | 137 | 2 138 | 139 | 140 | YES 141 | 142 | 143 | 144 | 145 | -1 146 | 147 | 148 | File's Owner 149 | 150 | 151 | 3 152 | 153 | 154 | 155 | 156 | -2 157 | 158 | 159 | 160 | 161 | 9 162 | 163 | 164 | YES 165 | 166 | 167 | 168 | 169 | 170 | 171 | 11 172 | 173 | 174 | 175 | 176 | 13 177 | 178 | 179 | YES 180 | 181 | 182 | 183 | 184 | 185 | 17 186 | 187 | 188 | YES 189 | 190 | 191 | 192 | 193 | 194 | 195 | YES 196 | 197 | YES 198 | -1.CustomClassName 199 | -2.CustomClassName 200 | 11.IBPluginDependency 201 | 13.CustomClassName 202 | 13.IBPluginDependency 203 | 17.IBPluginDependency 204 | 2.IBAttributePlaceholdersKey 205 | 2.IBEditorWindowLastContentRect 206 | 2.IBPluginDependency 207 | 3.CustomClassName 208 | 3.IBPluginDependency 209 | 9.IBEditorWindowLastContentRect 210 | 9.IBPluginDependency 211 | 212 | 213 | YES 214 | UIApplication 215 | UIResponder 216 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 217 | RootViewController 218 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 219 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 220 | 221 | YES 222 | 223 | 224 | YES 225 | 226 | 227 | {{490, 376}, {320, 480}} 228 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 229 | FSWalkerAppDelegate 230 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 231 | {{492, 343}, {320, 480}} 232 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 233 | 234 | 235 | 236 | YES 237 | 238 | 239 | YES 240 | 241 | 242 | 243 | 244 | YES 245 | 246 | 247 | YES 248 | 249 | 250 | 251 | 36 252 | 253 | 254 | 255 | YES 256 | 257 | FSWalkerAppDelegate 258 | NSObject 259 | 260 | YES 261 | 262 | YES 263 | navigationController 264 | rootViewController 265 | window 266 | 267 | 268 | YES 269 | UINavigationController 270 | RootViewController 271 | UIWindow 272 | 273 | 274 | 275 | YES 276 | 277 | YES 278 | navigationController 279 | rootViewController 280 | window 281 | 282 | 283 | YES 284 | 285 | navigationController 286 | UINavigationController 287 | 288 | 289 | rootViewController 290 | RootViewController 291 | 292 | 293 | window 294 | UIWindow 295 | 296 | 297 | 298 | 299 | IBProjectSource 300 | Classes/FSWalkerAppDelegate.h 301 | 302 | 303 | 304 | NSObject 305 | 306 | IBProjectSource 307 | CocoaHTTPServer/AsyncSocket.h 308 | 309 | 310 | 311 | RootViewController 312 | UITableViewController 313 | 314 | IBProjectSource 315 | Classes/RootViewController.h 316 | 317 | 318 | 319 | 320 | YES 321 | 322 | NSObject 323 | 324 | IBFrameworkSource 325 | Foundation.framework/Headers/NSError.h 326 | 327 | 328 | 329 | NSObject 330 | 331 | IBFrameworkSource 332 | Foundation.framework/Headers/NSFileManager.h 333 | 334 | 335 | 336 | NSObject 337 | 338 | IBFrameworkSource 339 | Foundation.framework/Headers/NSKeyValueCoding.h 340 | 341 | 342 | 343 | NSObject 344 | 345 | IBFrameworkSource 346 | Foundation.framework/Headers/NSKeyValueObserving.h 347 | 348 | 349 | 350 | NSObject 351 | 352 | IBFrameworkSource 353 | Foundation.framework/Headers/NSKeyedArchiver.h 354 | 355 | 356 | 357 | NSObject 358 | 359 | IBFrameworkSource 360 | Foundation.framework/Headers/NSObject.h 361 | 362 | 363 | 364 | NSObject 365 | 366 | IBFrameworkSource 367 | Foundation.framework/Headers/NSRunLoop.h 368 | 369 | 370 | 371 | NSObject 372 | 373 | IBFrameworkSource 374 | Foundation.framework/Headers/NSThread.h 375 | 376 | 377 | 378 | NSObject 379 | 380 | IBFrameworkSource 381 | Foundation.framework/Headers/NSURL.h 382 | 383 | 384 | 385 | NSObject 386 | 387 | IBFrameworkSource 388 | Foundation.framework/Headers/NSURLConnection.h 389 | 390 | 391 | 392 | NSObject 393 | 394 | IBFrameworkSource 395 | UIKit.framework/Headers/UIAccessibility.h 396 | 397 | 398 | 399 | NSObject 400 | 401 | IBFrameworkSource 402 | UIKit.framework/Headers/UINibLoading.h 403 | 404 | 405 | 406 | NSObject 407 | 408 | IBFrameworkSource 409 | UIKit.framework/Headers/UIResponder.h 410 | 411 | 412 | 413 | UIApplication 414 | UIResponder 415 | 416 | IBFrameworkSource 417 | UIKit.framework/Headers/UIApplication.h 418 | 419 | 420 | 421 | UIBarButtonItem 422 | UIBarItem 423 | 424 | IBFrameworkSource 425 | UIKit.framework/Headers/UIBarButtonItem.h 426 | 427 | 428 | 429 | UIBarItem 430 | NSObject 431 | 432 | IBFrameworkSource 433 | UIKit.framework/Headers/UIBarItem.h 434 | 435 | 436 | 437 | UINavigationBar 438 | UIView 439 | 440 | IBFrameworkSource 441 | UIKit.framework/Headers/UINavigationBar.h 442 | 443 | 444 | 445 | UINavigationController 446 | UIViewController 447 | 448 | IBFrameworkSource 449 | UIKit.framework/Headers/UINavigationController.h 450 | 451 | 452 | 453 | UINavigationItem 454 | NSObject 455 | 456 | 457 | 458 | UIResponder 459 | NSObject 460 | 461 | 462 | 463 | UISearchBar 464 | UIView 465 | 466 | IBFrameworkSource 467 | UIKit.framework/Headers/UISearchBar.h 468 | 469 | 470 | 471 | UISearchDisplayController 472 | NSObject 473 | 474 | IBFrameworkSource 475 | UIKit.framework/Headers/UISearchDisplayController.h 476 | 477 | 478 | 479 | UITableViewController 480 | UIViewController 481 | 482 | IBFrameworkSource 483 | UIKit.framework/Headers/UITableViewController.h 484 | 485 | 486 | 487 | UIView 488 | 489 | IBFrameworkSource 490 | UIKit.framework/Headers/UIPrintFormatter.h 491 | 492 | 493 | 494 | UIView 495 | 496 | IBFrameworkSource 497 | UIKit.framework/Headers/UITextField.h 498 | 499 | 500 | 501 | UIView 502 | UIResponder 503 | 504 | IBFrameworkSource 505 | UIKit.framework/Headers/UIView.h 506 | 507 | 508 | 509 | UIViewController 510 | 511 | 512 | 513 | UIViewController 514 | 515 | IBFrameworkSource 516 | UIKit.framework/Headers/UIPopoverController.h 517 | 518 | 519 | 520 | UIViewController 521 | 522 | IBFrameworkSource 523 | UIKit.framework/Headers/UISplitViewController.h 524 | 525 | 526 | 527 | UIViewController 528 | 529 | IBFrameworkSource 530 | UIKit.framework/Headers/UITabBarController.h 531 | 532 | 533 | 534 | UIViewController 535 | UIResponder 536 | 537 | IBFrameworkSource 538 | UIKit.framework/Headers/UIViewController.h 539 | 540 | 541 | 542 | UIWindow 543 | UIView 544 | 545 | IBFrameworkSource 546 | UIKit.framework/Headers/UIWindow.h 547 | 548 | 549 | 550 | 551 | 0 552 | IBCocoaTouchFramework 553 | 554 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 555 | 556 | 557 | 558 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 559 | 560 | 561 | 562 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 563 | 564 | 565 | YES 566 | FSWalker.xcodeproj 567 | 3 568 | 132 569 | 570 | 571 | -------------------------------------------------------------------------------- /MyIP.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyIP.h 3 | // ip 4 | // 5 | // Created by Nicolas Seriot on 12.11.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface MyIP : NSObject { 13 | 14 | } 15 | 16 | + (MyIP *)sharedInstance; 17 | - (NSDictionary *)ipsForInterfaces; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /MyIP.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyIP.m 3 | // ip 4 | // 5 | // Created by Nicolas Seriot on 12.11.08. 6 | // Copyright 2008 Sen:te. All rights reserved. 7 | // 8 | 9 | #import "MyIP.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | static MyIP *sharedInstance = nil; 17 | 18 | @implementation MyIP 19 | 20 | + (MyIP *)sharedInstance { 21 | if (sharedInstance == nil) { 22 | sharedInstance = [[MyIP alloc] init]; 23 | } 24 | return sharedInstance; 25 | } 26 | 27 | - (NSDictionary *)ipsForInterfaces { 28 | 29 | struct ifaddrs *list; 30 | if(getifaddrs(&list) < 0) { 31 | perror("getifaddrs"); 32 | return nil; 33 | } 34 | 35 | NSMutableDictionary *d = [NSMutableDictionary dictionary]; 36 | struct ifaddrs *cur; 37 | for(cur = list; cur != NULL; cur = cur->ifa_next) { 38 | if(cur->ifa_addr->sa_family != AF_INET) 39 | continue; 40 | 41 | struct sockaddr_in *addrStruct = (struct sockaddr_in *)cur->ifa_addr; 42 | NSString *name = [NSString stringWithUTF8String:cur->ifa_name]; 43 | NSString *addr = [NSString stringWithUTF8String:inet_ntoa(addrStruct->sin_addr)]; 44 | [d setValue:addr forKey:name]; 45 | } 46 | 47 | freeifaddrs(list); 48 | return d; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | FSWalker 2 | ======== 3 | 4 | _A File System Browser for iOS_ 5 | 6 | FSWalker lets you browse the iPhone file system, directly on the device or remotely through an embedded web server. 7 | 8 | No private API were used. The iPhone does not need to be jailbroken. 9 | 10 | An Apple iPhone developer certificate is required to run the application on an actual device. 11 | 12 | TODO: 13 | 14 | - files deletion 15 | - uncripple png files before sending them to http clients 16 | - improve sound and video support 17 | - make files downloadable with $ wget -r 18 | 19 | ![FSWalker](screenshots/screenshot_1.png "FSWalker") ![FSWalker](screenshots/screenshot_2.png "FSWalker") ![FSWalker](screenshots/screenshot_3.png "FSWalker") ![FSWalker](screenshots/web_page.png "FSWalker") 20 | -------------------------------------------------------------------------------- /RootViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 768 5 | 10F569 6 | 804 7 | 1038.29 8 | 461.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 123 12 | 13 | 14 | YES 15 | 16 | 17 | YES 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | YES 22 | 23 | YES 24 | 25 | 26 | YES 27 | 28 | 29 | 30 | YES 31 | 32 | IBFilesOwner 33 | IBCocoaTouchFramework 34 | 35 | 36 | IBFirstResponder 37 | IBCocoaTouchFramework 38 | 39 | 40 | 41 | 292 42 | {320, 460} 43 | 44 | 45 | 46 | 3 47 | MQA 48 | 49 | NO 50 | YES 51 | NO 52 | IBCocoaTouchFramework 53 | 1 54 | 0 55 | YES 56 | 44 57 | 27 58 | 27 59 | 60 | 61 | 62 | 63 | YES 64 | 65 | 66 | view 67 | 68 | 69 | 70 | 5 71 | 72 | 73 | 74 | dataSource 75 | 76 | 77 | 78 | 6 79 | 80 | 81 | 82 | delegate 83 | 84 | 85 | 86 | 7 87 | 88 | 89 | 90 | tableView 91 | 92 | 93 | 94 | 8 95 | 96 | 97 | 98 | 99 | YES 100 | 101 | 0 102 | 103 | 104 | 105 | 106 | 107 | -1 108 | 109 | 110 | File's Owner 111 | 112 | 113 | -2 114 | 115 | 116 | 117 | 118 | 3 119 | 120 | 121 | 122 | 123 | 124 | 125 | YES 126 | 127 | YES 128 | -1.CustomClassName 129 | -2.CustomClassName 130 | 3.IBEditorWindowLastContentRect 131 | 3.IBPluginDependency 132 | 133 | 134 | YES 135 | RootViewController 136 | UIResponder 137 | {{421, 361}, {320, 460}} 138 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 139 | 140 | 141 | 142 | YES 143 | 144 | 145 | YES 146 | 147 | 148 | 149 | 150 | YES 151 | 152 | 153 | YES 154 | 155 | 156 | 157 | 9 158 | 159 | 160 | 161 | YES 162 | 163 | NSObject 164 | 165 | IBProjectSource 166 | CocoaHTTPServer/AsyncSocket.h 167 | 168 | 169 | 170 | RootViewController 171 | UITableViewController 172 | 173 | IBProjectSource 174 | Classes/RootViewController.h 175 | 176 | 177 | 178 | RootViewController 179 | UITableViewController 180 | 181 | tableView 182 | UITableView 183 | 184 | 185 | tableView 186 | 187 | tableView 188 | UITableView 189 | 190 | 191 | 192 | IBUserSource 193 | 194 | 195 | 196 | 197 | 198 | YES 199 | 200 | NSObject 201 | 202 | IBFrameworkSource 203 | Foundation.framework/Headers/NSError.h 204 | 205 | 206 | 207 | NSObject 208 | 209 | IBFrameworkSource 210 | Foundation.framework/Headers/NSFileManager.h 211 | 212 | 213 | 214 | NSObject 215 | 216 | IBFrameworkSource 217 | Foundation.framework/Headers/NSKeyValueCoding.h 218 | 219 | 220 | 221 | NSObject 222 | 223 | IBFrameworkSource 224 | Foundation.framework/Headers/NSKeyValueObserving.h 225 | 226 | 227 | 228 | NSObject 229 | 230 | IBFrameworkSource 231 | Foundation.framework/Headers/NSKeyedArchiver.h 232 | 233 | 234 | 235 | NSObject 236 | 237 | IBFrameworkSource 238 | Foundation.framework/Headers/NSObject.h 239 | 240 | 241 | 242 | NSObject 243 | 244 | IBFrameworkSource 245 | Foundation.framework/Headers/NSRunLoop.h 246 | 247 | 248 | 249 | NSObject 250 | 251 | IBFrameworkSource 252 | Foundation.framework/Headers/NSThread.h 253 | 254 | 255 | 256 | NSObject 257 | 258 | IBFrameworkSource 259 | Foundation.framework/Headers/NSURL.h 260 | 261 | 262 | 263 | NSObject 264 | 265 | IBFrameworkSource 266 | Foundation.framework/Headers/NSURLConnection.h 267 | 268 | 269 | 270 | NSObject 271 | 272 | IBFrameworkSource 273 | UIKit.framework/Headers/UIAccessibility.h 274 | 275 | 276 | 277 | NSObject 278 | 279 | IBFrameworkSource 280 | UIKit.framework/Headers/UINibLoading.h 281 | 282 | 283 | 284 | NSObject 285 | 286 | IBFrameworkSource 287 | UIKit.framework/Headers/UIResponder.h 288 | 289 | 290 | 291 | UIResponder 292 | NSObject 293 | 294 | 295 | 296 | UIScrollView 297 | UIView 298 | 299 | IBFrameworkSource 300 | UIKit.framework/Headers/UIScrollView.h 301 | 302 | 303 | 304 | UISearchBar 305 | UIView 306 | 307 | IBFrameworkSource 308 | UIKit.framework/Headers/UISearchBar.h 309 | 310 | 311 | 312 | UISearchDisplayController 313 | NSObject 314 | 315 | IBFrameworkSource 316 | UIKit.framework/Headers/UISearchDisplayController.h 317 | 318 | 319 | 320 | UITableView 321 | UIScrollView 322 | 323 | IBFrameworkSource 324 | UIKit.framework/Headers/UITableView.h 325 | 326 | 327 | 328 | UITableViewController 329 | UIViewController 330 | 331 | IBFrameworkSource 332 | UIKit.framework/Headers/UITableViewController.h 333 | 334 | 335 | 336 | UIView 337 | 338 | IBFrameworkSource 339 | UIKit.framework/Headers/UITextField.h 340 | 341 | 342 | 343 | UIView 344 | UIResponder 345 | 346 | IBFrameworkSource 347 | UIKit.framework/Headers/UIView.h 348 | 349 | 350 | 351 | UIViewController 352 | 353 | IBFrameworkSource 354 | UIKit.framework/Headers/UINavigationController.h 355 | 356 | 357 | 358 | UIViewController 359 | 360 | IBFrameworkSource 361 | UIKit.framework/Headers/UIPopoverController.h 362 | 363 | 364 | 365 | UIViewController 366 | 367 | IBFrameworkSource 368 | UIKit.framework/Headers/UISplitViewController.h 369 | 370 | 371 | 372 | UIViewController 373 | 374 | IBFrameworkSource 375 | UIKit.framework/Headers/UITabBarController.h 376 | 377 | 378 | 379 | UIViewController 380 | UIResponder 381 | 382 | IBFrameworkSource 383 | UIKit.framework/Headers/UIViewController.h 384 | 385 | 386 | 387 | 388 | 0 389 | IBCocoaTouchFramework 390 | 391 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 392 | 393 | 394 | 395 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 396 | 397 | 398 | 399 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 400 | 401 | 402 | YES 403 | FSWalker.xcodeproj 404 | 3 405 | 123 406 | 407 | 408 | -------------------------------------------------------------------------------- /Settings.bundle/Root.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | FSWalker 7 | StringsTable 8 | Root 9 | PreferenceSpecifiers 10 | 11 | 12 | Type 13 | PSGroupSpecifier 14 | Title 15 | Web Server 16 | 17 | 18 | Type 19 | PSToggleSwitchSpecifier 20 | Title 21 | Enabled 22 | Key 23 | ShouldStartServer 24 | DefaultValue 25 | 26 | 27 | 28 | Type 29 | PSToggleSwitchSpecifier 30 | Title 31 | Show Alert 32 | Key 33 | ShowAlertWhenServerStarts 34 | DefaultValue 35 | 36 | 37 | 38 | Type 39 | PSGroupSpecifier 40 | Title 41 | Display 42 | 43 | 44 | Type 45 | PSToggleSwitchSpecifier 46 | Title 47 | Plists in XML 48 | Key 49 | XMLPlist 50 | DefaultValue 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Settings.bundle/en.lproj/Root.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/Settings.bundle/en.lproj/Root.strings -------------------------------------------------------------------------------- /SymLinkIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/SymLinkIcon.png -------------------------------------------------------------------------------- /WebServerIcons/back.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/back.gif -------------------------------------------------------------------------------- /WebServerIcons/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/blank.gif -------------------------------------------------------------------------------- /WebServerIcons/folder.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/folder.gif -------------------------------------------------------------------------------- /WebServerIcons/generic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/generic.gif -------------------------------------------------------------------------------- /WebServerIcons/image2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/image2.gif -------------------------------------------------------------------------------- /WebServerIcons/pdf.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/pdf.gif -------------------------------------------------------------------------------- /WebServerIcons/text.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/WebServerIcons/text.gif -------------------------------------------------------------------------------- /art/FolderGnuSteps.acorn: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/art/FolderGnuSteps.acorn -------------------------------------------------------------------------------- /art/GenericFolder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/art/GenericFolder.png -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // FSWalker 4 | // 5 | // Created by Nicolas Seriot on 17.08.08. 6 | // Copyright Sen:te 2008. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /screenshots/screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/screenshots/screenshot_1.png -------------------------------------------------------------------------------- /screenshots/screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/screenshots/screenshot_2.png -------------------------------------------------------------------------------- /screenshots/screenshot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/screenshots/screenshot_3.png -------------------------------------------------------------------------------- /screenshots/web_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nst/FSWalker/18b57062bbdffa55948cc4adf249c4cb66e032d7/screenshots/web_page.png --------------------------------------------------------------------------------