pax_global_header00006660000000000000000000000064117725312040014514gustar00rootroot0000000000000052 comment=7ef56dd462b5ade4f8680df8bb138afee790172f ftp.app-0.3/000077500000000000000000000000001177253120400127265ustar00rootroot00000000000000ftp.app-0.3/AppController.h000066400000000000000000000077101177253120400156700ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-03-30 Application Controller This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define connectionModeKey @"connectionMode" #import #import "ftpclient.h" #import "localclient.h" #import "fileTable.h" #include @interface AppController : NSObject { IBOutlet NSWindow *mainWin; IBOutlet NSTableView *localView; IBOutlet NSTableView *remoteView; IBOutlet NSPopUpButton *localPath; IBOutlet NSPopUpButton *remotePath; IBOutlet NSButton *buttDownload; IBOutlet NSButton *buttUpload; IBOutlet NSTextField *infoMessage; IBOutlet NSTextField *infoSpeed; IBOutlet NSTextField *infoSize; IBOutlet NSProgressIndicator *progBar; IBOutlet NSWindow *logWin; IBOutlet NSTextView *logTextField; IBOutlet NSPanel *connectPanel; IBOutlet NSTextField *connAddress; IBOutlet NSTextField *connPort; IBOutlet NSTextField *connUser; IBOutlet NSTextField *connPass; IBOutlet NSButton *connAnon; IBOutlet NSPanel *prefPanel; IBOutlet NSMatrix *portType; NSMutableDictionary *textAttributes; FileTable *localTableData; FileTable *remoteTableData; FtpClient *ftp; LocalClient *local; @private connectionModes connMode; @private struct timeval beginTimeVal; @private unsigned long long transferSize; @private BOOL threadRunning; } + (void)initialize; - (id)init; - (void)dealloc; - (void)awakeFromNib; - (void)applicationDidFinishLaunching:(NSNotification *)aNotif; - (BOOL)applicationShouldTerminate:(id)sender; - (void)applicationWillTerminate:(NSNotification *)aNotif; - (BOOL)application:(NSApplication *)application openFile:(NSString *)fileName; - (void)updatePath :(NSPopUpButton *)path :(NSArray *)pathArray; - (IBAction)changePathFromMenu:(id)sender; - (void)listDoubleClick:(id)sender; - (IBAction)downloadButton:(id)sender; - (IBAction)uploadButton:(id)sender; - (IBAction)localDelete:(id)sender; - (IBAction)remoteDelete:(id)sender; - (void)setThreadRunningState:(BOOL)flag; - (void)setTransferBegin:(NSString *)name :(unsigned long long)size; - (void)setTransferProgress:(NSNumber *)bytesTransferred; - (void)setTransferEnd:(NSNumber *)bytesTransferred; /** closes the open connections and quits teh session with the remote server */ - (IBAction)disconnect:(id)sender; - (IBAction)showPrefPanel:(id)sender; - (IBAction)prefSave:(id)sender; - (IBAction)prefCancel:(id)sender; - (IBAction)showFtpLog:(id)sender; /** Called by the server object to register itself */ - (void)setServer:(id)anObject; - (void)appendTextToLog:(NSString *)textChunk; - (IBAction)showConnPanel:(id)sender; - (IBAction)connectConn:(id)sender; - (IBAction)cancelConn:(id)sender; - (IBAction)anonymousConn:(id)sender; - (void)showAlertDialog:(NSString*)message; /* accessor */ - (connectionModes)connectionMode; /* internal methods */ - (void)performRetrieveFile; - (void)performStoreFile; @end @interface fileTransmitParms : NSObject { @public FileElement *file; @public LocalClient *localClient; @public int depth; } @end ftp.app-0.3/AppController.m000066400000000000000000000454131177253120400156770ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-03-30 Application Controller This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import "AppController.h" #import "fileElement.h" @implementation fileTransmitParms @end @implementation AppController + (void)initialize { NSMutableDictionary *defaults = [NSMutableDictionary dictionary]; /* * Register your app's defaults here by adding objects to the * dictionary, eg * * [defaults setObject:anObject forKey:keyForThatObject]; * */ [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; [[NSUserDefaults standardUserDefaults] synchronize]; } - (id)init { NSFont *font; if ((self = [super init])) { connMode = defaultMode; threadRunning = NO; font = [NSFont userFixedPitchFontOfSize: 0]; textAttributes = [NSMutableDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; [textAttributes retain]; } return self; } - (void)dealloc { [textAttributes release]; [super dealloc]; } - (void)awakeFromNib { } - (void)applicationDidFinishLaunching:(NSNotification *)aNotif { NSArray *dirList; NSUserDefaults *defaults; NSString *readValue; NSPort *port1; NSPort *port2; NSArray *portArray; NSConnection *kitConnection; /* read the user preferences */ defaults = [NSUserDefaults standardUserDefaults]; readValue = [defaults stringForKey:connectionModeKey]; /* if no value was set for the key we set port as mode */ if ([readValue isEqualToString:@"default"]) connMode = defaultMode; else if ([readValue isEqualToString:@"port"] || readValue == nil) connMode = portMode; else if ([readValue isEqualToString:@"passive"]) connMode = passiveMode; else NSLog(@"Unrecognized value in user preferences for %@: %@", connectionModeKey, readValue); /* set double actions for tables */ [localView setTarget:self]; [localView setDoubleAction:@selector(listDoubleClick:)]; [remoteView setTarget:self]; [remoteView setDoubleAction:@selector(listDoubleClick:)]; /* startup code */ local = [[LocalClient alloc] init]; [local setWorkingDir:[local homeDir]]; dirList = [local dirContents]; [progBar setDoubleValue:0.0]; // reset the progress bar /* we create a data source and set the tableviews */ localTableData = [[FileTable alloc] init]; [localTableData initData:dirList]; [localView setDataSource:localTableData]; remoteTableData = [[FileTable alloc] init]; /* we update the path menu */ [self updatePath :localPath :[local workDirSplit]]; // #### and a release of this array ?!? // we set up distributed objects port1 = [NSPort port]; port2 = [NSPort port]; kitConnection = [[NSConnection alloc] initWithReceivePort:port1 sendPort:port2]; [kitConnection setRootObject:self]; /* Ports switched here. */ portArray = [NSArray arrayWithObjects:port2, port1, nil]; [NSThread detachNewThreadSelector: @selector(connectWithPorts:) toTarget: [FtpClient class] withObject: portArray]; return; } - (BOOL)applicationShouldTerminate:(id)sender { return YES; } - (void)applicationWillTerminate:(NSNotification *)aNotif { } - (BOOL)application:(NSApplication *)application openFile:(NSString *)fileName { return NO; } /* update the pop-up menu with a new path */ - (void)updatePath :(NSPopUpButton *)path :(NSArray *)pathArray { [path removeAllItems]; [path addItemsWithTitles:pathArray]; } /* performs the action of the path pull-down menu it navigates upwards the tree and works for both the local and remote path */ - (IBAction)changePathFromMenu:(id)sender { Client *theClient; NSTableView *theView; FileTable *theTable; NSString *thePath; NSArray *items; int selectedIndex; int i; NSArray *dirList; NSLog(@"%@", [sender class]); if (sender == localPath) { theClient = local; theView = localView; theTable = localTableData; } else { theClient = ftp; theView = remoteView; theTable = remoteTableData; } thePath = [NSString string]; selectedIndex = [sender indexOfItem:[sender selectedItem]]; items = [sender itemTitles]; for (i = [items count] - 1; i >= selectedIndex; i--) thePath = [thePath stringByAppendingPathComponent: [items objectAtIndex:i]]; NSLog(@"selected path: %@", thePath); [theClient changeWorkingDir:thePath]; if ((dirList = [theClient dirContents]) == nil) return; [theTable initData:dirList]; [theView reloadData]; [self updatePath :sender :[theClient workDirSplit]]; } /* perform the action of a double click in a table element a directory should be opened, a file down or uploaded The same method works for local and remote, detecting them */ - (IBAction)listDoubleClick:(id)sender { Client *theClient; NSTableView *theView; FileTable *theTable; int elementIndex; FileElement *fileEl; NSString *thePath; NSArray *dirList; NSPopUpButton *thePathMenu; if (threadRunning) { NSLog(@"thread was still running"); return; } theView = sender; NSLog(@"%@", [theView class]); if (theView == localView) { theClient = local; theTable = localTableData; thePathMenu = localPath; } else { theClient = ftp; theTable = remoteTableData; thePathMenu = remotePath; } elementIndex = [sender selectedRow]; if (elementIndex < 0) { NSLog(@"error: double click with nothing selected"); return; } fileEl = [theTable elementAtIndex:elementIndex]; NSLog(@"element: %@ %d", [fileEl filename], [fileEl isDir]); thePath = [NSString stringWithString:[theClient workingDir]]; thePath = [thePath stringByAppendingPathComponent: [fileEl filename]]; if ([fileEl isDir]) { NSLog(@"should cd to %@", thePath); [theClient changeWorkingDir:thePath]; if ((dirList = [theClient dirContents]) == nil) return; [theTable initData:dirList]; [theView reloadData]; [self updatePath :thePathMenu :[theClient workDirSplit]]; } else { if (theView == localView) { NSLog(@"should upload %@", thePath); [self performStoreFile]; } else { NSLog(@"should download %@", thePath); [self performRetrieveFile]; } } } - (void)tableView:(NSTableView *)tableView didClickTableColumn:(NSTableColumn *)tableColumn { if (tableView == localView) { NSLog(@"local"); [localTableData sortByIdent: [tableColumn identifier]]; [localView reloadData]; } else { NSLog(@"remote"); [remoteTableData sortByIdent: [tableColumn identifier]]; [remoteView reloadData]; } } - (void)setInterfaceEnabled:(BOOL)flag { [localView setEnabled:flag]; [remoteView setEnabled:flag]; [localPath setEnabled:flag]; [remotePath setEnabled:flag]; [buttUpload setEnabled:flag]; [buttDownload setEnabled:flag]; } - (void)setThreadRunningState:(BOOL)flag { threadRunning = flag; [self setInterfaceEnabled:!flag]; } - (void)performRetrieveFile { NSEnumerator *elemEnum; FileElement *fileEl; id currEl; [self setThreadRunningState:YES]; // We should actually do a copy of the selection elemEnum = [remoteView selectedRowEnumerator]; while ((currEl = [elemEnum nextObject]) != nil) { fileEl = [remoteTableData elementAtIndex:[currEl intValue]]; NSLog(@"should download: %@", [fileEl filename]); [ftp retrieveFile:fileEl to:local beingAt:0]; } } - (void)performStoreFile { NSEnumerator *elemEnum; FileElement *fileEl; id currEl; [self setThreadRunningState:YES]; // We should actually do a copy of the selection elemEnum = [localView selectedRowEnumerator]; while ((currEl = [elemEnum nextObject]) != nil) { fileEl = [localTableData elementAtIndex:[currEl intValue]]; NSLog(@"should upload: %@", [fileEl filename]); [ftp storeFile:fileEl from:local beingAt:0]; } } - (IBAction)downloadButton:(id)sender { if (threadRunning) { NSLog(@"thread was still running"); return; } [self performRetrieveFile]; } - (IBAction)uploadButton:(id)sender { if (threadRunning) { NSLog(@"thread was still running"); return; } [self performStoreFile]; } - (IBAction)localDelete:(id)sender { NSEnumerator *elemEnum; FileElement *fileEl; id currEl; elemEnum = [localView selectedRowEnumerator]; while ((currEl = [elemEnum nextObject]) != nil) { fileEl = [localTableData elementAtIndex:[currEl intValue]]; [local deleteFile:fileEl beingAt:0]; } } - (IBAction)remoteDelete:(id)sender { NSEnumerator *elemEnum; FileElement *fileEl; id currEl; elemEnum = [remoteView selectedRowEnumerator]; while ((currEl = [elemEnum nextObject]) != nil) { fileEl = [remoteTableData elementAtIndex:[currEl intValue]]; [ftp deleteFile:fileEl beingAt:0]; } } - (void)setTransferBegin:(NSString *)name :(unsigned long long)size { [infoMessage setStringValue:name]; [progBar setDoubleValue:0]; #ifdef WIN32 DWORD msecs = timeGetTime(); beginTimeVal.tv_sec=msecs/1000; beginTimeVal.tv_usec=(msecs - beginTimeVal.tv_sec*1000) * 1000; #else gettimeofday(&beginTimeVal, NULL); #endif transferSize = size; [mainWin displayIfNeeded]; } - (void)setTransferProgress:(NSNumber *)bytesTransferred { struct timeval currTimeVal; float speed; NSString *speedStr; NSString *sizeStr; double percent; unsigned long long bytes; bytes = [bytesTransferred unsignedLongLongValue]; #ifdef WIN32 DWORD msecs = timeGetTime(); currTimeVal.tv_sec=msecs/1000; currTimeVal.tv_usec=(msecs - currTimeVal.tv_sec*1000) * 1000; #else gettimeofday(&currTimeVal, NULL); #endif speed = (float)((double)bytes / (double)(currTimeVal.tv_sec - beginTimeVal.tv_sec)); percent = ((double)bytes / (double)transferSize) * 100; [progBar setDoubleValue:percent]; speedStr = [NSString alloc]; if (speed < 1024) speedStr = [speedStr initWithFormat:@"%3.2fB/s", speed]; else if (speed < 1024*1024) speedStr = [speedStr initWithFormat:@"%3.2fKB/s", speed/1024]; else speedStr = [speedStr initWithFormat:@"%3.2fMB/s", speed/(1024*1024)]; [infoSpeed setStringValue:speedStr]; [speedStr release]; sizeStr = [NSString alloc]; if (transferSize < 1024) sizeStr = [sizeStr initWithFormat:@"%3.2f : %3.2f B", (float)bytes, (float)transferSize]; else if (transferSize < 1024*1024) sizeStr = [sizeStr initWithFormat:@"%3.2f : %3.2f KB", (double)bytes/1024, (double)transferSize/1024]; else sizeStr = [sizeStr initWithFormat:@"%3.2f : %3.2f MB", (double)bytes/(1024*1024), (double)transferSize/(1024*1024)]; [infoSize setStringValue:sizeStr]; [sizeStr release]; } - (void)setTransferEnd:(NSNumber *)bytesTransferred { struct timeval currTimeVal; double deltaT; float speed; NSString *speedStr; NSString *sizeStr; double percent; unsigned long long bytes; bytes = [bytesTransferred unsignedLongLongValue]; #ifdef WIN32 DWORD msecs = timeGetTime(); currTimeVal.tv_sec=msecs/1000; currTimeVal.tv_usec=(msecs - currTimeVal.tv_sec*1000) * 1000; #else gettimeofday(&currTimeVal, NULL); #endif deltaT = (currTimeVal.tv_sec - beginTimeVal.tv_sec)+((double)(currTimeVal.tv_usec - beginTimeVal.tv_usec)/1000000); speed = (float)((double)bytes / deltaT); NSLog(@"Elapsed time: %f", (float)deltaT); percent = ((double)bytes / (double)transferSize) * 100; speedStr = [NSString alloc]; if (speed < 1024) speedStr = [speedStr initWithFormat:@"%3.2fB/s", speed]; else if (speed < 1024*1024) speedStr = [speedStr initWithFormat:@"%3.2fKB/s", speed/1024]; else speedStr = [speedStr initWithFormat:@"%3.2fMB/s", speed/(1024*1024)]; [infoSpeed setStringValue:speedStr]; [speedStr release]; sizeStr = [NSString alloc]; if (transferSize < 1024) sizeStr = [sizeStr initWithFormat:@"%3.2f : %3.2f B", (float)bytes, (float)transferSize]; else if (transferSize < 1024*1024) sizeStr = [sizeStr initWithFormat:@"%3.2f : %3.2f KB", (double)bytes/1024, (double)transferSize/1024]; else sizeStr = [sizeStr initWithFormat:@"%3.2f : %3.2f MB", (double)bytes/(1024*1024), (double)transferSize/(1024*1024)]; [infoSize setStringValue:sizeStr]; [sizeStr release]; [progBar setDoubleValue:percent]; [mainWin displayIfNeeded]; } - (IBAction)disconnect:(id)sender { [ftp disconnect]; [mainWin setTitle:@"FTP"]; } - (IBAction)showPrefPanel:(id)sender { [prefPanel makeKeyAndOrderFront:self]; switch (connMode) { case defaultMode: [portType selectCellWithTag:0]; break; case portMode: [portType selectCellWithTag:1]; break; case passiveMode: [portType selectCellWithTag:2]; break; default: NSLog(@"Unexpected mode on pref pane setup."); } } - (IBAction)prefSave:(id)sender { NSUserDefaults *defaults; defaults = [NSUserDefaults standardUserDefaults]; NSLog(@"tag... %d", [[portType selectedCell] tag]); switch ([[portType selectedCell] tag]) { case 0: //default NSLog(@"default"); connMode = defaultMode; [ftp setPortDefault]; [defaults setObject:@"default" forKey:connectionModeKey]; break; case 1: //port NSLog(@"port"); connMode = portMode; [ftp setPortPort]; [defaults setObject:@"port" forKey:connectionModeKey]; break; case 2: // passive NSLog(@"passive"); connMode = passiveMode; [ftp setPortPassive]; [defaults setObject:@"passive" forKey:connectionModeKey]; break; default: NSLog(@"unexpected selection"); } [prefPanel performClose:nil]; } - (IBAction)prefCancel:(id)sender { [prefPanel performClose:nil]; } - (IBAction)showFtpLog:(id)sender { [logWin makeKeyAndOrderFront:self]; } /** Called by the server object to register itself. */ - (void)setServer:(id)anObject { ftp = (FtpClient*)[anObject retain]; NSLog(@"FTP server object set"); return; } /* This routine is called after adding new results to the text view's backing store. We now need to scroll the NSScrollView in which the NSTextView sits to the part that we just added at the end */ - (void)scrollToVisible:(id)ignore { [logTextField scrollRangeToVisible:NSMakeRange([[logTextField string] length], 0)]; } - (IBAction)appendTextToLog:(NSString *)textChunk { NSAttributedString *attrStr; attrStr = [[NSAttributedString alloc] initWithString: textChunk attributes: textAttributes]; /* add the textChunk to the NSTextView's backing store as an attributed string */ [[logTextField textStorage] appendAttributedString: attrStr]; /* setup a selector to be called the next time through the event loop to scroll the view to the just pasted text. We don't want to scroll right now, because of a bug in Mac OS X version 10.1 that causes scrolling in the context of a text storage update to starve the app of events */ [self performSelector:@selector(scrollToVisible:) withObject:nil afterDelay:0.0]; [attrStr autorelease]; } /* --- connection panel methods --- */ - (IBAction)showConnPanel:(id)sender { [connectPanel makeKeyAndOrderFront:self]; } - (IBAction)connectConn:(id)sender { NSArray *dirList; char tempStr[1024]; char tempStr2[1024]; [connectPanel performClose:nil]; [mainWin makeKeyAndOrderFront:self]; ftp = [ftp initWithController:self :connMode]; [[connAddress stringValue] getCString:tempStr]; if ([ftp connect:[connPort intValue] :tempStr] < 0) { NSRunAlertPanel(@"Error", @"Connection failed.\nCheck that you typed the host name correctly.", @"Ok", nil, nil); NSLog(@"connection failed in connectConn"); return; } if ([connAnon state] == NSOnState) { strcpy(tempStr, "anonymous"); strcpy(tempStr2, "user@myhost.com"); } else { [[connUser stringValue] getCString:tempStr]; [[connPass stringValue] getCString:tempStr2]; } if ([ftp authenticate:tempStr :tempStr2] < 0) { NSRunAlertPanel(@"Error", @"Authentication failed.\nCheck that your username and password are correct.", @"Ok", nil, nil); NSLog(@"authentication failed."); return; } else { [ftp setWorkingDir:[ftp homeDir]]; if ((dirList = [ftp dirContents]) == nil) return; [remoteTableData initData:dirList]; [remoteView setDataSource:remoteTableData]; /* update the path menu */ [self updatePath :remotePath :[ftp workDirSplit]]; /* set the window title */ [mainWin setTitle:[connAddress stringValue]]; } } - (IBAction)cancelConn:(id)sender { [connectPanel performClose:nil]; } - (IBAction)anonymousConn:(id)sender { if ([connAnon state] == NSOnState) { [connUser setEnabled:NO]; [connPass setEnabled:NO]; } else { [connUser setEnabled:YES]; [connPass setEnabled:YES]; } } - (void)showAlertDialog:(NSString *)message { [message retain]; NSRunAlertPanel(@"Attention", message, @"Ok", nil, nil); [message release]; } - (connectionModes)connectionMode { return connMode; } @end ftp.app-0.3/English.lproj/000077500000000000000000000000001177253120400154445ustar00rootroot00000000000000ftp.app-0.3/English.lproj/InfoPlist.strings000066400000000000000000000011361177253120400207670ustar00rootroot00000000000000/* Localized versions of Info.plist keys */ CFBundleName = "FTP"; CFBundleShortVersionString = "FTP version 0.3"; CFBundleGetInfoString = "FTP version 0.3, Copyright 2005-2012."; NSHumanReadableCopyright = "Copyright 2005-2012 Riccardo Mottola.\n This software is distributed under GPL v2 or later."; ftp.app-0.3/English.lproj/MainMenu.nib/000077500000000000000000000000001177253120400177245ustar00rootroot00000000000000ftp.app-0.3/English.lproj/MainMenu.nib/classes.nib000066400000000000000000000034321177253120400220550ustar00rootroot00000000000000{ IBClasses = ( { ACTIONS = { anonymousConn = id; cancelConn = id; changePathFromMenu = id; connectConn = id; disconnect = id; downloadButton = id; listDoubleClick = id; localDelete = id; prefCancel = id; prefSave = id; remoteDelete = id; showConnPanel = id; showFtpLog = id; showPrefPanel = id; uploadButton = id; }; CLASS = AppController; LANGUAGE = ObjC; OUTLETS = { buttDownload = NSButton; buttUpload = NSButton; connAddress = NSTextField; connAnon = NSButton; connPass = NSTextField; connPort = NSTextField; connUser = NSTextField; connectPanel = NSPanel; infoMessage = NSTextField; infoSize = NSTextField; infoSpeed = NSTextField; localPath = NSPopUpButton; localView = NSTableView; logTextField = NSTextView; logWin = NSWindow; mainWin = NSWindow; portType = NSMatrix; prefPanel = NSPanel; progBar = NSProgressIndicator; remotePath = NSPopUpButton; remoteView = NSTableView; }; SUPERCLASS = NSObject; }, {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, {CLASS = fileTransmitParms; LANGUAGE = ObjC; SUPERCLASS = NSObject; } ); IBVersion = 1; }ftp.app-0.3/English.lproj/MainMenu.nib/info.nib000066400000000000000000000013031177253120400213460ustar00rootroot00000000000000 IBDocumentLocation 68 90 356 240 0 0 1440 938 IBEditorPositions 29 759 492 369 44 0 0 1440 938 IBFramework Version 489.0 IBOldestOS 1 IBOpenObjects 218 21 206 29 274 IBSystem Version 8S165 ftp.app-0.3/English.lproj/MainMenu.nib/keyedobjects.nib000066400000000000000000000734551177253120400231070ustar00rootroot00000000000000bplist00 Y$archiverX$versionT$topX$objects_NSKeyedArchiver ]IB.objectdataA 159@CFKcdefiq{$'/014:CHKPQSVZ^bcfqrsv~rbqr~r  !"',-.248;BCKLPQS[\uw (*-.19:BIJQRTUV\]adghijknr "#$%*1#238?@AELPQRUY`abeipqruye"&(*9&BGHMNQ[&\bcehklpqtu~rrhj!"#+./4>?@ACHOY]elmvw{|U?U  hj   !&',-2328=>CDIJ2O2T2Y2^cdijiot{|}8 %,12:;=?@EOP@QSYcgklUmstv}~hj   " # ) 3 " 8 9 B 8 B C G P Y 8 Y Z ^ _ c l 8 m r t w x y d 8d 8 ^ 8 8 6 r  ::   ^ _ _ _fU U {          ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v wX x y z { | } ~   U$null  !"#$%&'()*+,-./0_NSObjectsValues_NSAccessibilityConnectors_NSClassesValuesZNSOidsKeys[NSNamesKeys]NSClassesKeys_NSAccessibilityOidsValues\NSOidsValues_NSVisibleWindowsV$class]NSConnections]NSNamesValues]NSObjectsKeys_NSAccessibilityOidsKeys[NSFramework]NSFontManagerYNSNextOidVNSRooth=i?@j2>J234[NSClassName678YNS.string]NSApplication:;<=X$classesZ$classname=>?_NSMutableStringXNSStringXNSObject:;ABB?^NSCustomObject6D8_IBCocoaFrameworkGHJZNS.objectsILMNOPQRSTUVWXYZ[\]^_`ab_NSWindowStyleMask_NSWindowBackingYNSMinSize]NSWindowTitle]NSWindowClass\NSWindowRect\NSScreenRectYNSMaxSize\NSWindowViewYNSWTFlags[NSViewClass px _{{202, 326}, {467, 392}}SFTPXNSWindow6g8TViewjklm.opZNSSubviews_NSNextResponderWNSFrameGrzstuvwxyEcov2jk|}~l__[NSSuperview]NSNextKeyView\NSCornerView_NSHeaderClipView[NSHScrollerXNSvFlagsXNSsFlags[NSVScroller]NSContentView\NSScrollAmts C;27DOA A AAGz7;2jk|}lssYNSBGColorYNSDocViewYNScvFlags35 6Gz2k|~_NSIntercellSpacingWidth\NSHeaderView_NSColumnAutoresizingStyle[NSRowHeight_NSDraggingSourceMaskForLocalYNSEnabledYNSTvFlags_NSIntercellSpacingHeight_NSDraggingSourceMaskForNonLocal[NSFrameSize[NSGridColor^NSTableColumns_NSBackgroundColor"@@"A Z@"@43-Z{186, 224}k|[NSTableViewjk|}lss>@?6Y{186, 17}:;?_NSTableHeaderViewVNSView[NSResponderk|lss_{{187, 0}, {16, 17}}:;?]_NSCornerViewGz2^NSResizingMask\NSHeaderCellZNSMinWidthWNSWidth\NSIdentifier^NSIsResizeableZNSDataCellZNSMaxWidth"Be`"C6X +"Dz1Xfilename     [NSTextColorYNSSupportZNSContents[NSCellFlags\NSCellFlags2$&! *TNameVNSSizeVNSNameXNSfFlags"A0"#\LucidaGrande:;?VNSFont !"#WNSWhite\NSColorSpaceK0.33333299%:;%&&?WNSColor&(!)*+,-#[NSColorName]NSCatalogName)('%VSystem_headerTextColor !2#B0%:;566789?_NSTableHeaderCell_NSTextFieldCell\NSActionCellVNSCell;  =>@AB]NSControlView-.,01@DG"AP"# !I#B1%&(!)*M,-#)/'%_controlTextColor:;R7789?:;TUU?]NSTableColumn:;WXXY?^NSMutableArrayWNSArray[!\#UNSRGBO!0.76086956 0.76086956 0.76086956%:;_Ц`a?\%NSTableViewYNSControl_{{1, 17}, {186, 224}}:;dee?ZNSClipViewk|glhisssmnopXNSTargetYNSPercentXNSAction8:"?[9_{{187, 17}, {15, 224}}\_doScroller::;tuua?ZNSScrollerk|glhissszn|}<:"?}ـ=_{{1, 241}, {186, 15}}Gz2_{{1, 0}, {186, 17}}&(!),-#BA'%_controlBackgroundColor !#K0.66666669%_{{10, 96}, {203, 257}}:;?\NSScrollViewjk|}~l__F GNLb]ZGDGzGZ]LN2jk|}lttHEEIYIX6GzI2k|~̀KG G4NJWP-k|ՀIMLLjk|}ltt`EEK@Ka6k|lttEEOGzԀQ2ISR V1    ǀU&!T* !"#%;  =>@AB-.,I0[!#O!0.76086998 0.76086998 0.76086998%[!#%k|glhitttnEEE[:"??S\k|glhitttn|EEE^:_GzK2_{{254, 96}, {203, 257}}k|l9__   d -ne_{{214, 271}, {39, 38}} ;  u_NSKeyEquivalent]NSNormalImage^NSButtonFlags2_NSPeriodicInterval]NSButtonFlags_NSPeriodicDelay_NSAlternateContentslhgfcmfP#&"A "# (2)*+^NSResourceNamejkiWNSImage[arrow_right:;/001?_NSCustomResource_%NSCustomResource6!8:;566789?\NSButtonCell]%NSButtonCell:;9::a?XNSButtonk|l9__>  A p nq_{{214, 222}, {39, 38}} ;  DEGvǀusgromfR<-(2M*+tkiZarrow_left6!8k|l9__VXYZ w x_{{17, 355}, {198, 26}}] ^_`a b;cd>fXghilmnwq>tX_NSAlternateImageVNSMenuZNSMenuItem_NSPreferredEdgeZNSPullDown]NSAltersState_NSUsesItemFromMenu_NSArrowPosition,A@@{zf  vy, K6!8^xyz{|g}~ihZ]NSMnemonicLoc_NSKeyEquivModMaskWNSTitleYNSOnImageZNSKeyEquivZNSIsHidden\NSMixedImage{|}fx z[NSMenuItemsZlocal view(2*+~ki_NSMenuCheckmark(2*+ki_NSMenuMixedState__popUpItemAction::;__?68ZOtherViewsGziz2:;^^?:;6789?_NSPopUpButtonCell^NSMenuItemCell:;:a?]NSPopUpButtonk|l9__Y  _{{252, 355}, {197, 26}}] ^_`a b;cd>fXglmnx>tX,f , 6!8^xyz{|g}~ì}f zр[remote view68Gz2jk|l__X\NSBorderType_NSTitlePosition[NSTitleCellYNSOffsets]NSTransparentYNSBoxType Gz瀔2jk|lyypGz2k|l9 _{{241, 10}, {187, 17}} ;  >@  ,f0@&(!),-#-'%_textBackgroundColor&(!)*,-#)'%YtextColor:;a?[NSTextField\%NSTextFieldk|l"#$%&'YNSpiFlagsZNSMaxValue\NSDrawMatrix#@Y):;+,,?ZNSPSMatrix_{{11, 6}, {210, 20}}:;/00?_NSProgressIndicatork|l9468 _{{13, 38}, {270, 17}} ;  >@ A,f0@k|l9EH _{{285, 38}, {143, 17}} ;  >@  ,f0_{{2, 2}, {440, 62}}:;S?_{{10, 15}, {444, 66}}V{0, 0}   XYZ@ǀ0XProgressD`"# !b#M0 0.80000001%:;eff?UNSBox_{{1, 9}, {467, 392}}_{{0, 0}, {1440, 938}}Z{300, 172}_{3.40282e+38, 3.40282e+38}:;lmm?_NSWindowTemplate:;oppq?\NSMutableSetUNSSetGsz;tuvwxyz{|}~ĀʀЀԀـހGIKMRV]cjrāƁȁʁ́΁Ёҁԁ؁ځ܁ށ ')+-/12WNSLabelXNSSource^xyz{|~}zcedXMinimizeQm68_performMiniaturize::;ɣ?_NSNibControlConnector^NSNibConnector΀À^xyz{|~€}f_Bring All to Front68_arrangeInFront:݀ɀ^xyz{|~ƀǀ}Ȁz>?_NewApplication HelpQ?68YshowHelp:0]NSDestinationπ^xyz{|~̀̀}΀zTWUXQuit FTPQq68Zterminate:0 Ӏ^xz{|~ ̀Ҁ}fYAbout FTP68_orderFrontStandardAboutPanel:0؀^xyz{|~ր}׀[Hide OthersQh_hideOtherApplications:0')݀^xyz{|~,.̀ۀ}܀XHide FTPUhide:057ဿ^xyz{|~:̀}fXShow All_unhideAllApplications:BD瀿^xyz{|~FGI}zMO[\SCutQx6S8Tcut:VX쀿^xyz{|~F[]}UPasteQv6c8Vpaste:fh񀿀^xyz{|~Fkm}ZSelect AllQa6s8ZselectAll:vx^xyz{|~F{}}TCopyQc68Ucopy:^xyz{|~F}fVDeleteWdelete:023]AppControllerXdelegate:;?_NSNibOutletConnectorFLMNOPQRSTUVWX`aDCE_{{101, 194}, {430, 155}}^Connection Log6g8jkl.pBGz2jk|} A >; DGz ;>2jk|}lXNSBoundsXNSCursor 8  -976Gzԁ 2k|lS.,\NSSharedDataZNSDelegateYNSTVFlags[NSDragTypes_NSTextContainer  "5 6 GJ_Apple HTML pasteboard type_Apple PICT pasteboard type_1NeXT Encapsulated PostScript v1.2 pasteboard type_*NeXT Rich Text Format v1.0 pasteboard type_Apple PDF pasteboard type_NSFilenamesPboardType_NSStringPboardType_NeXT TIFF v4.0 pasteboard type_NSColor pasteboard type_#CorePasteboardFlavorType 0x6D6F6F76_NeXT RTFD pasteboard type_{{0, 24}, {413, 153}}    ZNSTextView_NSLayoutManagerYNSTCFlags"C΀ !,.]NSTextStorageYNSLMFlags_NSTextContainers >.6!8:; !?_NSMutableAttributedString_NSAttributedStringG#z2:;'  ?:;)?+,-./012.*56._NSSelectedAttributesWNSFlags_NSDefaultParagraphStyle_NSInsertionColor_NSLinkAttributes_NSMarkedAttributes# a)+4-G:;>AWNS.keys<=&(?@$%*&(!)D,-#B''%_selectedTextBackgroundColor&(!)*J,-#))'%_selectedTextColor:;OPP?\NSDictionaryG:RVASTU/03WXY,-.*[NSUnderline]^_`aYNSHotSpot\NSCursorType1 2W{8, -8}:;dϢ?[!f#F0 0 1%:;ijj?_NSTextViewSharedData\{428, 1e+07}:;m  no?[%NSTextViewVNSText_{{1, 1}, {413, 153}}]^ra:2W{4, -5}k|vgliy{n}ZNSCurValue"?<:=_{{414, 1}, {15, 139}}k|vglhiyn?:"?rC@_{{-100, -100}, {87, 18}}Z{430, 155}_{{1, 9}, {430, 155}}Z{213, 129}VlogWinIHZremoteViewJYlocalView L\logTextFieldQN^xyz{|~OP}fz56XShow Log[showFtpLog:US^xyz{|~́T}f^Preferences...^showPrefPanel:W\k|l9ɁXXY Zjk|lp_{{14, 14}, {170, 22}} ;  >@_NSDrawsBackground,[W 0qA@Ylocalhost[connAddress^bk|l9XX_ `_{{198, 14}, {51, 22}} ;  >@ۀ,a^ 0R21XconnPortdik|l9eef gjk|lp|zz_{{96, 55}, {153, 22}} ;  > @ۀ,hd 0SftpXconnUserkqk|l92 _NSOriginalClassNameeemn pol_NSSecureTextField_{{96, 25}, {153, 22}} ;  >@ۀ,fk 0:;,--?^NSClassSwapperXconnPass01sLMNOPQRSTUVX56789:;`a=uvtxw_{{79, 285}, {289, 271}}WConnectWNSPanel6g8jklD.FpyGIzKĹz2jk|lP;;XSTU{xxeGZze2G^z_bc}dk2k|l9h kee~ n_{{10, 88}, {97, 18}}] ;  o>q_Xsǀf,}Hb@ .,0XUsername&(!),-#B'%\controlColork|l9ee _{{9, 27}, {82, 17}} ;  =>c@ .,0XPassword_{{2, 2}, {263, 115}}_{{10, 52}, {267, 135}}   Y@ǀ0WAccount !b#%k|l9;; xx n_{{199, 12}, {84, 32}}] ;  >K,@mf8D#YHelvetica6!8k|l9;; ΁xx n_{{115, 12}, {84, 32}}] ;  >L,mfVCancel6!8jk|l;;XxxXGzāX2GzW^2k|l9XX _{{184, 16}, {15, 17}} ;  =>@.,0@Q:_{{2, 2}, {263, 50}}_{{10, 194}, {267, 70}}   Y@ǀ0_Server Address and Port !b#%_{{1, 1}, {289, 271}}\connectPanel^xyz{|~O}fZConnect...^showConnPanel:K\connectConn:#L[cancelConn:)_}^anonymousConn:/^W[nextKeyView5kd_:}XconnAnonw@vÀYlocalPathxFŀZremotePathKLǀkQKWɀ_V߁}ˀ^[_d̀}K`0πs_initialFirstResponderfwрv_changePathFromMenu:lxӀqs׀^xyz{|~vOր}fZDisconnect[disconnect:ـWprogBaruۀc]uploadButton:v݀o_downloadButton:I߀WmainWinXinfoSize[infoMessage耿^xyz{|~}fzDE\localDelete:퀿^xyz{|~}fzFG]remoteDelete:lk|>[NSCellClassYNSNumRowsZNSCellSizeYNSNumColsWNSCells[NSProtoCell^NSSelectedCell_NSCellBackgroundColor]NSMatrixFlags_NSIntercellSpacing -D(,jk|lp_{{12, 22}, {224, 58}}Gz2] ;  >s ǁ,mf]default portsxz]NSRadioButton6!8] ;  >sUNSTag,mf_client arbitrates (PORT)] ;  l> tsXǀf,mf_server arbitrates (PASV)Y{224, 18}V{4, 2}]   >tlǁ,H8QmfURadio:;a?XNSMatrixY%NSMatrixXportType"$ k|l9&&( + njkl-./p"_{{182, 10}, {84, 32}}] ;  3>6$9 ,m TSave6!86!8YprefSave:AB &LMNOPQRSTUVXFGHIJK&`aN$#%_{{258, 199}, {280, 174}}[Preferences6g8GTz$W2jk|lZ&&]^_Gdzׁ2Ghzā2_{{2, 2}, {236, 88}}_{{20, 58}, {240, 92}}   o>q@ǀ,0_Data Connection Managment !b#%k|l9&&y | n_{{98, 10}, {84, 32}}] ;  >W!,m 6!86!8_{{1, 1}, {280, 174}}YprefPanelW([prefCancel:uc*ZbuttUploadvo,\buttDownload.YinfoSpeed00IG ]Dsh0I)xb;u_&xXy_AWs7wLih$Ktv  Fc 3{e4SdOs7;WځN@xAc}H递Ձ 8QIXQ XՀ߁K̀vzkƁ^ˁ zV倦EoŁ`]сg^xyz{ |~ \NSIsDisabled]NSIsSeparatorf} f ^xyz{ |~ €̀f} f TFileG $zsՁN2^xy *z{|~i - 2YNSSubmenu8O9}f:z 4 5 7OfP^submenuAction:^xy *z{|~i < A8Ɓ<}f=THelpG Dz݀ŀ2^xyz{ |~ €̀f} f ^xy *z{|~i S X8B}fCULocalG [z2VRemoteG `z2^xy *z{|~i f ḱKI}fJXServicesz n o qLNM6 l8G uz2__NSServicesMenuXMainMenuG zz āQ7XA]`;2^xy *z{|~i  8́R}fSG z )7сS@H4ڀՀ߁Vˀ2^xyz{ |~ €̀f} f \_NSAppleMenu^xy *z{|~iF  8Y}fZTEdit6 8G zDxXh2^xy *z{|~i  8^}f_^xy *z{|~i  ȁ8a}fbVWindow6 8G z΀32^_NSWindowsMenu[_NSMainMenu:; YY?G ]F&_sw0000F0_ A_F_I0t0&yF_;;xhF&;__;  vz̀́e7X88X́Óes8 ]e ̀ ́OIE88AÓHQ xe;Xx́{́x怔 Ɓ8x`8XégG 7 9A_K$huIXFibDwWcLxshvx00t } ;{cŀIWOdkS^zvXˀ3Q8ƀos7EgG s 9 t u v w x y z { | } ~     klmnopqrstuvwxyzv{|}~vvgYPrefPanelYNSButton46 8Q1YPopUpListYNSButton3\NSTextField26!8WMainWin[NSMenuItem9\NSTextField3\NSTextField4S121YNSMatrix1YConLogWin\NSTextField1]NSTextField22[NSMenuItem3[NSMenuItem4YNSButton1^NSTextField221]NSScrollView2^NSTextField311^NSPopUpButton1T1111]NSScrollView16 x8\NSMenuItem106 8Q2ZNSButton31[NSMenuItem1YConnPanel6 8\File's Owner^NSScrollView11G kgG  lgG {huFs;|hDcvwX}0x$xKuyA&W~_ b tLw i7y0)I_tvzsxNހ{ˀzej7k؁8xހ^ʀIVKЁR;o/ʀՁX)Ā1]@Ɓ4܁XVQrQIЁcGWꀞԁ ΁K- Ԁ€ сd OȀ]Ev'`MHzA߁̀3ҁ+sڀڀ}ĀفՀŀƁcŚgG |  } ~  S                ÁāŁƁǁȁɁʁˁ́́΁ρЁсҁӁԁՁցׁ؁فځہ/܁݁ށ߁      !"#$%&'()*+,-./0123456789:;<g':5!S'#B* ; >g,DHCEI<j)8=9$ G@?:Q"7A9\ 4F(%zo G z2G gG g:; ?^NSIBObjectData#,1:LQVdf=Ok})5CMTWZ]`cfilnqsvy|~   & / B D M X [ ] _  # % ' ) + - / 1 3 5 : < > Y ] f o t v  ! / < O [ d m y   ) + - / 1 3 5 7 9 < > G J L N    6 X d p  &(*,.0246@IRfmy"-5BQ\gikmrwyz|$&(*7@ELYanz| 0=Daoqsuwy~-5BHlnw 7DMXc &(AJS`  fhjkmoqsuwy+-/1246SUWY[]jl,.02468ADFHb -?UWY[]_aclnpuwx  !.<EPYvxz|} &(*,-024M#%')*-24579;<>GIv!#%7DFHJ]qz/13569;=W!*,58:<q~79;=>ACE^  " C M X e g i k m v y { } !!!!!!@!B!D!F!H!J!L!Q!n!p!r!t!u!w!y!!!!!!!!!!!!""!"#"%"'")"+"4"E"G"I"L"Y"g"i"r"{""""""""## ###%######################################$$$$ $$$$$$$ $#$&$)$,$/$2$5$8$;$>$A$C$P$X$a$c$e$g$$$$$$$$$$$$$$$$$$$%%% %"%$%&%G%I%K%M%O%Q%S%h%q%%%%%%%%%%%%%%%%%%%%&&&&&&(&*&,&.&O&Q&S&U&W&Y&[&l&o&r&t&w&&&&&&&&&&&&&&&&&&&' '' '"'$'&'('I'K'P'R'T'V'X'Z'f'h''''''''''''''''''''((((((((%(>(K(M(O(Q(r(t(v(x(z(|(~((((((((((((((((((((((()))))))7)9);)=)?)A)C)N)P)Y)d)f)s)u)w)y)))))))))))))))))))))))** ** *"*$*&*/*1*3*A*J*S*Z*q****************++ + ++ +"+%+'+0+3+6+8+e+h+k+n+q+t+w+z+|++++++++++++++++++++++,, , ,,<,I,T,^,j,|,,,,,,,,,,,,,,,,,,,,,,,,,--J-w-----.!.=.U.j.u..................// ///8/M/V/Y/\/^/g/l/u/z//////00000000!0#00080=0@0C0H0K0N0Q0f0h0k0m0o00000000000000001111 11#1-1:1=1?1B1J1S1X1e1l1n1w1|1111111111122'2*2-2225282:2=2U2~2222222222222222233333 3"3,3=3@3C3E3G3T3e3g3j3l3o333333333333333333444 4 4 444 4/4@4C4F4H4J4g4j4m4p4q4s4v444444444444444455555.515456585U5X5[5^5_5a5d5|55555555555555555555666666!6$6&6>6c6e6g6i6l6o6p6r6v6666666666666666677<7>7@7B7D7G7H7J7S7X7g7p7777777777777777788 8 888!8$8&8/888;8>8A8D8F8w8z8}8888888888888888888888888899=9?9B9D9G9J9O9Q9S9]9f9r9u9x999999999999:: : ::::: :5:7:::<:>:K:h:k:n:q:r:t:w:::::::::::;;;;;;;';4;6;S;V;Y;\;];_;b;z;;;;;;;;;;;;;;;;<<<< >>>,>=>?>B>D>G>h>k>n>p>r>t>v>>>>>>>>>>>>>>>>>>>? ??? ?"?%?1?B?E?H?J?M?^?a?d?f?h?q??????????????????????@@@ @ @@@"@%@'@*@;@>@A@C@F@^@o@q@t@v@x@@@@@@@@@@@@@@@@@@@A AAAA!A#A+AAAACAEASAdAfAiAkAmAAAAAAAAAAAAAAAAAAAAABBBB&B)B,B.B0B2B4BABDBFBIBVBgBiBlBnBqBBBBBBBBBBBBBBBBBC)C5C?CJCTC\ChCwCCCCCCCCCCCCCCCCCCCCCCCDDD!D(D+D.D1D3DhDkDnDpDsDvDxDzDDDDDDDDDDDDDDDEEEUEWEZE\E_EbEdEfEEEEEEEEEEEEEEEFFFFF F#F@FCFFFIFJFLFOF`FcFeFhFjFFFFFFFFFFFFFFFGGGGG G;G>GAGDGGGJGMGPGRGUGpG|GGGGGGGGGGGGGGGGGGGGGGHHH H H#H;HXHZH]H_HbHdHHHHHHHHHHHII I IIIIII#I%I.I0IGIQIbIdIgIiIlIxIIIIIIIIIIIIIIIIIIIIIJJJJJJJJ%JJJJJJJJJJJJKKKKK KKKKKKKK!K#K&K(K+K.K1K4K7K9KM@MiMkMmMoMpMrMtMvMwMMMMMMMMMMMMMMMMMMMN NNNNNNNNN(N9NP@PCPJPSPUP^PePgPjPlPnP}PPPPQ]Q_QbQeQgQiQkQmQoQrQtQvQyQ{Q~QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRR R RRRRRRRRR!R$R'R)R+R-R/R2R5R8R;R>RARDRFRIRRRRRRRRRRRRRRRRRRRRRRRRSSSS S SSSSSSSSS"S$S&S(S+S-S/S1S4S7S9S;S=S@SBSDSFSHSKSMSPSRSTSWS`SSSSSSSSSSSSSSSTTTT TTTTTTT T#T&T)T,T/T2T5T8T;T>TATDTGTJTMTPTSTVTYT\T_TbTeThTkTnTqTtTwTzT}TTTTTTTTTTTTTTTTUU UU#U1U=UIUSUbUpUUUUUUUUUUUUUUUUVVVVV V)V,V/V2V;WpWsWuWxWzW|W~WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXX X XXXXXXXX!X$X'X*X-X0X2X4X6X9X;X=X@XCXFXIXLXNXPXSXUXXX[X^XaXdXgXjXmXpXsXvXyX{X}XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYZEZHZKZNZQZTZWZZZ]Z`ZcZfZiZlZoZrZuZxZ{Z~ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ[[[[ [[[[[[[ [#[&[)[,[/[2[5[8[;[>[A[D[G[J[M[P[S[V[Y[\[_[b[e[h[k[n[q[t[w[z[}[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\\\\ \ \\\\\\\\\"\$\&\(\*\,\/\2\4\7\9\;\=\@\C\E\G\J\L\N\Q\S\U\X\Z\\\_\b\d\f\i\l\n\p\r\u\x\z\}\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\]]]]] ] ]]]]]]]]]!]#]&](]*],].]0]2]5]8]:]=]@]B]E]G]I]K]M]O]Q]S]V]X]Z]]]_]a]d]m]n]p]y]z]}]]]]] ]ftp.app-0.3/English.lproj/MainMenu.nib/objects.nib000066400000000000000000000306021177253120400220500ustar00rootroot00000000000000 typedstream@NSIBObjectDataNSObjectNSCustomObject)@@NSMutableStringNSString+ NSApplicationi] NSMenuItemNSMenu̔i@@@EditNSMutableArrayNSArray i@@IIi@@@@:i@CopycNSCustomResource)NSImageNSMenuCheckmarkNSMenuMixedStatePastevDelete Select AllaCutxRemoteDeleteNSBox*NSView) NSResponder @@@@ffffffffNSButton NSControl) T T icc@ NSButtonCell? NSActionCellNSCellAii8@@@@SaveNSFont$[36c]LucidaGrandef ci: ssii@@@@@@ʚ[28c]Helvetica ’b T T Ŭ8CancelɅγ@ͅNSMatrix>ÒԚ ::Ԓ#iiii:::ffffi@@@@@D(Ŭ default portsɅֳHƬData Connection ManagmentɅc@@儙textBackgroundColor膄?L͆ NSTextFieldÒ NSScrollView⽒ NSClipView: NSTableView=Ò @@@ff@@f::iNSTableHeaderView@@ccc儙controlBackgroundColor熅 _NSCornerView NSTableColumn)@fff@@ccfilenameC6XBe`脄NSTableHeaderCell쬂Nameʚ$LucidaGrande >儙headerTextColor쬂1@Ʌ儙controlTextColorffff?BY?BY?BYZ@ NSScrollerÒff:?[ _doScroller:?}̱ `ˁˁffffi „  DŽfilenameC6XBe` Name>쬂1@ɅɃ?B`?B`?B`Z@ĄɃ?B`?B`?B`??S̱?}̱ "`ˁˁ,- " ’-ց'&'&Ŭʚ$LucidaGrande  . arrow_right’-ց'&'&Ŭ<-04 arrow_left NSPopUpButton’cNSPopUpButtonCell1NSMenuItemCellŬA@Ʌ:K@Ʌ OtherViews@ local view_popUpItemAction:<i@iA; c=A@ɅEK@Ʌ OtherViewsH remote viewF҂I􆅅 ӁӁ󆅅 BB쬂Progressʚ$LucidaGrande ?L͆񒄄NSProgressIndicatorܽF NSPSMatrix[12f] 󒅒ccddcd &󒅒쬂@ɅW儙 textColor:&󒅒쬂@Ʌ[Yׅ>> 󒅒쬂@ɅYׅWindow_Minimizem^_Bring All to Front_NSWindowsMenu_A:i’j T T jŬ8ConnectɅl@ͅ’js T T jŬ8CancelɅp@ͅjtvv쬂qA@ localhostɅxYׅv33v쬂qA@21Ʌ{Yׅvv쬂@:Ʌ~ׅ22t  F Fj쬂Server Address and PortP?L͆v!!h 4  j쬂AccountP?L͆h’h XaahŬ AnonymousɅHugW,4~DHT竁vCE`ÁIyHفE<j)ȁw8=$Vlh.9mx綁$SX ́ q绁G翁΁@?ցIbb:Qс"ԁ7p:Ask@[-ʁ箁9_^\ 4F߁(L%RzZo碁{ JIBCocoaFrameworkftp.app-0.3/FTP.pbproj/000077500000000000000000000000001177253120400146525ustar00rootroot00000000000000ftp.app-0.3/FTP.pbproj/project.pbxproj000066400000000000000000000315121177253120400177300ustar00rootroot00000000000000// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 39; objects = { 080E96DCFE201CFB7F000001 = { fileRef = 29B97318FDCFA39411CA2CEA; isa = PBXBuildFile; settings = { }; }; 080E96DDFE201D6D7F000001 = { children = ( F5F5F93707FD8CAD01A80101, F5F5F93807FD8CAD01A80101, F5F5F93907FD8CAD01A80101, F5F5F93A07FD8CAD01A80101, F56A03FB080AC70701A80101, F56A03FD080AC71101A80101, F5BE3AF6080C6A3601A80101, F5BE3AF7080C6A3601A80101, F5C84D6008142DF201A80101, F5C84D6108142DF201A80101, F5EFB6470818FE6E01A80101, F5EFB6450818FE6001A80101, ); isa = PBXGroup; name = Classes; refType = 4; sourceTree = ""; }; 089C165CFE840E0CC02AAC07 = { children = ( 089C165DFE840E0CC02AAC07, ); isa = PBXVariantGroup; name = InfoPlist.strings; refType = 4; sourceTree = ""; }; 089C165DFE840E0CC02AAC07 = { fileEncoding = 10; isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; refType = 4; sourceTree = ""; }; 089C165EFE840E0CC02AAC07 = { fileRef = 089C165CFE840E0CC02AAC07; isa = PBXBuildFile; settings = { }; }; //080 //081 //082 //083 //084 //100 //101 //102 //103 //104 1058C7A0FEA54F0111CA2CBB = { children = ( 1058C7A1FEA54F0111CA2CBB, ); isa = PBXGroup; name = "Linked Frameworks"; refType = 4; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; refType = 0; sourceTree = ""; }; 1058C7A2FEA54F0111CA2CBB = { children = ( 29B97325FDCFA39411CA2CEA, 29B97324FDCFA39411CA2CEA, ); isa = PBXGroup; name = "Other Frameworks"; refType = 4; sourceTree = ""; }; 1058C7A3FEA54F0111CA2CBB = { fileRef = 1058C7A1FEA54F0111CA2CBB; isa = PBXBuildFile; settings = { }; }; //100 //101 //102 //103 //104 //190 //191 //192 //193 //194 19C28FACFE9D520D11CA2CBB = { children = ( 8518DC1E0E354C3500A80101, ); isa = PBXGroup; name = Products; refType = 4; sourceTree = ""; }; //190 //191 //192 //193 //194 //290 //291 //292 //293 //294 29B97313FDCFA39411CA2CEA = { buildSettings = { }; buildStyles = ( 4A9504CCFFE6A4B311CA0CBA, 4A9504CDFFE6A4B311CA0CBA, ); hasScannedForEncodings = 1; isa = PBXProject; mainGroup = 29B97314FDCFA39411CA2CEA; projectDirPath = ""; targets = ( 29B97326FDCFA39411CA2CEA, ); }; 29B97314FDCFA39411CA2CEA = { children = ( 080E96DDFE201D6D7F000001, 29B97315FDCFA39411CA2CEA, 29B97317FDCFA39411CA2CEA, 29B97323FDCFA39411CA2CEA, 19C28FACFE9D520D11CA2CBB, ); isa = PBXGroup; name = FTP; path = ""; refType = 4; sourceTree = ""; }; 29B97315FDCFA39411CA2CEA = { children = ( 29B97316FDCFA39411CA2CEA, ); isa = PBXGroup; name = "Other Sources"; path = ""; refType = 4; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; refType = 4; sourceTree = ""; }; 29B97317FDCFA39411CA2CEA = { children = ( 85FC29710DD7B28300A80101, 29B97318FDCFA39411CA2CEA, 089C165CFE840E0CC02AAC07, F5C0879F08A0C47B01A8012F, F5C087A108A0C4AF01A8012F, ); isa = PBXGroup; name = Resources; path = ""; refType = 4; sourceTree = ""; }; 29B97318FDCFA39411CA2CEA = { children = ( 29B97319FDCFA39411CA2CEA, ); isa = PBXVariantGroup; name = MainMenu.nib; path = ""; refType = 4; sourceTree = ""; }; 29B97319FDCFA39411CA2CEA = { isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; refType = 4; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA = { children = ( 1058C7A0FEA54F0111CA2CBB, 1058C7A2FEA54F0111CA2CBB, ); isa = PBXGroup; name = Frameworks; path = ""; refType = 4; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; refType = 0; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; refType = 0; sourceTree = ""; }; 29B97326FDCFA39411CA2CEA = { buildPhases = ( 29B97327FDCFA39411CA2CEA, 29B97328FDCFA39411CA2CEA, 29B9732BFDCFA39411CA2CEA, 29B9732DFDCFA39411CA2CEA, ); buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; HEADER_SEARCH_PATHS = ""; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = FTP; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; WRAPPER_EXTENSION = app; }; dependencies = ( ); isa = PBXApplicationTarget; name = FTP; productInstallPath = "$(HOME)/Applications"; productName = FTP; productReference = 8518DC1E0E354C3500A80101; productSettingsXML = " CFBundleDevelopmentRegion English CFBundleExecutable FTP CFBundleIconFile FTP_icon_osx.icns CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion 0.2 NSMainNibFile MainMenu NSPrincipalClass NSApplication "; }; 29B97327FDCFA39411CA2CEA = { buildActionMask = 2147483647; files = ( F5F5F93B07FD8CAD01A80101, F5F5F93D07FD8CAD01A80101, F56A03FE080AC71101A80101, F5BE3AF8080C6A3601A80101, F5C84D6208142DF201A80101, F5EFB6480818FE6E01A80101, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 29B97328FDCFA39411CA2CEA = { buildActionMask = 2147483647; files = ( 080E96DCFE201CFB7F000001, 089C165EFE840E0CC02AAC07, F5C087A008A0C47C01A8012F, F5C087A208A0C4B001A8012F, 85FC29720DD7B28300A80101, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 29B9732BFDCFA39411CA2CEA = { buildActionMask = 2147483647; files = ( 29B9732CFDCFA39411CA2CEA, F5F5F93C07FD8CAD01A80101, F5F5F93E07FD8CAD01A80101, F56A03FC080AC70701A80101, F5BE3AF9080C6A3601A80101, F5C84D6308142DF201A80101, F5EFB6460818FE6001A80101, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 29B9732CFDCFA39411CA2CEA = { fileRef = 29B97316FDCFA39411CA2CEA; isa = PBXBuildFile; settings = { ATTRIBUTES = ( ); }; }; 29B9732DFDCFA39411CA2CEA = { buildActionMask = 2147483647; files = ( 1058C7A3FEA54F0111CA2CBB, ); isa = PBXFrameworksBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; //290 //291 //292 //293 //294 //4A0 //4A1 //4A2 //4A3 //4A4 4A9504CCFFE6A4B311CA0CBA = { buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OPTIMIZATION_CFLAGS = "-O0"; ZERO_LINK = YES; }; isa = PBXBuildStyle; name = Development; }; 4A9504CDFFE6A4B311CA0CBA = { buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; ZERO_LINK = NO; }; isa = PBXBuildStyle; name = Deployment; }; //4A0 //4A1 //4A2 //4A3 //4A4 //850 //851 //852 //853 //854 8518DC1E0E354C3500A80101 = { explicitFileType = wrapper.application; isa = PBXFileReference; path = FTP.app; refType = 3; sourceTree = BUILT_PRODUCTS_DIR; }; 85FC29710DD7B28300A80101 = { isa = PBXFileReference; lastKnownFileType = image.icns; path = FTP_icon_osx.icns; refType = 4; sourceTree = ""; }; 85FC29720DD7B28300A80101 = { fileRef = 85FC29710DD7B28300A80101; isa = PBXBuildFile; settings = { }; }; //850 //851 //852 //853 //854 //F50 //F51 //F52 //F53 //F54 F56A03FB080AC70701A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = localclient.m; refType = 4; sourceTree = ""; }; F56A03FC080AC70701A80101 = { fileRef = F56A03FB080AC70701A80101; isa = PBXBuildFile; settings = { }; }; F56A03FD080AC71101A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = localclient.h; refType = 4; sourceTree = ""; }; F56A03FE080AC71101A80101 = { fileRef = F56A03FD080AC71101A80101; isa = PBXBuildFile; settings = { }; }; F5BE3AF6080C6A3601A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fileTable.h; refType = 4; sourceTree = ""; }; F5BE3AF7080C6A3601A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fileTable.m; refType = 4; sourceTree = ""; }; F5BE3AF8080C6A3601A80101 = { fileRef = F5BE3AF6080C6A3601A80101; isa = PBXBuildFile; settings = { }; }; F5BE3AF9080C6A3601A80101 = { fileRef = F5BE3AF7080C6A3601A80101; isa = PBXBuildFile; settings = { }; }; F5C0879F08A0C47B01A8012F = { isa = PBXFileReference; lastKnownFileType = image.tiff; path = arrow_right.tiff; refType = 4; sourceTree = ""; }; F5C087A008A0C47C01A8012F = { fileRef = F5C0879F08A0C47B01A8012F; isa = PBXBuildFile; settings = { }; }; F5C087A108A0C4AF01A8012F = { isa = PBXFileReference; lastKnownFileType = image.tiff; path = arrow_left.tiff; refType = 4; sourceTree = ""; }; F5C087A208A0C4B001A8012F = { fileRef = F5C087A108A0C4AF01A8012F; isa = PBXBuildFile; settings = { }; }; F5C84D6008142DF201A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fileElement.h; refType = 4; sourceTree = ""; }; F5C84D6108142DF201A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fileElement.m; refType = 4; sourceTree = ""; }; F5C84D6208142DF201A80101 = { fileRef = F5C84D6008142DF201A80101; isa = PBXBuildFile; settings = { }; }; F5C84D6308142DF201A80101 = { fileRef = F5C84D6108142DF201A80101; isa = PBXBuildFile; settings = { }; }; F5EFB6450818FE6001A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = client.m; refType = 4; sourceTree = ""; }; F5EFB6460818FE6001A80101 = { fileRef = F5EFB6450818FE6001A80101; isa = PBXBuildFile; settings = { }; }; F5EFB6470818FE6E01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = client.h; refType = 4; sourceTree = ""; }; F5EFB6480818FE6E01A80101 = { fileRef = F5EFB6470818FE6E01A80101; isa = PBXBuildFile; settings = { }; }; F5F5F93707FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppController.h; refType = 4; sourceTree = ""; }; F5F5F93807FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppController.m; refType = 4; sourceTree = ""; }; F5F5F93907FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftpclient.h; refType = 4; sourceTree = ""; }; F5F5F93A07FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ftpclient.m; refType = 4; sourceTree = ""; }; F5F5F93B07FD8CAD01A80101 = { fileRef = F5F5F93707FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; F5F5F93C07FD8CAD01A80101 = { fileRef = F5F5F93807FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; F5F5F93D07FD8CAD01A80101 = { fileRef = F5F5F93907FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; F5F5F93E07FD8CAD01A80101 = { fileRef = F5F5F93A07FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; }; rootObject = 29B97313FDCFA39411CA2CEA; } ftp.app-0.3/FTP.xcode/000077500000000000000000000000001177253120400144605ustar00rootroot00000000000000ftp.app-0.3/FTP.xcode/project.pbxproj000066400000000000000000000310471177253120400175410ustar00rootroot00000000000000// !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 39; objects = { 080E96DDFE201D6D7F000001 = { children = ( F5F5F93707FD8CAD01A80101, F5F5F93807FD8CAD01A80101, F5F5F93907FD8CAD01A80101, F5F5F93A07FD8CAD01A80101, F56A03FB080AC70701A80101, F56A03FD080AC71101A80101, F5BE3AF6080C6A3601A80101, F5BE3AF7080C6A3601A80101, F5C84D6008142DF201A80101, F5C84D6108142DF201A80101, F5EFB6470818FE6E01A80101, F5EFB6450818FE6001A80101, ); isa = PBXGroup; name = Classes; refType = 4; sourceTree = ""; }; 089C165CFE840E0CC02AAC07 = { children = ( 089C165DFE840E0CC02AAC07, ); isa = PBXVariantGroup; name = InfoPlist.strings; refType = 4; sourceTree = ""; }; 089C165DFE840E0CC02AAC07 = { fileEncoding = 10; isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; refType = 4; sourceTree = ""; }; //080 //081 //082 //083 //084 //100 //101 //102 //103 //104 1058C7A0FEA54F0111CA2CBB = { children = ( 1058C7A1FEA54F0111CA2CBB, ); isa = PBXGroup; name = "Linked Frameworks"; refType = 4; sourceTree = ""; }; 1058C7A1FEA54F0111CA2CBB = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; refType = 0; sourceTree = ""; }; 1058C7A2FEA54F0111CA2CBB = { children = ( 29B97325FDCFA39411CA2CEA, 29B97324FDCFA39411CA2CEA, ); isa = PBXGroup; name = "Other Frameworks"; refType = 4; sourceTree = ""; }; //100 //101 //102 //103 //104 //190 //191 //192 //193 //194 19C28FACFE9D520D11CA2CBB = { children = ( 8576CCFB152E1559008F8C62, ); isa = PBXGroup; name = Products; refType = 4; sourceTree = ""; }; //190 //191 //192 //193 //194 //290 //291 //292 //293 //294 29B97313FDCFA39411CA2CEA = { buildSettings = { }; buildStyles = ( 4A9504CCFFE6A4B311CA0CBA, 4A9504CDFFE6A4B311CA0CBA, ); hasScannedForEncodings = 1; isa = PBXProject; mainGroup = 29B97314FDCFA39411CA2CEA; projectDirPath = ""; targets = ( 8576CCE2152E1559008F8C62, ); }; 29B97314FDCFA39411CA2CEA = { children = ( 080E96DDFE201D6D7F000001, 29B97315FDCFA39411CA2CEA, 29B97317FDCFA39411CA2CEA, 29B97323FDCFA39411CA2CEA, 19C28FACFE9D520D11CA2CBB, 8576CCFA152E1559008F8C62, ); isa = PBXGroup; name = FTP; path = ""; refType = 4; sourceTree = ""; }; 29B97315FDCFA39411CA2CEA = { children = ( 29B97316FDCFA39411CA2CEA, ); isa = PBXGroup; name = "Other Sources"; path = ""; refType = 4; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; refType = 4; sourceTree = ""; }; 29B97317FDCFA39411CA2CEA = { children = ( 85FC29710DD7B28300A80101, 29B97318FDCFA39411CA2CEA, 089C165CFE840E0CC02AAC07, F5C0879F08A0C47B01A8012F, F5C087A108A0C4AF01A8012F, ); isa = PBXGroup; name = Resources; path = ""; refType = 4; sourceTree = ""; }; 29B97318FDCFA39411CA2CEA = { children = ( 29B97319FDCFA39411CA2CEA, ); isa = PBXVariantGroup; name = MainMenu.nib; path = ""; refType = 4; sourceTree = ""; }; 29B97319FDCFA39411CA2CEA = { isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; refType = 4; sourceTree = ""; }; 29B97323FDCFA39411CA2CEA = { children = ( 1058C7A0FEA54F0111CA2CBB, 1058C7A2FEA54F0111CA2CBB, ); isa = PBXGroup; name = Frameworks; path = ""; refType = 4; sourceTree = ""; }; 29B97324FDCFA39411CA2CEA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; refType = 0; sourceTree = ""; }; 29B97325FDCFA39411CA2CEA = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; refType = 0; sourceTree = ""; }; //290 //291 //292 //293 //294 //4A0 //4A1 //4A2 //4A3 //4A4 4A9504CCFFE6A4B311CA0CBA = { buildSettings = { COPY_PHASE_STRIP = NO; GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_OPTIMIZATION_LEVEL = 0; OPTIMIZATION_CFLAGS = "-O0"; ZERO_LINK = YES; }; isa = PBXBuildStyle; name = Development; }; 4A9504CDFFE6A4B311CA0CBA = { buildSettings = { COPY_PHASE_STRIP = YES; GCC_ENABLE_FIX_AND_CONTINUE = NO; ZERO_LINK = NO; }; isa = PBXBuildStyle; name = Deployment; }; //4A0 //4A1 //4A2 //4A3 //4A4 //850 //851 //852 //853 //854 8576CCE2152E1559008F8C62 = { buildPhases = ( 8576CCE3152E1559008F8C62, 8576CCEA152E1559008F8C62, 8576CCF0152E1559008F8C62, 8576CCF8152E1559008F8C62, ); buildRules = ( ); buildSettings = { FRAMEWORK_SEARCH_PATHS = ""; GCC_ENABLE_CPP_EXCEPTIONS = NO; GCC_ENABLE_CPP_RTTI = NO; GCC_ENABLE_PASCAL_STRINGS = NO; GCC_MODEL_TUNING = G3; HEADER_SEARCH_PATHS = ""; INFOPLIST_FILE = "Info-FTP.plist"; INSTALL_PATH = "$(HOME)/Applications"; LIBRARY_SEARCH_PATHS = ""; OTHER_CFLAGS = ""; OTHER_LDFLAGS = ""; PRODUCT_NAME = FTP; SECTORDER_FLAGS = ""; WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; WRAPPER_EXTENSION = app; }; dependencies = ( ); isa = PBXNativeTarget; name = FTP; productInstallPath = "$(HOME)/Applications"; productName = FTP; productReference = 8576CCFB152E1559008F8C62; productType = "com.apple.product-type.application"; }; 8576CCE3152E1559008F8C62 = { buildActionMask = 2147483647; files = ( 8576CCE4152E1559008F8C62, 8576CCE5152E1559008F8C62, 8576CCE6152E1559008F8C62, 8576CCE7152E1559008F8C62, 8576CCE8152E1559008F8C62, 8576CCE9152E1559008F8C62, ); isa = PBXHeadersBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 8576CCE4152E1559008F8C62 = { fileRef = F5F5F93707FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; 8576CCE5152E1559008F8C62 = { fileRef = F5F5F93907FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; 8576CCE6152E1559008F8C62 = { fileRef = F56A03FD080AC71101A80101; isa = PBXBuildFile; settings = { }; }; 8576CCE7152E1559008F8C62 = { fileRef = F5BE3AF6080C6A3601A80101; isa = PBXBuildFile; settings = { }; }; 8576CCE8152E1559008F8C62 = { fileRef = F5C84D6008142DF201A80101; isa = PBXBuildFile; settings = { }; }; 8576CCE9152E1559008F8C62 = { fileRef = F5EFB6470818FE6E01A80101; isa = PBXBuildFile; settings = { }; }; 8576CCEA152E1559008F8C62 = { buildActionMask = 2147483647; files = ( 8576CCEB152E1559008F8C62, 8576CCEC152E1559008F8C62, 8576CCED152E1559008F8C62, 8576CCEE152E1559008F8C62, 8576CCEF152E1559008F8C62, ); isa = PBXResourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 8576CCEB152E1559008F8C62 = { fileRef = 29B97318FDCFA39411CA2CEA; isa = PBXBuildFile; settings = { }; }; 8576CCEC152E1559008F8C62 = { fileRef = 089C165CFE840E0CC02AAC07; isa = PBXBuildFile; settings = { }; }; 8576CCED152E1559008F8C62 = { fileRef = F5C0879F08A0C47B01A8012F; isa = PBXBuildFile; settings = { }; }; 8576CCEE152E1559008F8C62 = { fileRef = F5C087A108A0C4AF01A8012F; isa = PBXBuildFile; settings = { }; }; 8576CCEF152E1559008F8C62 = { fileRef = 85FC29710DD7B28300A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF0152E1559008F8C62 = { buildActionMask = 2147483647; files = ( 8576CCF1152E1559008F8C62, 8576CCF2152E1559008F8C62, 8576CCF3152E1559008F8C62, 8576CCF4152E1559008F8C62, 8576CCF5152E1559008F8C62, 8576CCF6152E1559008F8C62, 8576CCF7152E1559008F8C62, ); isa = PBXSourcesBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 8576CCF1152E1559008F8C62 = { fileRef = 29B97316FDCFA39411CA2CEA; isa = PBXBuildFile; settings = { ATTRIBUTES = ( ); }; }; 8576CCF2152E1559008F8C62 = { fileRef = F5F5F93807FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF3152E1559008F8C62 = { fileRef = F5F5F93A07FD8CAD01A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF4152E1559008F8C62 = { fileRef = F56A03FB080AC70701A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF5152E1559008F8C62 = { fileRef = F5BE3AF7080C6A3601A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF6152E1559008F8C62 = { fileRef = F5C84D6108142DF201A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF7152E1559008F8C62 = { fileRef = F5EFB6450818FE6001A80101; isa = PBXBuildFile; settings = { }; }; 8576CCF8152E1559008F8C62 = { buildActionMask = 2147483647; files = ( 8576CCF9152E1559008F8C62, ); isa = PBXFrameworksBuildPhase; runOnlyForDeploymentPostprocessing = 0; }; 8576CCF9152E1559008F8C62 = { fileRef = 1058C7A1FEA54F0111CA2CBB; isa = PBXBuildFile; settings = { }; }; 8576CCFA152E1559008F8C62 = { isa = PBXFileReference; lastKnownFileType = text.xml; path = "Info-FTP.plist"; refType = 4; sourceTree = ""; }; 8576CCFB152E1559008F8C62 = { explicitFileType = wrapper.application; includeInIndex = 0; isa = PBXFileReference; path = FTP.app; refType = 3; sourceTree = BUILT_PRODUCTS_DIR; }; 85FC29710DD7B28300A80101 = { isa = PBXFileReference; lastKnownFileType = image.icns; path = FTP_icon_osx.icns; refType = 4; sourceTree = ""; }; //850 //851 //852 //853 //854 //F50 //F51 //F52 //F53 //F54 F56A03FB080AC70701A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = localclient.m; refType = 4; sourceTree = ""; }; F56A03FD080AC71101A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = localclient.h; refType = 4; sourceTree = ""; }; F5BE3AF6080C6A3601A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fileTable.h; refType = 4; sourceTree = ""; }; F5BE3AF7080C6A3601A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fileTable.m; refType = 4; sourceTree = ""; }; F5C0879F08A0C47B01A8012F = { isa = PBXFileReference; lastKnownFileType = image.tiff; path = arrow_right.tiff; refType = 4; sourceTree = ""; }; F5C087A108A0C4AF01A8012F = { isa = PBXFileReference; lastKnownFileType = image.tiff; path = arrow_left.tiff; refType = 4; sourceTree = ""; }; F5C84D6008142DF201A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = fileElement.h; refType = 4; sourceTree = ""; }; F5C84D6108142DF201A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = fileElement.m; refType = 4; sourceTree = ""; }; F5EFB6450818FE6001A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = client.m; refType = 4; sourceTree = ""; }; F5EFB6470818FE6E01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = client.h; refType = 4; sourceTree = ""; }; F5F5F93707FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppController.h; refType = 4; sourceTree = ""; }; F5F5F93807FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppController.m; refType = 4; sourceTree = ""; }; F5F5F93907FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ftpclient.h; refType = 4; sourceTree = ""; }; F5F5F93A07FD8CAD01A80101 = { fileEncoding = 30; isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ftpclient.m; refType = 4; sourceTree = ""; }; }; rootObject = 29B97313FDCFA39411CA2CEA; } ftp.app-0.3/FTPInfo.plist000066400000000000000000000010131177253120400152430ustar00rootroot00000000000000{ ApplicationDescription = "FTP client"; ApplicationIcon = "FTP_icon_gs.tif"; ApplicationName = FTP; ApplicationRelease = "0.3"; Authors = ( "Riccardo Mottola " ); Copyright = "Copyright (C) 2005-2012"; CopyrightDescription = "Released under GPL"; FullVersionID = "0.3"; NSExecutable = FTP; NSIcon = "FTP_icon_gs.tif"; NSMainNibFile = "FTP.gorm"; NSPrincipalClass = NSApplication; NSRole = Application; URL = "http://savannah.nongnu/project/gap/"; } ftp.app-0.3/FTP_icon_osx.icns000066400000000000000000001432301177253120400161410ustar00rootroot00000000000000icnsƘich#H\@????????????????G?\@????????????????G?ih32½]uDz}zqspyK١p˨ɯ˓׌Ρ꠩є{^쳮彠엾ѓjήˊķՓyאǤ}v˓qуාnwё󌷱ϷŠmqhҹŠTE]I۾ٯȋ!ʊʋؽɸǵ⿳ŸͻɛIJګ̰αȱ˿ݭج˵л¯z!|qnh{Ĺt!}_t}z|mٷح͹x"twơνܶȱ}#}ڳϞ۱ΪدŹ|#p~νq\dmܯ̼Ծ߳z#ppŲQ@JHKayډ۟ϻڢ~#˭{fCގcҪ#t˲~xtFFiљ!nxsYEE á͏]qĥPb:Q)̣z޹9e.N |۷JlCg1/~ݹ_o'C@՝ⴸdj.34#ߝy㼿ol *=|ea2&(ߝqƳj.56㺪S9CDGÒƍgf:TYϝțuLt۝̜el| qظt\s ¤׿Qn׻~trik[q5ҋVǤް㡛伓̅ǛߊÓtyU⫫府“pށfͫɆðۆǐxs֍Š{xppջzn״hrvÐ3Ҿδ~د"bfh\}δۅҰ"H5O=ܓѩ"оvJKanƴ"ݫzVHGT`\z~lfccyξƵ"pzeliƳ"ź"ֵױÿς֚İܚپע;؂ΟӽŢĥνѡϞۺۥ¿t郃Ҷŭ֘˻i!uԏwwӽصףĶd!oʽМrѬÚg"ϼϽŲ̥n#zŁզĝǝk#h͸֥ٽ°̳ӣk#iƦxQf{֔ӑƯ͎n#˰فVܬ#÷^¶~!ӻOʰ؍ʢĿ̿ۏūѴ՝չҼ͸Ʒɮʶ߽ɥݝĴ k׻s ¤ֿLzȲyulmgwCrڕطڪדل͙ƮxQ⶙~cʨĂqҊʝwtnvm|{贇eoj 򅰬лͲ"[>34jE)biaͳ"Wn`wvTwJϿ=Ȱ{ʷYg<y׿jiyN̼@ם̨ywQAƵŻZCüǺ_DųzzƾpC{Ѵ}ŹCיȦˏɸDҐ̲ȦʚиDʓҬuyدȧѢҸDƈƃuvҙ}᫔ƹƤЪɸDq}Xͬ쨀Ҕֱ̤ѫոEr{^|뷮ԓֽӨѲD~tћ^}lǧܱϡѷ׸Dи|ץӵjYsĻИңּ׸DݳǞoÉZzŎ쫑yĺۥջָDݶ๓g˦^n毠ڶ|apʡާȽԭD״ൕaբqͻךԩӏsrogo⮈خDݲ礁j٣אӟturw^|ȹ殉ޮDתܕynwurľ͍ժyyuU[ruxé筊ʺDѭ֔vmў|޹շ{nntwؿ䫍ѽҮEڱޓyxǏķqv֕׿¨ܧ߱νӭDܬȊb᭛ɬεڹЎ⹜ɮK䩥{lҔŭ·뿽⾔J帧{l⊮»ެ濕ƺ̟I氬ȥmkֵz{Ӻǝ˟Hncg]c]Qbd`нٟ̚GҖrvrryyhXNVJZwBmʹèӨF깬߰mTrL>U]wI.Ѽҫ¾8W^@,+25:93^ҨƻՠF~nOJT]focrүݠG̯ݟGΪH沫̫ʺݠ݀2ƤIƤ 彫߀ ↓DҮʿܟDŹѯD곜ƽþ鮮D侮лŭݠD俳ʻߺϽ ݲϳ~4~xwi׹ʷϵߠD컬⽜{pŭwۻ˻һD龧㿪Ĵյ䰤avֳмԚDðޮӷѴóɻbrѲĭȵDʨإָٵ¢μر`uǭŲDȦӓ§d~òÿڛDɣύղ﷩ŸթkƪěD֮ӗ˻ݯжո|ŨӻïМCպٛշҴ~̺|C̞нα־ϡַ담äŻƿzCʥٶ阸乨͹½z̞Lϰɽ¤Ѵᓹ⾯űĶzVûָΧĪݵ՚뽧Ŀÿx\ݹ{rxjvniehnw޻Ϫ֥˺Ķt[Ɨtq_eX^gcpr}}{iac̭زխæ͹oZ٣}f^Takfiriqgatusi]ȸټѽ׹ĭ{С[᷎jV\QhyocjһӨɟطưt]ŏ\Wfi|ĺ~ڴмҸпۯʹs̞^f[t}qw»Ƽ׵нǩҲܰѾ}ԝ_ܔ`wt}¿µƻҲϭ׳Ծֲͼʹ`hyڿũ¤ƴӽ̚ȝֺǽ¶}a}ۿïȚʽ԰֣ɾطĹ|̛anʴŽb`w̛Șʺ˵޵ĩabjɽlONxvx˓̧ɝɽഫķ|_csp½u}YbdLMOahZOfȕᰳ̡ǯκ߳w_ڒklrvDZykYOBBQgEG=CGDo֠䷚Ęճɼοٹz˝-ro|pvIJ}oQ?B@DLHMH<;KNba`yԀ.—zⴑȫ⼿޽ڽ}ԝ_Аwɮwqw}~oaif`XD.<77B=4MPK\dvryRxϤq؍ȶܼǷຸส˝_݉ƱzonLUepxs[fW~bquW[ݧtsѾʦռ״̝ ⍒̀Qݸro]ACsoUqžٰɼҵ̝_ӏwڤz{fF4Bu{U]ٹعY{՝_ӑwtοտs{x}dGC@J{b]׮ջdOߝ]גynʿĦttunk[:PcCyeͿùq^\ܗxd߿ƸsjnbUXY0N^*;J0'@*缢qµxwh]xa2276DD+A*~sоtopeHr]'A2.<48,D*ܴtҷepNug2B=&X49ª*غpmú~vhVp\8?4#EB$*=W*ٺmoŴ}jao\)C-J@+0-HOj=˶໓״ߠ\?ݱ̬ԄKP1"$*(#R޼xӸР2R䋙ڠڜt`B?KRZcUi޼zǷՠ\&evۧ]UJEDKL^dlnɽӟ]/[D痄z~t}zxnjrn{~ηȺߟ]'ϲSJޝwoQILIFO\b`iekmTpwxuy|xswyxe_`gj|ɷР0޸O׈I櫚ĦZHFEL?ALHRVZden||nvn\]Q\UNUjfqt~ؽƳ7uOawyy}ʫӹDz՟:SpDݯzzsmmx{{|re_nkcilpԤ¾ƳП PQ읋D㶏zymlfkh_^_hN@DHONP[gq~ĺ̸؟ ^G͘ւDۡ{w|vzxpnmdTQS\\[[VSV[]^bhhszܻ˹П ǁ=Dؚþێкڽʬ̠ÚMD߱ҦѾIJʱ̠ǢZӂƅDݲͻ͡տǩ͠׫~ɌDݤʽuorqr{xп˳wqkl_ġɾҾƠߠޯȒ݀D⭛خjbqrs|ȻnʣϻϿ˧ ʝD߱ڳ̧ޢ¹۾ޕWjӾλǧԚȯD䵠ՠɩȨ˹ؼᾮXh⻘D˖ΫЩް۷įФUk岓³ηĻDǃ׬޶οȴҷ[t㬛־ʼțǣ߉D|߶Υ꫚еԺ̛b⮐ƶкěԜD̚ˈ٩ՠŻƪˬtܭɽʹ}М񼅵CɧΊ߽ͬɨзʹ޷wڨĹŲi酃Cܭٽ߰ȱģβƓΩ焬ߪƸg̝ QCÿоȸ׶̿Щ׺台֞˴Ǵi̞ ꊷW`܃IŤ׸ǿҶȨۊԤǾg^8õϭϺѻĿĘת͑এʼe\uJ}å~wwvux߸ĿҾپدǟ͜תɾc[ӆĤ{k`_|ͻҺáХ̢Эò^ZФsovƵʴ}fW̹ѾбDZ ŹjС[ڷU_wźgfȭɽ˚úɵğµe]Ō\f˿ҥǰɬ̶ƴ˖c̞^afŲѩ÷Dzɦ˵̖ųnԝ_ߕ^뼩港ɥƠϦ̳|v`dϺֺ׺˰Ƚִ¥kݛayž٬ҿˢ͕⿱ǣl̛aiǪƹÐ罺ž߿ѠrZiGÿħ|qÇݨ˜޷̾ӟm_w]szƼwb`pῊբÒŮҞg_ډ|vξlZFIVi͒{جۻͧIJʧjĝ_}inqfQGPftǒӶo֦}ӻ۰֯ͬm͝_ʇȯxntzzk`rz}ylX`]VQKJ`szŕe}{亨Աڬզŝ_݂ҺztrWeuǶͼטi؆bǰα䳮ǜƝ_↯˾dHdУƝ_ӉԼ¸qIOѬصɡNpѝ_Ѝ˽ֹXOРƤZCڝ]ՐȿvYֻjP\ܓƺ;fƶϹYSvZ٘üƼ̲ڿ*໠wXOXۓÿvvyտcJyWԕ¾˾ڴﯡ}z۪UטİڴSҕֿөPҐijǸĬPϕ÷zՓr֙Bž}Ӛxvs{¾ҹǽЯ0ϛŽ|Ķ*؜;­ ڎƾ*ؕκ*ϙ{*ŷ*ȿ*©̿**縧ƾ~*Ͽ*ծʸrƪ*д¼*ԴǺ*ճȼ*Ӳĩ*ݮ§*ٱ˼â*۳ʮ*ҵs*ݹֽo*ϵůǴŤi*ؾ½ʻDZt*Žȥ(Ԯû|'ஔþqv%Śoi{ϼrU#ǓkPWXP ˢq^glϽgb~߁ѻ{zisؽuqnkgrhgfqjt̿»ֶǿ ˧{r{߀ƼҼ4Қ_AP]PP[MYɭpkfbWX[Ra{~5٨L0PzѾrxzvuqlluwbhg8d7mvȍe`MS?| Ҷ#Lj`_wOֶ~wԚZCp2~wɲyQh1xt`iE@͕ܭ|{JAҕSCغ^DʾҴvCzׄڹCߜڽיܸDɫӶڥݖФly~qҀ$ة˧܍xjynϔv⥋DՊdyN}ŤxӋ~ѪġՌgxտQz殨|&ՊжϾDՉtnˑTtgÿ㍘اɸеDЃ؟xϫ^Onóɒ~ʼζḊƔhҽ}QtʼŇ硊q÷DΎ괊`ǚRhĽ쪚ԭzsYjś̿úDΐ㭍ZДh}ɶӑ֤υiif]h|ѼD̍zdԗ½҇ЗjmimSuóмĄDNjٍuhnlkƇңpokKQilpϾļuu=ʐԋqiʕt{۰Ӵrfel|o~չrPJ>̣݊qvнgnѐֺϼ؞gf)<Dɶyx~ϹYޥǥɯֲȈN]wS 4ǽry̿a͎Ĩ绲鷹0ʣûBfkA:q{c܀أ]}[C-&&*-96Rm2fɰ]:Wvnba^jwnwv[MjegKbJkE2KTo:ϹA0Ykvtv}cSe\pZNT3!"$%,*#U\'Ys}qmwwijwnpeWXgo|~>WwgHDQW^h^m\TygirjidkqrtfHfq?.f۰vsu~1%co}eR\XY]ebEdr6Bˀ(Ͼ]|WltjqܯyJgK 8ϼŷ}$^gobayOկ}Pq^*ύƼ&alo`WaO̱ZU4"bjsbPDå[E׀DļȻþø 1_ll_S9ʕ_.ZDþ 4XmejP(aMD QaugaFDYguuU<*زلځ4UsqhWD8ςƅDϺXuy[WHZɌDӭ|weߠVjn_UL`ǀD׽˿Șu Vpn[`[n݊D]zԚ̞ϧcqxdpt݈D^s̝~fr}oz|}̈D\v۽lqvwt~{eՈ߀=aǶTwjnsvrhDgכ[L]^|xtMDyѽт=N`mr{sfBMӋC}غ ц,LOitwp`U*wCվ `#C^tcV\H9C .5k|fVMi܃Dϻ^׉,`sh=6̴̼~\h2xQ:ƭ|vyƹy[oJ~qȧƽrea~ĶxZkvwɥhXƾС ڷUcMɚpgھ| É[nEѱ~ƶy_m4ӟ׀_]ڪųaKΜ̼µ |S֯ª mK̛ܫǭ]l߀0vݥҀú_{^uкej|ۨӹ{ϝ_ڋxɶgKNbќ깗̷۝-}glȴyYPb~ߕ.ǼѪ_ʋǮwmry{lbxqvshYTVmܚz晴׷˷ٝ_݆ս|wu_n|ך͂񒉯յ̼ݝމWҒ}\wɱ۝ ЍPӌӆV`ֳՙY АP։ٗfaӾrQ ՒOڒәcѹg וJՈԭoٯ̹Ƴ}hZ֚҃û̟̯ͨzjXٕЇؐ̚fWԖɎɳUי̏?Ӗʐ#ՒπDž!PҘɃ痏 כ?€欑0ҜҾ~ٝ׾ ސӹ ؗд*Ϛϳ~̀Ѷžӹ ëζϰ繫ϫ$Ԁ*կѝĪԵ֫*ֵԮ*ճد*ղڮޯ߷ ۲޽۳ sݸހpϴj*ؼx*֮ⷡؤ ౕ޹}vˤrhz϶}Y#ɕkOTͬWP ͢q]dlfa|߁ѽzyhr~ؽromkgqhfepgr̿ſÿֶt8mk@ " *-,-% ) wtGAMTbo_\٬g&v'" *c N$ *- W M) .x'[p]u~mUK0M OH&;#]Ixt5C  3j7ySz]Մ8b-fqX!/] ӕ)ֲko#Ӿxzu9 @:.  8Z 4)  w+vm+-%HV_5u;Oa@q.q-+.u6!]!2K }O+)2y* 'Bu֟E+P}ɉw`6ftp.app-0.3/GNUmakefile000066400000000000000000000020141177253120400147750ustar00rootroot00000000000000# # GNUmakefile - Generated by ProjectCenter # ifeq ($(GNUSTEP_MAKEFILES),) GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null) endif ifeq ($(GNUSTEP_MAKEFILES),) $(error You need to set GNUSTEP_MAKEFILES before compiling!) endif include $(GNUSTEP_MAKEFILES)/common.make # # Application # VERSION = 0.3 PACKAGE_NAME = FTP APP_NAME = FTP FTP_APPLICATION_ICON = FTP_icon_gs.tif # # Resource files # FTP_RESOURCE_FILES = \ Resources/FTP.gorm \ Resources/arrow_left.tiff \ Resources/arrow_right.tiff \ Resources/FTP_icon_gs.tif # # Header files # FTP_HEADER_FILES = \ AppController.h \ ftpclient.h \ localclient.h \ fileTable.h \ fileElement.h \ client.h # # Class files # FTP_OBJC_FILES = \ AppController.m \ ftpclient.m \ localclient.m \ fileTable.m \ fileElement.m \ client.m # # Other sources # FTP_OBJC_FILES += \ main.m # # Makefiles # -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/aggregate.make include $(GNUSTEP_MAKEFILES)/application.make -include GNUmakefile.postamble ftp.app-0.3/GNUmakefile.preamble000066400000000000000000000010701177253120400165640ustar00rootroot00000000000000# # GNUmakefile.preamble - Generated by ProjectCenter # # Additional flags to pass to the preprocessor ADDITIONAL_CPPFLAGS += # Additional flags to pass to Objective C compiler ADDITIONAL_OBJCFLAGS += # Additional flags to pass to C compiler ADDITIONAL_CFLAGS += # Additional flags to pass to the linker ADDITIONAL_LDFLAGS += # Additional include directories the compiler should search ADDITIONAL_INCLUDE_DIRS += # Additional library directories the linker should search ADDITIONAL_LIB_DIRS += # Additional GUI libraries to link ADDITIONAL_GUI_LIBS += ftp.app-0.3/Info-FTP.plist000066400000000000000000000013131177253120400153230ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleExecutable FTP CFBundleIconFile FTP_icon_osx.icns CFBundleInfoDictionaryVersion 6.0 CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion 0.3 NSMainNibFile MainMenu NSPrincipalClass NSApplication ftp.app-0.3/README000066400000000000000000000001731177253120400136070ustar00rootroot00000000000000NOTES To compile on windows, please add the following to your GNUmakefile.preamble ADDITIONAL_GUI_LIBS += -lwinmm ftp.app-0.3/Resources/000077500000000000000000000000001177253120400147005ustar00rootroot00000000000000ftp.app-0.3/Resources/FTP.gorm/000077500000000000000000000000001177253120400162745ustar00rootroot00000000000000ftp.app-0.3/Resources/FTP.gorm/arrow_left.tiff000066400000000000000000000021161177253120400213120ustar00rootroot00000000000000MM*     t(R/---ҮQwLLLiii cccLLL <"""j<""" cccLLL jjj vLLL/---ҮQ ftp.app-0.3/Resources/FTP.gorm/arrow_right.tiff000066400000000000000000000021161177253120400214750ustar00rootroot00000000000000MM*     t(RQ---/LLLw iii LLLccc """<j"""< LLLccc jjjLLLvQ---/ ftp.app-0.3/Resources/FTP.gorm/data.classes000066400000000000000000000025561177253120400205740ustar00rootroot00000000000000{ "## Comment" = "Do NOT change this file, Gorm maintains it"; AppController = { Actions = ( "changePathFromMenu:", "listDoubleClick:", "downloadButton:", "uploadButton:", "localDelete:", "remoteDelete:", "disconnect:", "showPrefPanel:", "prefSave:", "prefCancel:", "showFtpLog:", "setServer:", "showConnPanel:", "connectConn:", "cancelConn:", "anonymousConn:" ); Outlets = ( mainWin, localView, remoteView, localPath, remotePath, buttDownload, buttUpload, infoMessage, infoSpeed, infoSize, progBar, logWin, logTextField, connectPanel, connAddress, connPort, connUser, connPass, connAnon, prefPanel, portType ); Super = NSObject; }; FirstResponder = { Actions = ( "anonymousConn:", "appendTextToLog:", "cancelConn:", "changePathFromMenu:", "connectConn:", "disconnect:", "downloadButton:", "listDoubleClick:", "localDelete:", "orderFrontFontPanel:", "prefCancel:", "prefSave:", "remoteDelete:", "setServer:", "showConnPanel:", "showFtpLog:", "showPrefPanel:", "uploadButton:" ); Super = NSObject; }; fileTransmitParms = { Actions = ( ); Outlets = ( ); Super = NSObject; }; }ftp.app-0.3/Resources/FTP.gorm/data.info000066400000000000000000000002701177253120400200610ustar00rootroot00000000000000GNUstep archive00002f45:00000003:00000003:00000000:01GormFilePrefsManager1NSObject% 01NSString&%Latest Version0& % Typed Streamftp.app-0.3/Resources/FTP.gorm/objects.gorm000066400000000000000000001032451177253120400206200ustar00rootroot00000000000000GNUstep archive00002f45:00000035:0000039a:00000001:01GSNibContainer1NSObject01 NSMutableSet1NSSet&01NSMenu01NSString&%FTP01NSMutableArray1NSArray&01 NSMenuItem0&%Info0&&&%0 1 NSImage0 1 NSMutableString&%common_2DCheckMark0 0 & % common_2DDash2 submenuAction:v12@0:4@8%0 0&0 0& % Info Panel...0&&&% %0 0&%Preferences...0&&&% %0 0&%Help...0&%?&&% %0 0& % Connection0&&&% %00&0 0& % Connect...0&&&% %0 0!& % Disconnect0"&&&% %0# 0$&%Show Log0%&&&% %0& 0'&%Local0(&&&% %0)'0*&0+ 0,&%Delete0-&&&% %0. 0/&%Remote00&&&% %01/02&03 04&%Delete05&&&% %06 07&%Windows08&&&% %0970:&0; 0<&%Arrange In Front0=&&&% %0> 0?&%Miniaturize Window0@&%m&&% %0A 0B& % Close Window0C&%w&&% %0D 0E&%Services0F&&&% %0GE0H&0I 0J&%Hide0K&%h&&% %0L 0M&%Quit0N&%q&&% %0O1 GSNibItem0P& % AppController  &0Q1 GSWindowTemplate1GSClassSwapper0R&%NSWindow1NSWindow1 NSResponder% ? A C C*&% C C0S1NSView% ? A C C*  C C*&0T&0U1 NSScrollView%  C C*  C C*&0V&0W1 NSClipView% A @ C̀ C& A @ C̀ C&&0X&0Y1 NSTextView1NSText% A @ C̀   C̀ &0Z&0[1NSColor0\&%NSNamedColorSpace0]&%System0^&%textBackgroundColor  K K0_\]0`& % textColor C̀ K[0a1 NSScroller1 NSControl% @ @ A C&  A C&&0b&%0c1NSCell0d&0e1NSFont%&&&&&&&&&&&&&&&W% A A A A a0f\0g&%System0h&%windowBackgroundColor0i&%Window0j&%Connection Logj ? ? F@ F@%&  D D0k 0l&%NSPanel1NSPanel% ? A C C[&% C D0m% ? A C C[  C C[&0n&0o1NSButton% CJ A B A  B A&0p&%0q1 NSButtonCell1 NSActionCell0r&%Connecte&&&&&&&&&&&&&&%0s&0t&&&& &&0u% C A B` A  B` A&0v&%0w0x&%Cancele&&&&&&&&&&&&&&%0y&0z&&&& &&0{1NSBox% A0 B4 C B  C B&0|&0}% @ @ Cv B  Cv B&0~&01 NSTextField% B A C( A  C( A&0&%01!NSTextFieldCell0&%joee&&&&&&&& &&&&&&%[_01"GSControlTemplate0&%NSSecureTextField % B @ C( A  C( A&0&%01#NSSecureTextFieldCell0&e&&&&&&&& &&&&&&%[_0% A B B A  B A&0&%00& % Anonymous0 0 &%common_SwitchOffe&&&&&&&&&&&&&&%0&0&0 0 &%common_SwitchOn&&& &&0 % A B A  B A&0&%0!0&%Username0% A@&&&&&&&& &&&&&&%[_0 % @ B A  B A&0&%0!0&%Password&&&&&&&& &&&&&&%[_00&%Accounte&&&&&&&&&&&&&& @ @%%0% A0 C C BH  C BH&0&0% @h @ Cup A  Cup A&0&0 % C?  B[e A  B[e A&0&%0!0&%21e&&&&&&&& &&&&&&%[_0 %  C0 A  C0 A&0&%0!0& % localhoste&&&&&&&& &&&&&&%[_0 % C5 @@ @ A  @ A&0&%0!0&%:&&&&&&&& &&&&&&%[_00&%Server Address and Porte&&&&&&&&&&&&&& @h @%%fi0&%Connect ? ? F@ F@%&  D D0 R% ? A C C&% CS D@0% ? A C C  C C&0&0% A0 B C5 C^  C5 C^&0&0% A A C C1  C C1&0&01$ NSTableView%  C) C!  C) C!&0&%00&e&&&&&&&&&&&&&&0&01% NSTableColumn0&%filename C) A GP01&NSTableHeaderCell0&%Name0% &&&&&&&& &&&&&&%0\g0±&%controlShadowColor0ñ\g0ı&%windowFrameTextColor0ű!0Ʊ&%ninee&&&&&&&& &&&&&&%[_0DZ\g0ȱ& % gridColor0ɱ\g0ʱ&%controlBackgroundColor01'NSTableHeaderView%  C) A  C) A&0̱&01(GSTableCornerView% @ @ A A  A A&0α&%% A @ @@0ϱ% @ A A CD  A CD&0б&%0ѱe&&&&&&&&&&&&&&&0ұ% A @ C A  C A&0ӱ&0Ա\g0ձ& % controlColor0ֱ% A CJ C A  C A&0ױ&%0ر0ٱ&e&&&&&&&&&&&&&&&Ͱ% A A A A 0ڱ% C B C5 C]  C5 C]&0۱&0ܱ% A A C C0  C C0&0ݱ&0ޱ$%  C) C!  C) C!&0߱&%00&e&&&&&&&&&&&&&&0&0%0&%filename C) A GP0&0&%Name&&&&&&&& &&&&&&%0!Ɛe&&&&&&&& &&&&&&%[_ǰ0'%  C) A  C) A&0&0(% @ @ A A  A A&0&%% A @ @@0% @ A A CC  A CC&0&%0ᐰe&&&&&&&&&&&&&&&0% A @ C A  C A&0&0% A CI C A  C A&0&%0ِe&&&&&&&&&&&&&&&% A A A A 0% CQ Cg B B  B B&-0&%00&%->0  A AP00&%NSCalibratedWhiteColorSpace 0&01)NSBitmapImageRep1* NSImageRep0&%NSDeviceRGBColorSpace A AP%%% 01+NSData&II*|777Q%%%&&&/555???w >>> 555=== ...<>>>j...< 555===  >>>555???v777Q%%%&&&/   tRe&&&&&&&&&&&&&&%0&P&&&& &&P1, NSPopUpButton% A C C* A  C* A&P&%P1-NSPopUpButtonCell1.NSMenuItemCellP&e&&&&&&&&PP&P&P P &%Item 1P &&&%P P &%common_3DArrowDown%P P&%Item 2 &&%%P P&%Item 3 &&%%&&&&&&%P&P&&&& &&%%%%%P,% C C C* A  C* A& P&%P-P&e&&&&&&&&PP&P&P P& % remote viewP&&&% %&&&&&&%P&P&&&& &&%%%%%P% CQ C0 B B  B B&-P &%P!P"&%<-P#  A APP$&P%) A AP%%% P&+&II*|&&&/%%%777Q???w555>>>  ===555 ...<>>>j...< ===555 >>>  ???v555&&&/%%%777Q  tRe&&&&&&&&&&&&&&%P'&P(&&&& &&P)% A0 A  C B  C B&P*&P+% @ @ C BT  C BT&P,&P- % B C A  C A&P.&%P/!P0&e0&&&&&&&& &&&&&&%[_P1 % C B C A  C A&P2&%P3!P4&e4&&&&&&&& &&&&&&%[_P51/NSProgressIndicator%  C> A  C> A&P6& ?UUUUUU @I @YP7 % Cf  C> A  C> A&P8&%P9!P:&e:&&&&&&&& &&&&&&%[_P;P<&%Titlee&&&&&&&&&&&&&& @ @%%fiP=&%FTP= ? ? F@ F@%&  D DP> l% ? A C C*& % C D"@P?% ? A C C*  C C*&P@&PA% A B8 Ce B  Ce B&PB&PC% @ @ CW B  CW B&PD&PE10NSMatrix% A @ C5 B  C5 B&PF&%PGPH&e&&&&&&&&&&&&&&%% C5 A ɰPI& % NSButtonCellPJPK&%RadioPL PM &%common_RadioOffe&&&&&&&&&&&&&&%PN&PO&PP PQ &%common_RadioOn&&& &&%%PR&PSPT& % default portsLe&&&&&&&&&&&&&&%NPU&P&&& &&PVPW&%client arbitrates (PORT)Le&&&&&&&&&&&&&&%NPX&P&&& &&PYPZ&%server arbitrates (PASV)Le&&&&&&&&&&&&&&%NP[&P&&& &&SP\P]&%Data Connection Managmente&&&&&&&&&&&&&& @ @%%P^% C7 A  B` A  B` A&P_&%P`Pa&%Savee&&&&&&&&&&&&&&%Pb&Pc&&&& &&Pd% B A  B` A  B` A&Pe&%PfPg&%Cancele&&&&&&&&&&&&&&%Ph&Pi&&&& &&fPj&%WindowPk& % Preferencesk @@ B F@ F@%&  D DPl&Pm&Pn11NSMutableDictionary12 NSDictionary&KPo& % MenuItem33Pp& % ScrollView1Pq& % MenuItem34Pr& % ScrollView2UPs& % MenuItem35Pt& % MenuItem36Pu& % Scroller(4)Pv& % MenuItem37Pw&%NSServicesMenuGPx& % MenuItem110.Py& % MenuItem38 Pz& % MenuItem1113P{& % MenuItem39#P|& % MenuItem1126P}& % MenuItem113;P~& % MenuItem114>P& % MenuItem115AP& % MenuItem(33).P& % MenuItem116DP& % MenuItem117IP&%Menu(12) P& % MenuItem118LP& % MenuItem119P& % MenuItem(22)6P&%TableCornerView(1)P&%Menu(6) P&%TableHeaderView(0)P& % ClipView(0)WP& % MenuItem(11)AP&%View(1)CP& % MenuItem406P& % MenuItem41;P& % MenuItem(2)P& % MenuItem42>P& % MenuItem43AP& % MenuItem44DP& % MenuItem45IP& % MenuItem46LP& % MenuItem476P& % MenuItem120P& % MenuItem48;P& % MenuItem121P& % MenuItem49>P& % MenuItem122#P& % MenuItem123&P& % MenuItem124+P& % MenuItem125.P& % MenuItem(34)3P& % MenuItem1263P& % MenuItem1276P&%Menu(13)P& % MenuItem128;P& % MenuItem129>P& % NSWindowsMenu9P& % MenuItem(23);P&%Menu(7)P&%TableHeaderView(1)P& % ClipView(1)P&%ButtonP& % MenuItem(12)DP&%View(2)+P& % MenuItem50AP& % MenuItem51DP& % MenuItem(3)#P& % MenuItem52IP& % MenuItem53LP& % MenuItem546P& % MenuItem55;P& % MenuItem56>P& % MenuItem57AP& % MenuItem130AP& % MenuItem58DP& % MenuItem131DP& % MenuItem59IP& % MenuItem132LP& % MenuItem133P& % MenuItem134P& % MenuItem135P& % MenuItem(35)6P& % MenuItem136#P& % MenuItem137&P&%Menu(14))P& % MenuItem138+P±& % MenuItem139.Pñ& % MenuItem(24)>Pı&%GormNSTableView1Pű&%Menu(8))PƱ& % ClipView(2)PDZ& % MenuItem(13)LPȱ& % GormNSMenu1GPɱ& % GormNSMenu29Pʱ& % MenuItem60LP˱& % GormNSMenu3 P̱& % MenuItem616Pͱ& % GormNSMenu4Pα& % MenuItem(4)&Pϱ& % MenuItem62;Pб& % GormNSMenu51Pѱ& % MenuItem63>Pұ& % GormNSMenu6)Pӱ& % MenuItem64APԱ& % GormNSMenu7 Pձ& % MenuItem65DPֱ& % GormNSMenu8Pױ& % MenuItem66IPر& % GormNSMenu9)Pٱ& % MenuItem67.Pڱ& % MenuItem1403P۱& % MenuItem683Pܱ& % MenuItem1416Pݱ& % MenuItem69&Pޱ& % MenuItem142;P߱& % MenuItem143>P& % MenuItem144AP& % MenuItem145DP&%ViewP& % MenuItem(36);P& % MenuItem146LP& % MenuItem147P&%Menu(15)1P& % MenuItem148P& % MenuItem149P& % MenuItem(25)AP& % ClipView(3)P&%Menu(9)1P& % MenuItem(14)P&%GormNSTableViewP& % MenuItem70+P& % MenuItem71P& % MenuItem(5)+P& % MenuItem72&P& % MenuItem73+P& % MenuItem74.P& % MenuItem753P& % MenuItem766P& % MenuItem77;P& % MenuItem78>P& % MenuItem150#P& % MenuItem79AP& % MenuItem151&P&%GormNSPopUpButton1P& % MenuItem152+P& % MenuItem153.P& % MenuItem1543P& % MenuItem(37)>P& % MenuItem1556P& % MenuItem156;P& % MenuItem157>P&%Menu(16)9P& % MenuItem158AP& % MenuItem159DP& % MenuItem(26)DP&%MatrixEP& % ClipView(4)P & % MenuItem(15)P & % GormNSMenu P & % GormNSWindow1QP & % MenuItem80DP & % MenuItem81IP& % MenuItem82LP& % MenuItem(6).P& % MenuItem83P& % MenuItem84&P& % GormNSMenu101P& % MenuItem85+P& % GormNSMenu119P& % MenuItem86.P&%Button1oP& % GormNSMenu12GP& % MenuItem873P&%Button2uP& % GormNSMenu13 P& % MenuItem886P&%Button3P& % MenuItem160LP& % GormNSMenu14P& % MenuItem89;P &%Button4P!& % GormNSMenu15)P"&%Button5^P#& % GormNSMenu161P$&%Button6dP%& % GormNSMenu179P&& % GormNSMenu18GP'& % MenuItem(38)AP(& % GormNSMenu19 P)&%Menu(17)GP*& % MenuItem(27)LP+& % MenuItem(16)P,& % MenuItem90>P-& % MenuItem91AP.& % MenuItem92DP/&%NSOwnerP0& % NSApplicationP1& % MenuItem(7)3P2& % MenuItem93IP3& % MenuItem94LP4& % MenuItem95P5& % GormNSMenu20P6& % MenuItem96&P7& % GormNSMenu21)P8& % MenuItem97+P9& % GormNSMenu221P:& % MenuItem98.P;&%Menu(0) P<& % GormNSMenu239P=& % MenuItem993P>& % GormNSMenu24GP?& % GormNSMenu25 P@& % GormNSMenu26PA& % GormNSMenu27)PB& % MenuItem(39)DPC& % GormNSMenu281PD& % GormNSMenu299PE&%NSMenuPF& % TextField107PG& % MenuItem(28)PH& % MenuItem(17)#PI& % MenuItem(8)6PJ& % TableColumnPK& % GormNSMenu30GPL& % GormNSMenu31 PM& % GormNSMenu32PN&%Menu(1)PO&%Box1APP& % GormNSMenu33)PQ&%Box2)PR& % ScrollViewPS& % GormNSMenu341PT&%Box3PU& % GormNSMenu359PV&%TextViewYPW& % GormNSMenu36GPX& % GormNSMenu37 PY& % GormNSMenu38PZ& % GormNSMenu39)P[& % MenuItem(40)LP\& % Scroller(0)aP]& % MenuItem(29)P^&%Box{P_& % MenuItem(18)&P`& % MenuItem(9);Pa& % GormNSMenu401Pb& % GormNSMenu419Pc& % GormNSMenu42GPd& % GormNSMenu43 Pe&%Menu(2))Pf& % GormNSMenu44Pg& % GormNSMenu45)Ph& % GormNSMenu461Pi& % GormNSMenu479Pj& % GormNSMenu48GPk& % TextField1Pl& % TextField2Pm& % TextField3Pn& % TextField4Po& % TextField6Pp&%GormNSPopUpButtonPq& % Scroller(1)Pr& % TextField7Ps& % TextField8-Pt& % GormNSPanelkPu& % TextField91Pv& % MenuItem(30)#Pw& % MenuItem(19)+Px&%ProgressIndicator5Py&%Menu(3)1Pz& % MenuItem10AP{& % MenuItem1LP|& % MenuItem116P}& % MenuItem2P~& % MenuItem12IP& % MenuItem3P& % MenuItem136P& % MenuItem4P& % MenuItem14IP& % MenuItem5P& % MenuItem156P& % MenuItem6DP& % MenuItem16;P& % MenuItem76P& % MenuItem17>P& % Scroller(2)P& % MenuItem8;P& % MenuItem18AP& % MenuItem9>P& % MenuItem19IP& % MenuItem(31)&POP&%Menu(10)9P& % TextFieldP& % MenuItem(20).P&%Menu(4)9P&%MenuItemIP& % GormNSPanel1>P& % MenuItem20P& % MenuItem21P& % MenuItem22P& % MenuItem(0)P& % MenuItem23P& % MenuItem24DP& % MenuItem25LP& % MenuItem26P& % MenuItem27P& % Scroller(3)P& % MenuItem28P& % MenuItem1006P& % MenuItem29#P& % MenuItem101;P& % MenuItem102>P& % MenuItem103AP& % MenuItem104DP& % MenuItem105IP& % MenuItem(32)+P& % MenuItem106LP& % MenuItem107P& % MenuItem108&P&%Menu(11)GP& % MenuItem109+P& % MenuItem(21)3P& % TableColumn1P%P&%column2 B A GPP&P&% &&&&&&&& &&&&&&%P!P&%ninee&&&&&&&& &&&&&&%[_P& % TableColumn2P& % TableColumn3P%P&%column2 B A GPP&P&% &&&&&&&& &&&&&&%P!e&&&&&&&& &&&&&&%[_P&%TableCornerView(0)P&%Menu(5)GP& % GormNSWindowP& % MenuItem(10)>P&%View(0)}P& % MenuItem30P±& % MenuItem31 Pñ& % MenuItem32Pı& % MenuItem(1)Pű&P13NSNibConnectorEPDZ&%NSOwnerPȱ3EPɱ3EPʱ3EP˱3dÐP̱3dPͱ3dPα3dPϱ3EPб3Pѱ3EPұ3Pӱ3PԱ3Pձ3P14NSNibControlConnectorEPױ&%submenuAction:Pر4EPٱ&%submenuAction:Pڱ4EP۱&%submenuAction:Pܱ4Pݱ&%NSFirstPޱ&%hide:P߱4P& % terminate:P4P&%orderFrontStandardInfoPanel:P4P&%arrangeInFront:P4P&%performMiniaturize:P4P& % performClose:P3PǐP4PP&%showPrefPanel:P15NSNibOutletConnectorǰPP &%delegateP3EP4EP&%submenuAction:P3fĐP3fP3fP3ǐP3 ǐP3tǐP3RP3P3JP3P3pP3P3P3P5P P&%logWinP3rP3VP5PVP& % logTextFieldP5PP& % localViewP5PP& % remoteViewP 4PP & % showFtpLog:P 4PP &%showConnPanel:P 3TP3kTP3lP3mP3P5PP& % connAddressP5PkP&%connPortP5PlP&%connUserP5PmP&%connPassP5PtP& % connectPanelP3P3P4PP& % connectConn:P 4PP!& % cancelConn:P"3oP#3rP$3^P%5kP& & % nextKeyViewP'5lm&P(3P)3pP*3P+5PP,& % remotePathP-5PpP.& % localPathP/3 P05PP1&%connAnonP25mP3 & % nextKeyViewP453P55k3P65l3P74pPP8&%changePathFromMenu:P94P8P:3P;3fP<3ǐP=3OP>3P?3sP@5PsPA& % infoMessagePB5PxPC&%progBarPD4PPE& % uploadButton:PF4 PPG&%downloadButton:PH5PPI&%mainWinPJ3FPK3QPL5PFPM& % infoSpeedPN5PuPO&%infoSizePP3EPQ4EPR&%submenuAction:PS3yPT3yPU3EPV4EPW&%submenuAction:PX3gPY3gPZ4PP[& % localDelete:P\4PP]& % remoteDelete:P^3"P_4"PP`& % prefSave:Pa5PPb&%portTypePc5PPd& % prefPanelPe4PPf &%anonymousConn:Pg3$Ph4$PPi& % prefCancel:Pj3TPk3TPl3nPm5P Pn& % buttDownloadPo5PPp & % buttUploadPq3rPr3\rPs4\rPt& % _doScroll:Pu3^Pv3OPw3RPx3qRPy4qRPz& % _doScroll:P{3RP|3ƐP}3RP~4RP& % _doScroll:P3RP3pP3pP4pP& % _doScroll:P3pP3P3upP4upP& % _doScroll:P3pP3QP3uP3xP4°PP & % disconnect:P5PP &%delegateP5İPP &%delegateP1&mftp.app-0.3/Resources/FTP_icon_gs.tif000066400000000000000000000673001177253120400175440ustar00rootroot00000000000000MM*00*&.6(1>2R=R)fI)iT\T=2R ' 'Adobe Photoshop 7.02008:05:12 01:09:32 adobe:docid:photoshop:5b2fcc99-214e-11dd-8124-e6ef54ace4d8 8BIM%8BIM com.apple.print.PageFormat.PMHorizontalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMHorizontalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMOrientation com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMOrientation 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalRes com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalRes 72 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMVerticalScaling com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMVerticalScaling 1 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.subTicket.paper_info_ticket com.apple.print.PageFormat.PMAdjustedPageRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPageRect 0.0 0.0 783 559 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T22:49:53Z com.apple.print.ticket.stateFlag 0 com.apple.print.PageFormat.PMAdjustedPaperRect com.apple.print.ticket.creator com.apple.printingmanager com.apple.print.ticket.itemArray com.apple.print.PageFormat.PMAdjustedPaperRect -18 -18 824 577 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T22:49:53Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMPaperName iso-a4 com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2000-07-28T22:57:04Z com.apple.print.ticket.stateFlag 1 com.apple.print.PaperInfo.PMUnadjustedPageRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPageRect 0.0 0.0 783 559 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.PMUnadjustedPaperRect com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.PMUnadjustedPaperRect -18 -18 824 577 com.apple.print.ticket.client com.apple.printingmanager com.apple.print.ticket.modDate 2008-05-11T21:20:19Z com.apple.print.ticket.stateFlag 0 com.apple.print.PaperInfo.ppd.PMPaperName com.apple.print.ticket.creator com.apple.print.pm.PostScript com.apple.print.ticket.itemArray com.apple.print.PaperInfo.ppd.PMPaperName A4 com.apple.print.ticket.client com.apple.print.pm.PostScript com.apple.print.ticket.modDate 2000-07-28T22:57:04Z com.apple.print.ticket.stateFlag 1 com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PaperInfoTicket com.apple.print.ticket.APIVersion 00.20 com.apple.print.ticket.privateLock com.apple.print.ticket.type com.apple.print.PageFormatTicket 8BIMxHH/8Ag{HH(dh 8BIMHH8BIM&?8BIM Transparency8BIM Transparency8BIMd8BIM8BIM x8BIM8BIM 8BIM 8BIM' 8BIMH/fflff/ff2Z5-8BIMp8BIM8BIM8BIM@@8BIM8BIMY00icon_computer_disk00nullboundsObjcRct1Top longLeftlongBtomlong0Rghtlong0slicesVlLsObjcslicesliceIDlonggroupIDlongoriginenum ESliceOrigin autoGeneratedTypeenum ESliceTypeImg boundsObjcRct1Top longLeftlongBtomlong0Rghtlong0urlTEXTnullTEXTMsgeTEXTaltTagTEXTcellTextIsHTMLboolcellTextTEXT horzAlignenumESliceHorzAligndefault vertAlignenumESliceVertAligndefault bgColorTypeenumESliceBGColorTypeNone topOutsetlong leftOutsetlong bottomOutsetlong rightOutsetlong8BIM8BIM8BIM G00+JFIFHH Adobe_CMAdobed            00"?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?D.Qe+iq BրkZ豥'o mCLj3D $1Zַo76SMS[EyXbGcfms,wp}vmV\}-:9ssek{^ޙozlXB'.ue6*x\ְMRSEv.5:/mo.rįcm `vìm`{@Cv'ݠܡU/ޓZOۈ͹,c1ShvNOKũ<̷4{\]I{CCB\|V'3Ä& GsIiVÚm2糧,/=+#*̭5{KK{K}Kim c/W﬚g9u6KJ@5+$N8BIM!UAdobe PhotoshopAdobe Photoshop 7.0 P8$ BaPd4DDR~?]y<7 -Au`0#_@@g\& >o4ìV;%KdÁ2o@ dp4z@|?ywh@ .Q5- —:[  ER,b3'`h0 ?0'b !!끁 ,onBH;";!wdZJ5AB 8`$kG ɭHF0QK<ι!l]ZXHR(is6PZL /@h=D!6ሬwlN ;,~<'ӺBȤ  $gy'ۺL& ně`Fà bLS%OD]C83" x'+U Á\x|$x A4!ah-)$q|nB =q 0!Tdm8O8h-lw0 U`)W* \)"nPR`$#q8M%Dwf쐀 0praH3 :80 +ǚ K A%8(:.xCQGv^Ixc  d5d "55A4 3[R@R6h,@@DZ1)F4GRF>B12N#P#;ean~&@6NjMu< bT?& >>AJ,6Ab`~v(,Aj=CeZdF`1 `A2'Ί&L tL!>:B1'D'T 2 !vW Z ʤ0A*AB&~!p!`f/HgG (:Zde&+ۂ쪆,0MF͢!O @rʎPNzP$<,`aux H ` !r=5P v 2Br ~>:p:40$@C*ʡQa%&\#Б$h'}'Ea޶A|Jv+{$_jѠK:a 1py@b @ j4J,A0~ "$N8e&82##2\/D<oA6XCs$:av^>J:FPOAB*RpmldT e60Az .   ` AJ0Ab6,](\HSιeOƆ$?Me$n!5#J 8.Q<,r~FFC= `!\F&FLa\`2ad;aN@X FP2P2. *D:@XC0d 6P"46]OF2̪DLG26`*QPbhi3HOc 4!|`x ! ,@JT*: ho4|< Z NΉf +InYc./BQت+,>] Rc::%:AOJ<NaDe:;RaƤp!KX`` `> <|E$1 ?_U2::zD24\$dJDjK8D{QAF6'xAra2 0@ &@rl:kfscZ3`gD&jlB%궠~'v VJZ!!İ taOî$NT 3cUToᐶ,&ZCa I V@bEbmTN#`JD,D漌Z͑ZC`Z D.`Wzʫfc2E @}A|+diC!20jʤZGG5*!>#4]ima, J#a'Fƶ)lp Dab+ J0ANhJ4 ` lZvj d`df#2 2P0hkaZhqQAHr´3 l"R'm:f.Z0bʢLj<"3dV<*O.2!z ((H&x%` P <dxE!u0c Ȯs>R"’a$D`E:OBZCc|kq822ra] Od3+*aZ%`v^0"!ИQ\VH gaQ p!!&xᲶ aDn@`@0Րh P!GvJ6a^]T#w3Eb=AV&dF%:o;V;kHbDnr'L&#!`N%7a`n`v4=|NDnܪ kd `pTe)cê2c {u2"T$x.JF`bgRH!<<%;>dn=rDXrOnw<`br&wC07A'$@Q\UC`n,F!p!f ;CDJ\a3a%\DXP9yOS56OTjU:V +`X0?/w=Ȱ}%f̻òֿ͠grðpbUSOiݾ̕r޾ZREK6 jw޷R_KE@mϢyี][J7X p¯߾viX6Se蛲¯w俾siU0Ilٮ|ĿtfR,=cϽݠoƹzfX0Axߪ߭rʬhZ9H.}Ķ]\J=Jyƕɤ{hQSgp̰ͤfn}ÉװǫyijgČȻfkuzÍѹݹ٫ޛȼ٫iǥ^=p٬ànfjrگCl˸v忞Ÿ湟ߡ껦񪖦²똏e壥䡣鰪ۀףḌouۿx↯١䣀ͬͨmZᅭ۽zyѰԨiUnۿ͑㆜züߏ¹dӶrȩ۾ȀœˋQ(@WꜾڵҰJI]Nɱհͭ}_Xiֳ~d^[^o}}ouvƩ|{j]c`OXeù殭䛹ǽőȯ៼Ʒ⤧ūƜ¹дޖίϵޗ½դʱĚ̼֑õ}ڽɽŤёtѮĪБslŬʯ|耗䷚׾´׼خͺê̿ʵyԲ÷µȐ𞓌tnno߱īƵˊǩƴֹ߾ȋƦY{ëɳ̴ݹ\ϱ﹀ߠͳޠƭޠȱ򑒦¼ޠ艤¼ޠҾ¼ޠѽԬ¼ޠнĶᡷ¼ޠǹ¼ޠij¼ޠ¼ޠƶޠūżޠ͆vޠ͉϶ܹޠ{cۨٗ÷{cۨ~ϭ_I{cۨ{}{cڧ[ȓ{cϦ{cƿװ{cǣ{cbߛ檪{cƯjqʻt{eʵ}ʩ٧gW{kaïuw̰eQkީ{lkggBw~ops\K3o~˾ŨFfC>[\WrэP*>TNypw_q^NK_NHpllw-ƶƿոL^~(o̧ƸMZyjOŻͮfOpˬeCٺ㬮ƹͲcihk~l쿮Ҹہ9FТ\RXDђdZո̑vďΙ炶פΙҜ䷙|”拉¶պ̿˩ٹطlܻᙶԣλР͠Рǯʱϣ𮬽ͶѝߨͶӢֹͶ՗˶ӣܳ֬¿ȹԙ̺҆t҉Ҹܸ8BIMLMsk28BIMPattftp.app-0.3/Resources/arrow_left.tiff000066400000000000000000000021161177253120400177160ustar00rootroot00000000000000MM*     t(R/---ҮQwLLLiii cccLLL <"""j<""" cccLLL jjj vLLL/---ҮQ ftp.app-0.3/Resources/arrow_right.tiff000066400000000000000000000021161177253120400201010ustar00rootroot00000000000000MM*     t(RQ---/LLLw iii LLLccc """<j"""< LLLccc jjjLLLvQ---/ ftp.app-0.3/arrow_left.tiff000066400000000000000000000021161177253120400157440ustar00rootroot00000000000000MM*     t(R/---ҮQwLLLiii cccLLL <"""j<""" cccLLL jjj vLLL/---ҮQ ftp.app-0.3/arrow_right.tiff000066400000000000000000000021161177253120400161270ustar00rootroot00000000000000MM*     t(RQ---/LLLw iii LLLccc """<j"""< LLLccc jjjLLLvQ---/ ftp.app-0.3/client.h000066400000000000000000000035771177253120400143710ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005 Free Software Foundation Author: Riccardo Mottola Created: 2005-04-21 Generic client class, to be subclassed. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import #import "fileElement.h" /** * Clas that represents an object to access files, be them remote or local. * It must be subclassed to be useful. This object holds porperties genrealy * valid for both local and remote instances as the working directory and the * home directory of the user. It also defines common methods for creating, * changing and deleting directories. */ @interface Client : NSObject { id controller; NSString *workingDir; NSString *homeDir; } - (id)init; - (id)initWithController:(id)cont; /** returns the current working directory */ - (NSString *)workingDir; - (void)setWorkingDirWithCString:(char *)dir; - (void)setWorkingDir:(NSString *)dir; - (void)changeWorkingDir:(NSString *)dir; - (BOOL)createNewDir:(NSString *)dir; - (void)deleteFile:(FileElement *)file beingAt:(int)depth; - (NSArray *)workDirSplit; /** returns an array with the directory listing */ - (NSArray *)dirContents; /** returns the current home directory */ - (NSString *)homeDir; @end ftp.app-0.3/client.m000066400000000000000000000050741177253120400143700ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2007 Free Software Foundation Author: Riccardo Mottola Created: 2005-04-21 Generic client class, to be subclassed. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import "client.h" @implementation Client /* initializer */ /* we set possibly unused stuff to NULL */ - (id)init { if (!(self =[super init])) return nil; controller = nil; return self; } - (id)initWithController:(id)cont { if (!(self =[super init])) return nil; controller = cont; return self; } - (void)dealloc { if (homeDir) [homeDir release]; if (workingDir) [workingDir release]; if (workingDir) [workingDir release]; [super dealloc]; } - (NSString *)workingDir { return workingDir; } - (NSString *)homeDir { return homeDir; } - (void)setWorkingDirWithCString:(char *)dir { [self setWorkingDir:[NSString stringWithCString:dir]]; } - (void)setWorkingDir:(NSString *)dir { if (workingDir) [workingDir release]; workingDir = [[NSString stringWithString:dir] retain]; } - (void)changeWorkingDir:(NSString *)dir { [self setWorkingDir:dir]; } - (NSArray *)workDirSplit { NSMutableArray *reversedList; NSArray *list; NSEnumerator *en; NSString *currElement; list = [workingDir pathComponents]; reversedList = [NSMutableArray arrayWithCapacity:[list count]]; en = [list reverseObjectEnumerator]; while ((currElement = [en nextObject])) [reversedList addObject:currElement]; return [reversedList retain]; } - (NSArray *)dirContents { NSLog(@"override me! dirContents superclass method"); return nil; } - (BOOL)createNewDir:(NSString *)dir { NSLog(@"override me! createNewDir superclass method"); return NO; } - (void)deleteFile:(FileElement *)file beingAt:(int)depth { NSLog(@"override me! deleteFile superclass method"); } @end ftp.app-0.3/fileElement.h000066400000000000000000000025331177253120400153330ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-04-18 Single element of a file listing This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import @interface FileElement : NSObject { NSString *filename; NSString *linkTargetName; BOOL isDir; BOOL isLink; unsigned long long size; NSDate *modifDate; } - (id)initWithFileAttributes :(NSString *)fname :(NSDictionary *)attribs; - (id)initWithLsLine :(char *)line; - (NSString *)filename; - (NSString *)linkTargetName; - (BOOL)isDir; - (BOOL)isLink; - (unsigned long long)size; @end ftp.app-0.3/fileElement.m000066400000000000000000000366561177253120400153550ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-04-18 Single element of a file listing This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import "fileElement.h" @implementation FileElement - (void)dealloc { [filename release]; [super dealloc]; } /* initialize a file element using attrbutes of NSFileManager */ - (id)initWithFileAttributes :(NSString *)fname :(NSDictionary *)attribs { [super init]; size = [attribs fileSize]; modifDate = [[attribs objectForKey:NSFileModificationDate] retain]; if ([attribs fileType] == NSFileTypeDirectory) isDir = YES; else isDir = NO; isLink = NO; filename = [fname retain]; return self; } /* as a parser aid, check if a string is a month */ - (int)checkMonth: (NSString *)token { if ([token compare:@"Jan" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 1; if ([token compare:@"Feb" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 2; if ([token compare:@"Mar" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 3; if ([token compare:@"Apr" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 4; if ([token compare:@"May" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 5; if ([token compare:@"Jun" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 6; if ([token compare:@"Jul" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 7; if ([token compare:@"Aug" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 8; if ([token compare:@"Sep" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 9; if ([token compare:@"Oct" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 10; if ([token compare:@"Nov" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 11; if ([token compare:@"Dec" options:NSCaseInsensitiveSearch ] == NSOrderedSame) return 12; return 0; } /* tries to parse a single line of LIST currently unix-style results will work, like drwx------ 22 multix staff 704 Apr 2 14:46 Documents or these where one of user/group are omitted drwxr-xr-x 8 users 4096 Apr 15 19:58 Documents inital blocks can be omitted, like: drwx------ multix staff 704 Apr 2 14:46 Documents user/group could be numerical drwx------ 22 4567 120 704 Apr 2 14:46 Documents the hour time could be the year drwx------ 22 multix staff 704 Apr 2 2005 Documents the filename could contain one or more spaces -rw-r--r-- 1 multix staff 0 May 25 10:08 test file the filesize can be zero.. it will skip a line that is not considered meaningful, like: total 74184 (typical from Unix ls -l) and return nil. some attempt at scanning OS400 / i5 ftp listings is attempted too, those are in the style of: SVIFELMA 32768 02/05/07 15:32:42 *FILE INSOLUTO SVIFELMA *MEM INSOLUTO.INSOLUTO the feof line is ignored */ - (id)initWithLsLine :(char *)line { NSString *fullLine; NSMutableArray *splitLine; unichar ch; unsigned elementsFound; NSCharacterSet *whiteSet; unsigned lineLen; NSRange searchRange; NSRange tokenEnd; NSRange tokenRange; BOOL foundStandardMonth; BOOL foundOneBeforeMonth; [super init]; // typical Unix end of listing if (strstr(line, "total") == line) return nil; // typical IBM OS400 end of listing if (strstr(line, "feof") == line) return nil; filename = nil; linkTargetName = nil; isLink = NO; isDir = NO; whiteSet = [NSCharacterSet whitespaceCharacterSet]; splitLine = [NSMutableArray arrayWithCapacity:5]; fullLine = [NSString stringWithCString:line]; lineLen = [fullLine length]; ch = [fullLine characterAtIndex:0]; if (ch == '-' || ch == 'd' || ch == 'l') { // this is a unix-like listing unsigned cursor; // file permissions block cursor = 0; searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // typically links - user - group - size searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"second token: %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange)); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"third token: %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange)); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"fourth token: %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange)); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"fifth token: %@ %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange), [fullLine substringWithRange:tokenRange]); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); foundOneBeforeMonth = [self checkMonth:[splitLine objectAtIndex:4]]; while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // typically month searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"sixth token: %@ %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange), [fullLine substringWithRange:tokenRange]); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); foundStandardMonth = [self checkMonth:[splitLine objectAtIndex:5]]; while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // typically day of the month searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"seventh token: %@ %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange), [fullLine substringWithRange:tokenRange]); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // typically year or hour // but it could be fileName already if (foundStandardMonth) { searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); // NSLog(@"eighth token: %@ %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange), [fullLine substringWithRange:tokenRange]); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; } // typically the filename if (cursor < lineLen) { tokenRange = NSMakeRange(cursor, lineLen-cursor); // NSLog(@"last token: %@ %@ %@", NSStringFromRange(tokenEnd), NSStringFromRange(tokenRange), [fullLine substringWithRange:tokenRange]); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; } elementsFound = [splitLine count]; // copy back the found data if (foundStandardMonth && elementsFound == 9) { NSRange linkArrowRange; // everything is fine and ok, we have a full-blown listing and parsed it well; isDir = NO; if ([[splitLine objectAtIndex:0] characterAtIndex:0] == 'd') isDir = YES; [[NSScanner scannerWithString: [splitLine objectAtIndex:4]] scanLongLong:(long long*)&size]; linkArrowRange = [[splitLine objectAtIndex:8] rangeOfString: @" -> "]; if (linkArrowRange.location == NSNotFound) { filename = [[splitLine objectAtIndex:8] retain]; } else { isLink = YES; filename = [[[splitLine objectAtIndex:8] substringToIndex: linkArrowRange.location] retain]; linkTargetName = [[[splitLine objectAtIndex:8] substringFromIndex: linkArrowRange.location+linkArrowRange.length] retain]; NSLog(@"we have a link %@", linkTargetName); } } else if (foundOneBeforeMonth && elementsFound == 8) { NSRange linkArrowRange; // we miss the link count or user probably isDir = NO; if ([[splitLine objectAtIndex:0] characterAtIndex:0] == 'd') isDir = YES; [[NSScanner scannerWithString: [splitLine objectAtIndex:3]] scanLongLong:(long long*)&size]; linkArrowRange = [[splitLine objectAtIndex:7] rangeOfString: @" -> "]; if (linkArrowRange.location == NSNotFound) { filename = [[splitLine objectAtIndex:7] retain]; } else { isLink = YES; filename = [[[splitLine objectAtIndex:7] substringToIndex: linkArrowRange.location] retain]; linkTargetName = [[[splitLine objectAtIndex:7] substringFromIndex: linkArrowRange.location+linkArrowRange.length] retain]; NSLog(@"we have a link %@", linkTargetName); } } else return nil; } else if ((fullLine != NULL) && ([fullLine rangeOfString: @"*FILE"].location != NSNotFound)) { // maybe it is an IBM AS400 / i5 style line // this is an IBM listing, having the *FILE element unsigned cursor; // username block cursor = 0; searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // file size searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // date searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // time searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // record type searchRange = NSMakeRange(cursor, lineLen-cursor); tokenEnd = [fullLine rangeOfCharacterFromSet:whiteSet options:0 range:searchRange]; tokenRange = NSMakeRange(cursor, tokenEnd.location-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; cursor = NSMaxRange(tokenEnd); while ([fullLine characterAtIndex:cursor] == ' ' && cursor <= lineLen) cursor++; // file name // typically the filename if (cursor < lineLen) { tokenRange = NSMakeRange(cursor, lineLen-cursor); [splitLine addObject:[fullLine substringWithRange:tokenRange]]; } // everything is fine and ok, we have a full-blown listing and parsed it well; isDir = NO; /* OS400 is not hierarchical */ [[NSScanner scannerWithString: [splitLine objectAtIndex:1]] scanLongLong:(long long*)&size]; filename = [[splitLine objectAtIndex:5] retain]; } else { /* we don't know better */ return nil; } /* let's ignore the current and the parent directory some servers send over... */ if([filename isEqualToString:@"."]) return nil; else if([filename isEqualToString:@".."]) return nil; return self; } /* accessors */ - (NSString *)filename { return self->filename; } - (NSString *)linkTargetName { return self->linkTargetName; } - (BOOL)isDir { return isDir; } - (BOOL)isLink { return isLink; } - (unsigned long long)size { return size; } @end ftp.app-0.3/fileTable.h000066400000000000000000000024151177253120400147700ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-04-12 Table class for file listing This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import #import "fileElement.h" #define TAG_FILENAME @"filename" enum sortOrderDef { ascending, descending, undefined }; @interface FileTable : NSObject { NSArray *fileStructs; NSMutableArray *sortedArray; NSString *sortByIdent; enum sortOrderDef sortOrder; } - (void)initData:(NSArray *)fnames; - (FileElement *)elementAtIndex:(unsigned)index; - (void)sortByIdent:(NSString *)idStr; @end ftp.app-0.3/fileTable.m000066400000000000000000000072021177253120400147740ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-04-12 Table class for file listing This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import "fileTable.h" #import "fileElement.h" /* we sort the already existing sorted array which contains only the keys to sort on */ NSComparisonResult compareDictElements(id e1, id e2, void *context) { NSString *s1; NSString *s2; NSComparisonResult r; enum sortOrderDef sortOrder; s1 = [(NSDictionary *)e1 objectForKey: @"name"]; s2 = [(NSDictionary *)e2 objectForKey: @"name"]; sortOrder = *(enum sortOrderDef *)context; r = [s1 compare: s2]; if (sortOrder == descending) { if (r == NSOrderedAscending) r = NSOrderedDescending; else if (r == NSOrderedDescending) r = NSOrderedAscending; } return r; } @implementation FileTable - (void)initData:(NSArray *)fnames { int i; sortByIdent = nil; if (fileStructs) { [fileStructs release]; [sortedArray release]; } fileStructs = [[NSArray arrayWithArray:fnames] retain]; sortedArray = [[NSMutableArray arrayWithCapacity: [fileStructs count]] retain]; for (i = 0; i < [fileStructs count]; i++) { NSNumber *n; NSMutableDictionary *dict; FileElement *fe; fe = [fileStructs objectAtIndex: i]; n = [NSNumber numberWithInt: i]; dict = [NSMutableDictionary dictionary]; [dict setObject: [fe filename] forKey: @"name"]; [dict setObject: n forKey: @"row"]; [sortedArray addObject: dict]; } sortOrder = undefined; } - (void)dealloc { [fileStructs release]; [sortedArray release]; [super dealloc]; } /** retunrs the object after resolving sorting */ - (FileElement *)elementAtIndex:(unsigned)index { int originalRow; originalRow = [[[sortedArray objectAtIndex: index] objectForKey: @"row"] intValue]; return [fileStructs objectAtIndex:originalRow]; } - (void)sortByIdent:(NSString *)idStr { if ([idStr isEqualToString: sortByIdent]) { if (sortOrder == ascending) sortOrder = descending; else sortOrder = ascending; } else { NSLog(@"Sort by: %@", idStr); sortOrder = ascending; } sortByIdent = idStr; [sortedArray sortUsingFunction:compareDictElements context:&sortOrder]; } /* methods implemented to follow the informal NSTableView protocol */ - (int)numberOfRowsInTableView:(NSTableView *)aTableView { return [sortedArray count]; } - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex { id theElement; int originalRow; theElement = NULL; NSParameterAssert(rowIndex >= 0 && rowIndex < [sortedArray count]); originalRow = [[[sortedArray objectAtIndex: rowIndex] objectForKey: @"row"] intValue]; if ([[aTableColumn identifier] isEqualToString:TAG_FILENAME]) theElement = [[fileStructs objectAtIndex:originalRow] filename]; else NSLog(@"unknown table column ident"); return theElement; } @end ftp.app-0.3/ftpclient.h000066400000000000000000000057231177253120400150760ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-03-30 FTP client class This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include /* for bcopy or memcpy */ #ifdef _WIN32 #include #include #define BCOPY(SRC, DST, LEN) memcpy(DST, SRC, LEN) #else #include #include #include #define BCOPY(SRC, DST, LEN) bcopy(SRC, DST, LEN) #endif /* WIN32 */ #include #import #import "client.h" #import "localclient.h" #import "fileElement.h" #define MAX_SOCK_BUFF 1024 #define MAX_DIR_RECURSION 5 #define ERR_COULDNT_RESOLVE -1 #define ERR_SOCKET_FAIL -2 #define ERR_CONNECT_FAIL -3 #define ERR_GESOCKNAME_FAIL -4 #define ERR_READ_FAIL -5 /** connection types: PASV or PORT */ typedef enum { defaultMode, portMode, passiveMode } connectionModes; /** private structure to use a socket like it was a file stream */ typedef struct { int socket; int position; int len; char buffer[MAX_SOCK_BUFF]; } streamStruct; @interface FtpClient : Client { int userDataPort; int serverDataPort; int dataSocket; int controlSocket; int localSocket; streamStruct dataStream; streamStruct ctrlStream; struct sockaddr_in remoteSockName; struct sockaddr_in localSockName; struct sockaddr_in dataSockName; BOOL usesPassive; BOOL usesPorts; @protected BOOL connected; } - (id)initWithController:(id)cont :(connectionModes)cMode; - (void)setPortDefault; - (void)setPortPort; - (void)setPortPassive; - (void)logIt:(NSString *)str; /** reads a reply from the control socket */ - (int)readReply :(NSMutableArray **)result; - (int)writeLine:(char *)line; - (int)writeLine:(char *)line byLoggingIt:(BOOL)doLog; - (oneway void)retrieveFile:(FileElement *)file to:(LocalClient *)localClient beingAt:(int)depth; - (oneway void)storeFile:(FileElement *)file from:(LocalClient *)localClient beingAt:(int)depth; - (int)connect:(int)port :(char *)server; - (void)disconnect; - (int)authenticate:(char *)user :(char *)pass; - (int)initDataConn; - (int)initDataStream; - (int)closeDataConn; - (void)closeDataStream; @end ftp.app-0.3/ftpclient.m000066400000000000000000001002751177253120400151010ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2010 Riccardo Mottola Author: Riccardo Mottola Created: 2005-03-30 FTP client class This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * this class handles acts as a remote client with the FTP server. * the connection modes, default, active (port) and passive * can be set using the three setPort* methods */ #import "ftpclient.h" #import "AppController.h" #import "fileElement.h" #include #include #include #include #include #ifdef _WIN32 #include #else #include /* for inet_ntoa and similar */ #include #define INVALID_SOCKET -1 #define closesocket close #endif /* WIN32 */ #define MAX_CONTROL_BUFF 2048 #define MAX_DATA_BUFF 2048 #if defined(__linux__) #define socklentype socklen_t #else #define socklentype int #endif void initStream(streamStruct *ss, int socket) { ss->socket = socket; ss->position = 0; ss->len = 0; ss->buffer[0] = '\0'; } int getChar(streamStruct* ss) { int result; BOOL gotEof; gotEof = NO; if (ss->position == ss->len) { int read; read = recv(ss->socket, ss->buffer, MAX_SOCK_BUFF, 0); if (read > 0) { ss->len = read; ss->position = 0; } else if (read == 0) { ss->len = 0; ss->position = 0; ss->buffer[0] = '\0'; gotEof = YES; } else { ss->len = 0; ss->position = 0; NSLog(@"error sock read"); perror("getChar:read"); ss->buffer[0] = '\0'; gotEof = YES; } } if (gotEof) result = EOF; else { result = ss->buffer[ss->position]; ss->position++; } return result; } @implementation FtpClient + (void)connectWithPorts:(NSArray *)portArray { NSAutoreleasePool *pool; NSConnection *serverConnection; FtpClient *serverObject; pool = [[NSAutoreleasePool alloc] init]; serverConnection = [NSConnection connectionWithReceivePort:[portArray objectAtIndex:0] sendPort:[portArray objectAtIndex:1]]; serverObject = [self alloc]; [(id)[serverConnection rootProxy] setServer:serverObject]; [serverObject release]; [[NSRunLoop currentRunLoop] run]; [pool release]; return; } - (id)initWithController:(id)cont :(connectionModes)cMode { if (!(self =[super initWithController:cont])) return nil; switch (cMode) { case defaultMode: [self setPortDefault]; break; case portMode: [self setPortPort]; break; case passiveMode: [self setPortPassive]; break; default: [self setPortDefault]; } #ifdef _WIN32 WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD( 1, 1 ); WSAStartup(wVersionRequested, &wsaData); NSLog(@"inited WinSock"); #endif connected = NO; return self; } /* three methods to set the connection handling */ - (void)setPortDefault { usesPassive = NO; usesPorts = NO; } - (void)setPortPort { usesPassive = NO; usesPorts = YES; } - (void)setPortPassive { usesPassive = YES; usesPorts = NO; } /* changes the current working directory this directory is implicit in many other actions */ - (void)changeWorkingDir:(NSString *)dir { char tempStr[MAX_CONTROL_BUFF]; char tempStr2[MAX_CONTROL_BUFF]; NSMutableArray *reply; if (!connected) return; [dir getCString:tempStr2]; sprintf(tempStr, "CWD %s\r\n", tempStr2); [self writeLine:tempStr]; if ([self readReply:&reply] == 250) [super changeWorkingDir:dir]; else NSLog(@"cwd failed"); } /* if we have a valid controller, we suppose it respons to appendTextToLog */ /* RM: is there a better way to append a newline? */ - (void)logIt:(NSString *)str { NSMutableString *tempStr; if (controller == NULL) return; tempStr = [NSMutableString stringWithCapacity:([str length] + 1)]; [tempStr appendString:str]; [tempStr appendString:@"\n"]; [controller appendTextToLog:tempStr]; } /* read the reply of a command, be it single or multi-line returned is the first numerical code NOTE: the parser is NOT robust in handling errors */ #define NUMCODELEN 4 - (int)readReply :(NSMutableArray **)result { char buff[MAX_CONTROL_BUFF]; int readBytes; int ch; /* the first numerical code, in case of multi-line output it is followed by '-' in the first line and by ' ' in the last line */ char numCodeStr[NUMCODELEN]; int numCode; int startNumCode; char separator; enum states { N1, N2, N3, SEPARATOR, CHARS, GOTR, END }; enum states state; BOOL multiline; readBytes = 0; state = N1; separator = 0; multiline = NO; startNumCode = numCode = 0; *result = [NSMutableArray arrayWithCapacity:1]; // TODO: protect against numCodeStr overflow while (!(state == END)) { ch = getChar(&ctrlStream); // NSLog(@"read char: %c", ch); if (ch == EOF) state = END; switch (state) { case N1: buff[readBytes] = ch; if (readBytes < NUMCODELEN) numCodeStr[readBytes] = ch; readBytes++; if (ch == ' ') /* skip internal lines of multi-line */ state = CHARS; else state = N2; break; case N2: buff[readBytes] = ch; numCodeStr[readBytes] = ch; readBytes++; state = N3; break; case N3: buff[readBytes] = ch; numCodeStr[readBytes] = ch; readBytes++; state = SEPARATOR; break; case SEPARATOR: buff[readBytes] = ch; numCodeStr[readBytes] = '\0'; readBytes++; numCode = atoi(numCodeStr); separator = ch; state = CHARS; break; case CHARS: if (ch == '\r') state = GOTR; else { buff[readBytes++] = ch; } break; case GOTR: if (ch == '\n') { buff[readBytes] = '\0'; [self logIt:[NSString stringWithCString:buff]]; [*result addObject:[NSString stringWithCString:buff]]; readBytes = 0; if (separator == ' ') { if (multiline) { if (numCode == startNumCode) state = END; } else { startNumCode = numCode; state = END; } } else { startNumCode = numCode; multiline = YES; state = N1; } } break; case END: NSLog(@"EOF reached prematurely"); startNumCode = -1; break; default: NSLog(@"Duh, a case default in the readReply parser"); } } [*result retain]; return startNumCode; } /* writes a single line to the control connection, logging it always */ - (int)writeLine:(char *)line { return [self writeLine:line byLoggingIt:YES]; } /* writes a single line to the control connection */ - (int)writeLine:(char *)line byLoggingIt:(BOOL)doLog { int sentBytes; int bytesToSend; bytesToSend = strlen(line); if (doLog) [self logIt:[NSString stringWithCString:line length:(bytesToSend - 2)]]; if ((sentBytes = send(controlSocket, line, strlen(line), 0)) < bytesToSend) NSLog(@"sent %d out of %d", sentBytes, bytesToSend); return sentBytes; } - (int)setTypeToI { NSMutableArray *reply; int retVal; retVal = [self writeLine:"TYPE I\r\n"]; if ( retVal > 0) { [self readReply:&reply]; [reply release]; } return retVal; } - (int)setTypeToA { NSMutableArray *reply; int retVal; retVal = [self writeLine:"TYPE A\r\n"]; NSLog(@"retval: %d", retVal); if ( retVal > 0) { [self readReply:&reply]; [reply release]; } return retVal; } - (oneway void)retrieveFile:(FileElement *)file to:(LocalClient *)localClient beingAt:(int)depth; { NSString *fileName; unsigned long long fileSize; char fNameCStr[MAX_CONTROL_BUFF]; char command[MAX_CONTROL_BUFF]; char buff[MAX_DATA_BUFF]; FILE *localFileStream; int bytesRead; NSMutableArray *reply; struct sockaddr from; int fromLen; unsigned int minimumPercentIncrement; unsigned int progressIncBytes; int replyCode; unsigned long long totalBytes; NSString *localPath; BOOL gotFile; fromLen = sizeof(from); fileName = [file filename]; fileSize = [file size]; minimumPercentIncrement = fileSize / 100; // we should guard against maxint localPath = [[localClient workingDir] stringByAppendingPathComponent:fileName]; if ([file isDir]) { NSString *pristineLocalPath; /* original path */ NSString *pristineRemotePath; /* original path */ NSArray *dirList; NSString *remoteDir; NSEnumerator *en; FileElement *fEl; if (depth > MAX_DIR_RECURSION) { NSLog(@"Max depth reached: %d", depth); return; } pristineLocalPath = [[localClient workingDir] retain]; pristineRemotePath = [[self workingDir] retain]; remoteDir = [[self workingDir] stringByAppendingPathComponent:fileName]; [self changeWorkingDir:remoteDir]; if ([localClient createNewDir:localPath] == YES) { [localClient changeWorkingDir:localPath]; dirList = [self dirContents]; en = [dirList objectEnumerator]; while ((fEl = [en nextObject])) { NSLog(@"recurse, download : %@", [fEl filename]); [self retrieveFile:fEl to:localClient beingAt:depth+1]; } } /* we get back were we started */ [self changeWorkingDir:pristineRemotePath]; [localClient changeWorkingDir:pristineLocalPath]; [pristineLocalPath release]; [pristineRemotePath release]; return; } /* lets settle to a plain binary standard type */ [self setTypeToI]; if ([self initDataConn] < 0) { NSLog(@"error initiating data connection, retrieveFile"); return; } [fileName getCString:fNameCStr]; sprintf(command, "RETR %s\r\n", fNameCStr); [self writeLine:command]; replyCode = [self readReply:&reply]; NSLog(@"%d reply is %@: ", replyCode, [reply objectAtIndex:0]); if(replyCode != 150) { [controller showAlertDialog:@"Unexpected server error."]; NSLog(@"Unexpected condition in retrieve"); return; /* we have an error or some unexpected condition */ } [reply release]; if ([self initDataStream] < 0) { [controller showAlertDialog:@"Unexpected connection error."]; return; } localFileStream = fopen([localPath cString], "w"); if (localFileStream == NULL) { [controller showAlertDialog:@"Opening of local file failed.\nCheck permissions and free space."]; perror("local fopen failed"); return; } totalBytes = 0; progressIncBytes = 0; gotFile = NO; [controller setThreadRunningState:YES]; [controller setTransferBegin:fileName :fileSize]; while (!gotFile) { bytesRead = recv(localSocket, buff, MAX_DATA_BUFF, 0); if (bytesRead == 0) gotFile = YES; else if (bytesRead < 0) { gotFile = YES; NSLog(@"error on socket read, retrieve file"); } else { if (fwrite(buff, sizeof(char), bytesRead, localFileStream) < bytesRead) { NSLog(@"file write error, retrieve file"); } totalBytes += bytesRead; progressIncBytes += bytesRead; if (progressIncBytes > minimumPercentIncrement) { [controller setTransferProgress:[NSNumber numberWithUnsignedLongLong:totalBytes]]; progressIncBytes = 0; } } } [controller setTransferEnd:[NSNumber numberWithUnsignedLongLong:totalBytes]]; fclose(localFileStream); [self closeDataStream]; [self readReply:&reply]; [reply release]; [controller setThreadRunningState:NO]; } - (oneway void)storeFile:(FileElement *)file from:(LocalClient *)localClient beingAt:(int)depth { NSString *fileName; unsigned long long fileSize; char fNameCStr[MAX_CONTROL_BUFF]; char command[MAX_CONTROL_BUFF]; char buff[MAX_DATA_BUFF]; FILE *localFileStream; NSMutableArray *reply; int bytesRead; struct sockaddr from; int fromLen; unsigned int minimumPercentIncrement; unsigned int progressIncBytes; int replyCode; unsigned long long totalBytes; NSString *localPath; BOOL gotFile; fromLen = sizeof(from); fileName = [file filename]; fileSize = [file size]; minimumPercentIncrement = fileSize / 100; // we should guard against maxint localPath = [[localClient workingDir] stringByAppendingPathComponent:fileName]; if ([file isDir]) { NSString *pristineLocalPath; /* original path */ NSString *pristineRemotePath; /* original path */ NSArray *dirList; NSString *remotePath; NSEnumerator *en; FileElement *fEl; if (depth > MAX_DIR_RECURSION) { NSLog(@"Max depth reached: %d", depth); return; } pristineLocalPath = [[localClient workingDir] retain]; pristineRemotePath = [[self workingDir] retain]; NSLog(@"it is a dir: %@", fileName); remotePath = [pristineRemotePath stringByAppendingPathComponent:fileName]; [localClient changeWorkingDir:localPath]; NSLog(@"local dir changed: %@", [localClient workingDir]); if ([self createNewDir:remotePath] == YES) { NSLog(@"remote dir created successfully"); [self changeWorkingDir:remotePath]; dirList = [localClient dirContents]; en = [dirList objectEnumerator]; while ((fEl = [en nextObject])) { NSLog(@"recurse, upload : %@", [fEl filename]); [self storeFile:fEl from:localClient beingAt:(depth+1)]; } } /* we get back were we started */ [self changeWorkingDir:pristineRemotePath]; [localClient changeWorkingDir:pristineLocalPath]; [pristineLocalPath release]; [pristineRemotePath release]; return; } /* lets settle to a plain binary standard type */ [self setTypeToI]; if ([self initDataConn] < 0) { [controller showAlertDialog:@"Error initiating the Data Connection."]; NSLog(@"error initiating data connection, storeFile"); return; } [fileName getCString:fNameCStr]; sprintf(command, "STOR %s\r\n", fNameCStr); [self writeLine:command]; replyCode = [self readReply:&reply]; NSLog(@"%d reply is %@: ", replyCode, [reply objectAtIndex:0]); if (replyCode >= 550 && replyCode <= 559) { [controller showAlertDialog:[reply objectAtIndex:0]]; [self logIt: [reply objectAtIndex:0]]; [reply release]; return; } [reply release]; if ([self initDataStream] < 0) { [controller showAlertDialog:@"Unexpected connection error."]; return; } localFileStream = fopen([localPath cString], "r"); if (localFileStream == NULL) { [controller showAlertDialog:@"Opening of local file failed.\n Check permissions."]; perror("local fopen failed"); return; } totalBytes = 0; progressIncBytes = 0; gotFile = NO; [controller setThreadRunningState:YES]; [controller setTransferBegin:fileName :fileSize]; while (!gotFile) { bytesRead = fread(buff, sizeof(char), MAX_DATA_BUFF, localFileStream); if (bytesRead == 0) { gotFile = YES; if (!feof(localFileStream)) NSLog(@"error on file read, store file"); else NSLog(@"feof"); } else { if (write(localSocket, buff, bytesRead) < bytesRead) { NSLog(@"socket write error, store file"); } totalBytes += bytesRead; progressIncBytes += bytesRead; if (progressIncBytes > minimumPercentIncrement) { [controller setTransferProgress:[NSNumber numberWithUnsignedLongLong:totalBytes]]; progressIncBytes = 0; } } } [controller setTransferEnd:[NSNumber numberWithUnsignedLongLong:totalBytes]]; fclose(localFileStream); [self closeDataStream]; [self readReply:&reply]; [reply release]; [controller setThreadRunningState:NO]; } - (void)deleteFile:(FileElement *)file beingAt:(int)depth { NSString *fileName; NSString *localPath; NSFileManager *fm; char command[MAX_CONTROL_BUFF]; NSMutableArray *reply; int replyCode; fm = [NSFileManager defaultManager]; fileName = [file filename]; localPath = [[self workingDir] stringByAppendingPathComponent:fileName]; if ([file isDir]) { NSString *pristineRemotePath; /* original path */ NSArray *dirList; NSString *remotePath; NSEnumerator *en; FileElement *fEl; if (depth > 3) { NSLog(@"Max depth reached: %d", depth); return; } pristineRemotePath = [[self workingDir] retain]; NSLog(@"it is a dir: %@", fileName); remotePath = [pristineRemotePath stringByAppendingPathComponent:fileName]; NSLog(@"remote dir created successfully"); [self changeWorkingDir:remotePath]; dirList = [self dirContents]; en = [dirList objectEnumerator]; while ((fEl = [en nextObject])) { NSLog(@"recurse, delete : %@", [fEl filename]); [self deleteFile:fEl beingAt:(depth+1)]; } /* we get back were we started */ [self changeWorkingDir:pristineRemotePath]; [pristineRemotePath release]; } sprintf(command, "DELE %s\r\n", [fileName cString]); [self writeLine:command]; replyCode = [self readReply:&reply]; NSLog(@"%d reply is %@: ", replyCode, [reply objectAtIndex:0]); [reply release]; } /* initialize a connection */ /* set up and connect the control socket */ - (int)connect:(int)port :(char *)server { struct hostent *hostentPtr; char *tempStr; socklentype addrLen; /* socklen_t on some systems? */ NSMutableArray *reply; NSLog(@"connect to %s : %d", server, port); if((hostentPtr = gethostbyname(server)) == NULL) { NSLog(@"Could not resolve %s", server); return ERR_COULDNT_RESOLVE; } BCOPY((char *)hostentPtr->h_addr, (char *)&remoteSockName.sin_addr, hostentPtr->h_length); remoteSockName.sin_family = PF_INET; remoteSockName.sin_port = htons(port); tempStr = inet_ntoa(remoteSockName.sin_addr); if ((controlSocket = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { perror("socket failed: "); return ERR_SOCKET_FAIL; } if (connect(controlSocket, (struct sockaddr*) &remoteSockName, sizeof(remoteSockName)) < 0) { perror("connect failed: "); return ERR_CONNECT_FAIL; } /* we retrieve now the local name of the created socked */ /* the local port is for example important as default data port */ addrLen = sizeof(localSockName); if (getsockname(controlSocket, (struct sockaddr *)&localSockName, &addrLen) < 0) { perror("ftpclient: getsockname"); return ERR_GESOCKNAME_FAIL; } initStream(&ctrlStream, controlSocket); if([self readReply :&reply] < 0) return ERR_READ_FAIL; [reply release]; return 0; } - (void)disconnect { NSMutableArray *reply; [self writeLine:"QUIT\r\n"]; [self readReply:&reply]; connected = NO; } - (int)authenticate:(char *)user :(char *)pass { char tempStr[MAX_CONTROL_BUFF]; NSMutableArray *reply; int replyCode; sprintf(tempStr, "USER %s\r\n", user); if ([self writeLine:tempStr] < 0) return -2; /* we couldn't write */ replyCode = [self readReply:&reply]; if (replyCode == 530) { NSLog(@"Not logged in: %@", [reply objectAtIndex:0]); [reply release]; [self disconnect]; return -1; } [reply release]; sprintf(tempStr, "PASS %s\r\n", pass); if ([self writeLine:tempStr byLoggingIt:NO] < 0) return -2; /* we couldn't write */ replyCode = [self readReply:&reply]; if (replyCode == 530) { NSLog(@"Not logged in: %@", [reply objectAtIndex:0]); [reply release]; [self disconnect]; return -1; } [reply release]; connected = YES; /* get home directory as dir we first connected to */ [self writeLine:"PWD\r\n"]; [self readReply:&reply]; if ([reply count] >= 1) { NSString *line; unsigned int length; unsigned int first; unsigned int last; unsigned int i; line = [reply objectAtIndex:0]; NSLog(@"pwd reply is: %@", line); length = [line length]; i = 0; while (i < length && ([line characterAtIndex:i] != '\"')) i++; first = i; if (first < length) { first++; i = length-1; while (i > 0 && ([line characterAtIndex:i] != '\"')) i--; last = i; homeDir = [[line substringWithRange: NSMakeRange(first, last-first)] retain]; NSLog(@"homedir: %@", homeDir); } else homeDir = nil; } return 0; } /* initialize the data connection */ - (int)initDataConn { socklentype addrLen; /* socklen_t on some systems ? */ int socketReuse; socketReuse = YES; /* passive mode */ if (usesPassive) { NSMutableArray *reply; int replyCode; NSScanner *addrScan; int a1, a2, a3, a4; int p1, p2; if ((dataSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { perror("socket in initDataConn"); return -1; } [self writeLine:"PASV\r\n"]; replyCode = [self readReply:&reply]; if (replyCode != 227) { NSLog(@"passive mode failed"); return -1; } NSLog(@"pasv reply is: %d %@", replyCode, [reply objectAtIndex:0]); addrScan = [NSScanner scannerWithString:[reply objectAtIndex:0]]; [addrScan setCharactersToBeSkipped:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; if ([addrScan scanInt:NULL] == NO) { NSLog(@"error while scanning pasv address"); return -1; } NSLog(@"skipped result code"); if ([addrScan scanInt:&a1] == NO) { NSLog(@"error while scanning pasv address"); return -1; } NSLog(@"got first"); if ([addrScan scanInt:&a2] == NO) { NSLog(@"error while scanning pasv address"); return -1; } NSLog(@"got second"); if ([addrScan scanInt:&a3] == NO) { NSLog(@"error while scanning pasv address"); return -1; } if ([addrScan scanInt:&a4] == NO) { NSLog(@"error while scanning pasv address"); return -1; } if ([addrScan scanInt:&p1] == NO) { NSLog(@"error while scanning pasv port"); return -1; } if ([addrScan scanInt:&p2] == NO) { NSLog(@"error while scanning pasv port"); return -1; } NSLog(@"read: %d %d %d %d : %d %d", a1, a2, a3, a4, p1, p2); dataSockName.sin_family = AF_INET; dataSockName.sin_addr.s_addr = htonl((a1 << 24) | (a2 << 16) | (a3 << 8) | a4); dataSockName.sin_port = htons((p1 << 8) | p2); if (connect(dataSocket, (struct sockaddr *) &dataSockName, sizeof(dataSockName)) < 0) { perror("connect in initDataConn"); return -1; } return 0; } /* active mode, default or PORT arbitrated */ dataSockName = localSockName; /* system picks up a port */ if (usesPorts == YES) dataSockName.sin_port = 0; if ((dataSocket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { perror("socket in initDataConn"); return -1; } /* if we use the default port, we set the option to reuse the port */ /* linux is happier if we set both ends that way */ if (usesPorts == NO) { if (setsockopt(dataSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuse, sizeof (socketReuse)) < 0) { perror("ftpclient: setsockopt (reuse address) on data"); } if (setsockopt(controlSocket, SOL_SOCKET, SO_REUSEADDR, &socketReuse, sizeof (socketReuse)) < 0) { perror("ftpclient: setsockopt (reuse address) on control"); } } if (bind(dataSocket, (struct sockaddr *)&dataSockName, sizeof (dataSockName)) < 0) { perror("ftpclient: bind"); return -1; } if (usesPorts == YES) { addrLen = sizeof (dataSockName); if (getsockname(dataSocket, (struct sockaddr *)&dataSockName, &addrLen) < 0) { perror("ftpclient: getsockname"); return -1; } } if (listen(dataSocket, 1) < 0) { perror("ftpclient: listen"); return -1; } if (usesPorts == YES) { union addrAccess { /* we use this union to extract the 8 bytes of an address */ struct in_addr sinAddr; unsigned char ipv4[4]; } addr; NSMutableArray *reply; char tempStr[256]; unsigned char p1, p2; int returnCode; unsigned int port; addr.sinAddr = dataSockName.sin_addr; port = ntohs(dataSockName.sin_port); p1 = (port & 0xFF00) >> 8; p2 = port & 0x00FF; sprintf(tempStr, "PORT %u,%u,%u,%u,%u,%u\r\n", addr.ipv4[0], addr.ipv4[1], addr.ipv4[2], addr.ipv4[3], p1, p2); [self writeLine:tempStr]; NSLog(@"port str: %s", tempStr); if ((returnCode = [self readReply:&reply]) != 200) { NSLog(@"error occoured in port command: %@", [reply objectAtIndex:0]); return -1; } } return 0; } - (int)initDataStream { struct sockaddr from; socklentype fromLen; fromLen = sizeof(from); if (usesPassive) { initStream(&dataStream, dataSocket); localSocket = dataSocket; } else { if ((localSocket = accept(dataSocket, &from, &fromLen)) < 0) { perror("accepting socket, initDataStream: "); } initStream(&dataStream, localSocket); } /* if (dataStream == NULL) { perror("data stream opening failed"); return -1; } */ NSLog(@"data stream open"); return 0; } - (int)closeDataConn { closesocket(dataSocket); return 0; } - (void)closeDataStream { // a passive localSocket is just a copy of the dataSocket if (usesPassive == NO) closesocket(localSocket); // apparently it is not true that fclose closes the underlying // descriptor, without closing dataSocket we got a bind error // at the next connection attempt [self closeDataConn]; } /* creates a new directory tries to guess if the given dir is relative (no starting /) or absolute Is this portable to non-unix OS's? */ - (BOOL)createNewDir:(NSString *)dir { NSString *remotePath; char command[MAX_CONTROL_BUFF]; char pathCStr[MAX_CONTROL_BUFF]; NSMutableArray *reply; int replyCode; if ([dir hasPrefix:@"/"]) { NSLog(@"%@ is an absolute path", dir); remotePath = dir; } else { NSLog(@"%@ is a relative path", dir); remotePath = [[self workingDir] stringByAppendingPathComponent:dir]; } [remotePath getCString:pathCStr]; sprintf(command, "MKD %s\r\n", pathCStr); [self writeLine:command]; replyCode = [self readReply:&reply]; if (replyCode == 257) return YES; else { NSLog(@"remote mkdir code: %d %@", replyCode, [reply objectAtIndex:0]); return NO; } } /* RM again: a better path limit is needed */ - (NSArray *)dirContents { int ch; char buff[MAX_DATA_BUFF]; int readBytes; enum states_m1 { READ, GOTR }; enum states_m1 state; NSMutableArray *listArr; FileElement *aFile; char path[4096]; NSMutableArray *reply; int replyCode; if (!connected) return nil; [workingDir getCString:path]; /* lets settle to a plain ascii standard type */ if ([self setTypeToA] < 0) { connected = NO; NSLog(@"Timed out."); return nil; } /* create an array with a reasonable starting size */ listArr = [NSMutableArray arrayWithCapacity:5]; [self initDataConn]; [self writeLine:"LIST\r\n"]; [self readReply:&reply]; if ([self initDataStream] < 0) return nil; /* read the directory listing, each line being CR-LF terminated */ state = READ; readBytes = 0; while ((ch = getChar(&dataStream)) != EOF) { if (ch == '\r') state = GOTR; else if (ch == '\n' && state == GOTR) { buff[readBytes] = '\0'; fprintf(stderr, "%s\n", buff); [self logIt:[NSString stringWithCString:buff]]; state = READ; /* reset the state for a new line */ readBytes = 0; aFile = [[FileElement alloc] initWithLsLine:buff]; if (aFile) [listArr addObject:aFile]; } else buff[readBytes++] = ch; } /* FIXME *********** if (ferror(dataStream)) { perror("error in reading data stream: "); } else if (feof(dataStream)) { fprintf(stderr, "feof\n"); } */ [self closeDataStream]; replyCode = [self readReply:&reply]; return [NSArray arrayWithArray:listArr]; } @end ftp.app-0.3/localclient.h000066400000000000000000000017301177253120400153710ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2007 Riccardo Mottola Author: Riccardo Mottola Created: 2005-04-09 Local filesystem class This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #import #import "client.h" @interface LocalClient : Client { } @end ftp.app-0.3/localclient.m000066400000000000000000000061261177253120400154020ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005-2011 Riccardo Mottola Author: Riccardo Mottola Created: 2005-04-09 Local filesystem class This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #import "localclient.h" #import "fileElement.h" @implementation LocalClient - (id)init { if (!(self = [super init])) return nil; homeDir = [NSHomeDirectory() retain]; return self; } /* creates a new directory tries to guess if the given dir is relative (no starting /) or absolute Is this portable to non-unix OS's? */ - (BOOL)createNewDir:(NSString *)dir { NSFileManager *fm; NSString *localPath; BOOL isDir; fm = [NSFileManager defaultManager]; if ([dir hasPrefix:@"/"]) { NSLog(@"%@ is an absolute path", dir); localPath = dir; } else { NSLog(@"%@ is a relative path", dir); localPath = [[self workingDir] stringByAppendingPathComponent:dir]; } if ([fm fileExistsAtPath:localPath isDirectory:&isDir] == YES) return isDir; if ([fm createDirectoryAtPath:localPath attributes:nil] == NO) return NO; else return YES; } - (NSArray *)dirContents { NSFileManager *fm; NSArray *fileNames; NSEnumerator *en; NSString *fileName; NSMutableArray *listArr; FileElement *aFile; fm = [NSFileManager defaultManager]; fileNames = [fm directoryContentsAtPath:workingDir]; if (fileNames == nil) return nil; listArr = [NSMutableArray arrayWithCapacity:[fileNames count]]; en = [fileNames objectEnumerator]; while ((fileName = [en nextObject])) { NSString *p; NSDictionary *attr; p = [workingDir stringByAppendingPathComponent:fileName]; attr = [fm fileAttributesAtPath :p traverseLink:YES]; aFile = [[FileElement alloc] initWithFileAttributes:fileName :attr]; [listArr addObject:aFile]; } return [NSArray arrayWithArray:listArr]; } - (void)deleteFile:(FileElement *)file beingAt:(int)depth { NSString *fileName; NSString *localPath; NSFileManager *fm; fm = [NSFileManager defaultManager]; fileName = [file filename]; localPath = [[self workingDir] stringByAppendingPathComponent:fileName]; if ([fm removeFileAtPath:(NSString *)localPath handler:nil] == NO) NSLog(@"an error occoured during local delete"); } @end ftp.app-0.3/main.m000066400000000000000000000017261177253120400140360ustar00rootroot00000000000000/* Project: FTP Copyright (C) 2005 Free Software Foundation Author: Created: 2005-03-30 09:43:03 +0200 by multix This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This application is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include int main(int argc, const char *argv[]) { return NSApplicationMain (argc, argv); }