2011-02-01 09:51:02 -06:00
//
// MGMFTPPlugIn . m
// CocoaShare
//
2011-02-02 14:58:24 -06:00
// Created by Mr . Gecko on 1 / 25 / 11.
2011-02-01 09:51:02 -06:00
// Copyright ( c ) 2011 Mr . Gecko ' s Media ( James Coleman ) . All rights reserved . http : // mrgeckosmedia . com /
//
# import "MGMFTPPlugIn.h"
# import "MGMController.h"
# import "MGMAddons.h"
NSString * const MGMCopyright = @ "Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/" ;
NSString * const MGMFTPHost = @ "MGMFTPHost" ;
NSString * const MGMFTPUser = @ "MGMFTPUser" ;
NSString * const MGMFTPPath = @ "MGMFTPPath" ;
NSString * const MGMFTPURL = @ "MGMFTPURL" ;
@ implementation MGMFTPPlugIn
- ( void ) dealloc {
[ self releaseView ] ;
[ filePath release ] ;
[ fileName release ] ;
[ FTPTask terminate ] ;
[ FTPTask release ] ;
[ [ NSNotificationCenter defaultCenter ] removeObserver : self ] ;
[ FTPPipe release ] ;
[ FTPInputPipe release ] ;
[ super dealloc ] ;
}
- ( BOOL ) isAccountPlugIn {
return YES ;
}
- ( NSString * ) plugInName {
return @ "FTP" ;
}
- ( NSView * ) plugInView {
if ( view = = nil ) {
if ( ! [ NSBundle loadNibNamed : @ "FTPAccountPane" owner : self ] ) {
NSLog ( @ "Unable to load FTP Account Pane" ) ;
} else {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
NSString * host = [ defaults objectForKey : MGMFTPHost ] ;
if ( host ! = nil )
[ hostField setStringValue : host ] ;
NSString * user = [ defaults objectForKey : MGMFTPUser ] ;
if ( user ! = nil )
[ userField setStringValue : user ] ;
NSString * password = [ [ MGMController sharedController ] password ] ;
if ( password ! = nil )
[ passwordField setStringValue : password ] ;
NSString * path = [ defaults objectForKey : MGMFTPPath ] ;
if ( path ! = nil )
[ pathField setStringValue : path ] ;
NSString * url = [ defaults objectForKey : MGMFTPURL ] ;
if ( url ! = nil )
[ urlField setStringValue : url ] ;
}
}
return view ;
}
- ( void ) releaseView {
[ view release ] ;
view = nil ;
hostField = nil ;
userField = nil ;
passwordField = nil ;
pathField = nil ;
urlField = nil ;
loginButton = nil ;
}
- ( void ) setCurrentPlugIn : ( BOOL ) isCurrent {
if ( ! isCurrent ) {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
[ defaults removeObjectForKey : MGMFTPHost ] ;
[ defaults removeObjectForKey : MGMFTPUser ] ;
[ defaults removeObjectForKey : MGMFTPPath ] ;
[ defaults removeObjectForKey : MGMFTPURL ] ;
}
}
- ( void ) lockLogin {
[ hostField setEnabled : NO ] ;
[ userField setEnabled : NO ] ;
[ passwordField setEnabled : NO ] ;
[ pathField setEnabled : NO ] ;
[ urlField setEnabled : NO ] ;
[ loginButton setEnabled : NO ] ;
2011-02-02 14:58:24 -06:00
[ loginButton setTitle : [ @ "Logging In" localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
}
- ( void ) unlockLogin {
[ hostField setEnabled : YES ] ;
[ userField setEnabled : YES ] ;
[ passwordField setEnabled : YES ] ;
[ pathField setEnabled : YES ] ;
[ urlField setEnabled : YES ] ;
[ loginButton setEnabled : YES ] ;
2011-02-02 14:58:24 -06:00
[ loginButton setTitle : [ @ "Login" localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
}
- ( IBAction ) login : ( id ) sender {
if ( [ [ hostField stringValue ] isEqual : @ "" ] ) {
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Host Required" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "Please enter your host." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
} else if ( [ [ userField stringValue ] isEqual : @ "" ] ) {
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "UserName Required" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "Please enter your username." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
} else if ( [ [ passwordField stringValue ] isEqual : @ "" ] ) {
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Password Required" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "Please enter your password." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
} else if ( [ [ urlField stringValue ] isEqual : @ "" ] ) {
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "URL Required" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "Please enter the URL to where the files will be uploaded." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
} else {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
[ [ MGMController sharedController ] setPassword : [ passwordField stringValue ] ] ;
[ defaults setObject : [ hostField stringValue ] forKey : MGMFTPHost ] ;
[ defaults setObject : [ userField stringValue ] forKey : MGMFTPUser ] ;
[ defaults setObject : [ pathField stringValue ] forKey : MGMFTPPath ] ;
[ defaults setObject : [ urlField stringValue ] forKey : MGMFTPURL ] ;
[ self lockLogin ] ;
FTPTask = [ NSTask new ] ;
[ FTPTask setLaunchPath : @ "/usr/bin/ftp" ] ;
[ FTPTask setArguments : [ NSArray arrayWithObjects : @ "-v" , [ NSString stringWithFormat : @ "ftp://%@:%@@%@" , [ defaults objectForKey : MGMFTPUser ] , [ [ MGMController sharedController ] password ] , [ defaults objectForKey : MGMFTPHost ] ] , nil ] ] ;
FTPPipe = [ NSPipe new ] ;
FTPInputPipe = [ NSPipe new ] ;
[ FTPTask setStandardError : FTPPipe ] ;
[ FTPTask setStandardOutput : FTPPipe ] ;
[ FTPTask setStandardInput : FTPInputPipe ] ;
NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter ] ;
[ notificationCenter addObserver : self selector : @ selector ( loginTestExit : ) name : NSTaskDidTerminateNotification object : FTPTask ] ;
[ notificationCenter addObserver : self selector : @ selector ( loginTestRead : ) name : NSFileHandleReadCompletionNotification object : [ FTPPipe fileHandleForReading ] ] ;
[ [ FTPPipe fileHandleForReading ] readInBackgroundAndNotify ] ;
[ FTPTask launch ] ;
}
}
- ( void ) loginTestExit : ( NSNotification * ) theNotification {
NSLog ( @ "FTP Exited" ) ;
NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter ] ;
[ notificationCenter removeObserver : self name : NSTaskDidTerminateNotification object : FTPTask ] ;
[ FTPTask release ] ;
FTPTask = nil ;
[ notificationCenter removeObserver : self name : NSFileHandleReadCompletionNotification object : [ FTPPipe fileHandleForReading ] ] ;
[ FTPPipe release ] ;
FTPPipe = nil ;
[ FTPInputPipe release ] ;
FTPInputPipe = nil ;
if ( ! [ loginButton isEnabled ] ) {
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Account Error" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "Incorrect login info." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
[ self unlockLogin ] ;
}
}
- ( void ) loginTestProcessFTPString : ( NSString * ) theString {
// NSLog ( @ "%@" , theString ) ;
NSCharacterSet * whiteSpace = [ NSCharacterSet whitespaceCharacterSet ] ;
NSRange range = [ theString rangeOfCharacterFromSet : whiteSpace ] ;
if ( range . location ! = NSNotFound ) {
int response = [ [ theString substringToIndex : range . location ] intValue ] ;
NSString * message = [ theString substringFromIndex : range . location + range . length ] ;
if ( response = = 250 ) {
[ self unlockLogin ] ;
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Login Successful" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "You have sucessfully logged into your account." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
} else if ( response = = 550 ) {
[ self unlockLogin ] ;
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Account Error" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "You have sucessfully logged into your account, but the path you have entered does not exist." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
} else if ( response = = 230 ) {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
if ( [ [ defaults objectForKey : MGMFTPPath ] isEqual : @ "" ] ) {
[ self unlockLogin ] ;
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Login Successful" localizedFor : self ] ] ;
[ alert setInformativeText : [ @ "You have sucessfully logged into your account." localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert runModal ] ;
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
} else {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ [ NSString stringWithFormat : @ "cd %@\n" , [ [ defaults objectForKey : MGMFTPPath ] escapePath ] ] dataUsingEncoding : NSUTF8StringEncoding ] ] ;
}
} else if ( response = = 530 ) {
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
[ self unlockLogin ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Account Error" localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert setInformativeText : message ] ;
[ alert runModal ] ;
} else if ( [ message rangeOfString : @ "Can't connect or login to host" ] . location ! = NSNotFound && ! [ loginButton isEnabled ] ) {
[ self unlockLogin ] ;
NSAlert * alert = [ [ NSAlert new ] autorelease ] ;
2011-02-02 14:58:24 -06:00
[ alert setMessageText : [ @ "Account Error" localizedFor : self ] ] ;
2011-02-01 09:51:02 -06:00
[ alert setInformativeText : message ] ;
[ alert runModal ] ;
}
}
}
- ( void ) loginTestRead : ( NSNotification * ) theNotification {
NSData * data = [ [ theNotification userInfo ] objectForKey : NSFileHandleNotificationDataItem ] ;
NSString * dataString = [ [ [ NSString alloc ] initWithData : data encoding : NSUTF8StringEncoding ] autorelease ] ;
NSArray * components = [ dataString componentsSeparatedByString : @ "\n" ] ;
NSCharacterSet * newline = [ NSCharacterSet newlineCharacterSet ] ;
for ( int i = 0 ; i < [ components count ] ; i + + ) {
[ self loginTestProcessFTPString : [ [ components objectAtIndex : i ] stringByTrimmingCharactersInSet : newline ] ] ;
}
[ [ theNotification object ] readInBackgroundAndNotify ] ;
}
- ( void ) sendFileAtPath : ( NSString * ) thePath withName : ( NSString * ) theName {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
if ( [ defaults objectForKey : MGMFTPHost ] = = nil || [ defaults objectForKey : MGMFTPUser ] = = nil || [ defaults objectForKey : MGMFTPURL ] = = nil ) {
2011-02-02 14:58:24 -06:00
NSError * error = [ NSError errorWithDomain : [ [ NSBundle bundleForClass : [ self class ] ] bundleIdentifier ] code : 5 userInfo : [ NSDictionary dictionaryWithObject : [ @ "Account is not logged in." localizedFor : self ] forKey : NSLocalizedDescriptionKey ] ] ;
2011-02-01 09:51:02 -06:00
[ [ MGMController sharedController ] upload : thePath receivedError : error ] ;
return ;
}
[ filePath release ] ;
filePath = [ thePath retain ] ;
[ fileName release ] ;
fileName = [ theName retain ] ;
FTPTask = [ NSTask new ] ;
[ FTPTask setLaunchPath : @ "/usr/bin/ftp" ] ;
[ FTPTask setCurrentDirectoryPath : [ filePath stringByDeletingLastPathComponent ] ] ;
[ FTPTask setArguments : [ NSArray arrayWithObjects : @ "-v" , [ NSString stringWithFormat : @ "ftp://%@:%@@%@" , [ defaults objectForKey : MGMFTPUser ] , [ [ MGMController sharedController ] password ] , [ defaults objectForKey : MGMFTPHost ] ] , nil ] ] ;
FTPPipe = [ NSPipe new ] ;
FTPInputPipe = [ NSPipe new ] ;
[ FTPTask setStandardError : FTPPipe ] ;
[ FTPTask setStandardOutput : FTPPipe ] ;
[ FTPTask setStandardInput : FTPInputPipe ] ;
NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter ] ;
[ notificationCenter addObserver : self selector : @ selector ( uploadExit : ) name : NSTaskDidTerminateNotification object : FTPTask ] ;
[ notificationCenter addObserver : self selector : @ selector ( uploadRead : ) name : NSFileHandleReadCompletionNotification object : [ FTPPipe fileHandleForReading ] ] ;
[ [ FTPPipe fileHandleForReading ] readInBackgroundAndNotify ] ;
[ FTPTask launch ] ;
}
- ( void ) uploadExit : ( NSNotification * ) theNotification {
NSLog ( @ "FTP Exited" ) ;
NSNotificationCenter * notificationCenter = [ NSNotificationCenter defaultCenter ] ;
[ notificationCenter removeObserver : self name : NSTaskDidTerminateNotification object : FTPTask ] ;
[ FTPTask release ] ;
FTPTask = nil ;
[ notificationCenter removeObserver : self name : NSFileHandleReadCompletionNotification object : [ FTPPipe fileHandleForReading ] ] ;
[ FTPPipe release ] ;
FTPPipe = nil ;
[ FTPInputPipe release ] ;
FTPInputPipe = nil ;
if ( theNotification ! = nil ) {
2011-02-02 14:58:24 -06:00
NSError * error = [ NSError errorWithDomain : [ [ NSBundle bundleForClass : [ self class ] ] bundleIdentifier ] code : 1 userInfo : [ NSDictionary dictionaryWithObject : [ @ "Incorrect login info." localizedFor : self ] forKey : NSLocalizedDescriptionKey ] ] ;
2011-02-01 09:51:02 -06:00
NSString * finishPath = [ [ filePath retain ] autorelease ] ;
[ filePath release ] ;
filePath = nil ;
[ fileName release ] ;
fileName = nil ;
[ [ MGMController sharedController ] upload : finishPath receivedError : error ] ;
}
}
- ( void ) uploadProcessFTPString : ( NSString * ) theString {
// NSLog ( @ "%@" , theString ) ;
NSCharacterSet * whiteSpace = [ NSCharacterSet whitespaceCharacterSet ] ;
NSRange range = [ theString rangeOfCharacterFromSet : whiteSpace ] ;
if ( range . location ! = NSNotFound ) {
int response = [ [ theString substringToIndex : range . location ] intValue ] ;
NSString * message = [ theString substringFromIndex : range . location + range . length ] ;
if ( response = = 250 ) {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ [ NSString stringWithFormat : @ "put %@ %@\n" , [ [ filePath lastPathComponent ] escapePath ] , [ fileName escapePath ] ] dataUsingEncoding : NSUTF8StringEncoding ] ] ;
} else if ( response = = 226 ) {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
[ self uploadExit : nil ] ;
NSString * url = [ defaults objectForKey : MGMFTPURL ] ;
if ( ! [ url hasSuffix : @ "/" ] )
url = [ url stringByAppendingFormat : @ "/%@" , fileName ] ;
else
url = [ url stringByAppendingString : fileName ] ;
NSString * finishPath = [ [ filePath retain ] autorelease ] ;
[ filePath release ] ;
filePath = nil ;
[ fileName release ] ;
fileName = nil ;
[ [ MGMController sharedController ] uploadFinished : finishPath url : [ NSURL URLWithString : url ] ] ;
} else if ( response = = 550 ) {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
[ self uploadExit : nil ] ;
2011-02-02 14:58:24 -06:00
NSError * error = [ NSError errorWithDomain : [ [ NSBundle bundleForClass : [ self class ] ] bundleIdentifier ] code : 1 userInfo : [ NSDictionary dictionaryWithObject : [ @ "The path to upload files to does not exist." localizedFor : self ] forKey : NSLocalizedDescriptionKey ] ] ;
2011-02-01 09:51:02 -06:00
NSString * finishPath = [ [ filePath retain ] autorelease ] ;
[ filePath release ] ;
filePath = nil ;
[ fileName release ] ;
fileName = nil ;
[ [ MGMController sharedController ] upload : finishPath receivedError : error ] ;
} else if ( response = = 421 ) {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
[ self uploadExit : nil ] ;
NSError * error = [ NSError errorWithDomain : [ [ NSBundle bundleForClass : [ self class ] ] bundleIdentifier ] code : 1 userInfo : [ NSDictionary dictionaryWithObject : message forKey : NSLocalizedDescriptionKey ] ] ;
NSString * finishPath = [ [ filePath retain ] autorelease ] ;
[ filePath release ] ;
filePath = nil ;
[ fileName release ] ;
fileName = nil ;
[ [ MGMController sharedController ] upload : finishPath receivedError : error ] ;
} else if ( response = = 230 ) {
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
if ( [ [ defaults objectForKey : MGMFTPPath ] isEqual : @ "" ] ) {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ [ NSString stringWithFormat : @ "put %@ %@\n" , [ [ filePath lastPathComponent ] escapePath ] , [ fileName escapePath ] ] dataUsingEncoding : NSUTF8StringEncoding ] ] ;
} else {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ [ NSString stringWithFormat : @ "cd %@\n" , [ [ defaults objectForKey : MGMFTPPath ] escapePath ] ] dataUsingEncoding : NSUTF8StringEncoding ] ] ;
}
} else if ( [ message rangeOfString : @ "Can't connect or login to host" ] . location ! = NSNotFound ) {
NSError * error = [ NSError errorWithDomain : [ [ NSBundle bundleForClass : [ self class ] ] bundleIdentifier ] code : 1 userInfo : [ NSDictionary dictionaryWithObject : message forKey : NSLocalizedDescriptionKey ] ] ;
NSString * finishPath = [ [ filePath retain ] autorelease ] ;
[ filePath release ] ;
filePath = nil ;
[ fileName release ] ;
fileName = nil ;
[ [ MGMController sharedController ] upload : finishPath receivedError : error ] ;
} else if ( [ message rangeOfString : @ "Can't open" ] . location ! = NSNotFound ) {
[ [ FTPInputPipe fileHandleForWriting ] writeData : [ @ "bye\n" dataUsingEncoding : NSUTF8StringEncoding ] ] ;
[ self uploadExit : nil ] ;
NSError * error = [ NSError errorWithDomain : [ [ NSBundle bundleForClass : [ self class ] ] bundleIdentifier ] code : 1 userInfo : [ NSDictionary dictionaryWithObject : message forKey : NSLocalizedDescriptionKey ] ] ;
NSString * finishPath = [ [ filePath retain ] autorelease ] ;
[ filePath release ] ;
filePath = nil ;
[ fileName release ] ;
fileName = nil ;
[ [ MGMController sharedController ] upload : finishPath receivedError : error ] ;
}
}
}
- ( void ) uploadRead : ( NSNotification * ) theNotification {
NSData * data = [ [ theNotification userInfo ] objectForKey : NSFileHandleNotificationDataItem ] ;
NSString * dataString = [ [ [ NSString alloc ] initWithData : data encoding : NSUTF8StringEncoding ] autorelease ] ;
NSArray * components = [ dataString componentsSeparatedByString : @ "\n" ] ;
NSCharacterSet * newline = [ NSCharacterSet newlineCharacterSet ] ;
for ( int i = 0 ; i < [ components count ] ; i + + ) {
[ self uploadProcessFTPString : [ [ components objectAtIndex : i ] stringByTrimmingCharactersInSet : newline ] ] ;
}
[ [ theNotification object ] readInBackgroundAndNotify ] ;
}
@ end