324 lines
14 KiB
Objective-C
324 lines
14 KiB
Objective-C
//
|
|
// MGMSFTPPlugIn.m
|
|
// CocoaShare
|
|
//
|
|
// Created by Mr. Gecko on 1/26/11.
|
|
// Copyright (c) 2011 Mr. Gecko's Media (James Coleman). All rights reserved. http://mrgeckosmedia.com/
|
|
//
|
|
|
|
#import "MGMSFTPPlugIn.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 MGMSFTPHost = @"MGMSFTPHost";
|
|
NSString * const MGMSFTPUser = @"MGMSFTPUser";
|
|
NSString * const MGMSFTPPath = @"MGMSFTPPath";
|
|
NSString * const MGMSFTPURL = @"MGMSFTPURL";
|
|
|
|
@implementation MGMSFTPPlugIn
|
|
- (void)dealloc {
|
|
[self releaseView];
|
|
[filePath release];
|
|
[fileName release];
|
|
[SFTPTask terminate];
|
|
[SFTPTask release];
|
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
|
[SFTPPipe release];
|
|
[SFTPInputPipe release];
|
|
[super dealloc];
|
|
}
|
|
|
|
- (BOOL)isAccountPlugIn {
|
|
return YES;
|
|
}
|
|
- (NSString *)plugInName {
|
|
return @"SFTP (SSH)";
|
|
}
|
|
- (NSView *)plugInView {
|
|
if (view==nil) {
|
|
if (![NSBundle loadNibNamed:@"SFTPAccountPane" owner:self]) {
|
|
NSLog(@"Unable to load SFTP Account Pane");
|
|
} else {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
NSString *host = [defaults objectForKey:MGMSFTPHost];
|
|
if (host!=nil)
|
|
[hostField setStringValue:host];
|
|
NSString *user = [defaults objectForKey:MGMSFTPUser];
|
|
if (user!=nil)
|
|
[userField setStringValue:user];
|
|
NSString *password = [[MGMController sharedController] password];
|
|
if (password!=nil)
|
|
[passwordField setStringValue:password];
|
|
NSString *path = [defaults objectForKey:MGMSFTPPath];
|
|
if (path!=nil)
|
|
[pathField setStringValue:path];
|
|
NSString *url = [defaults objectForKey:MGMSFTPURL];
|
|
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:MGMSFTPHost];
|
|
[defaults removeObjectForKey:MGMSFTPUser];
|
|
[defaults removeObjectForKey:MGMSFTPPath];
|
|
[defaults removeObjectForKey:MGMSFTPURL];
|
|
}
|
|
}
|
|
|
|
- (void)lockLogin {
|
|
[hostField setEnabled:NO];
|
|
[userField setEnabled:NO];
|
|
[passwordField setEnabled:NO];
|
|
[pathField setEnabled:NO];
|
|
[urlField setEnabled:NO];
|
|
[loginButton setEnabled:NO];
|
|
[loginButton setTitle:[@"Logging In" localizedFor:self]];
|
|
}
|
|
- (void)unlockLogin {
|
|
[hostField setEnabled:YES];
|
|
[userField setEnabled:YES];
|
|
[passwordField setEnabled:YES];
|
|
[pathField setEnabled:YES];
|
|
[urlField setEnabled:YES];
|
|
[loginButton setEnabled:YES];
|
|
[loginButton setTitle:[@"Login" localizedFor:self]];
|
|
}
|
|
- (IBAction)login:(id)sender {
|
|
if ([[hostField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Host Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter your sftp host." localizedFor:self]];
|
|
[alert runModal];
|
|
} else if ([[userField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"UserName Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter your sftp username." localizedFor:self]];
|
|
[alert runModal];
|
|
} else if ([[urlField stringValue] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"URL Required" localizedFor:self]];
|
|
[alert setInformativeText:[@"Please enter the URL to where the files will be uploaded." localizedFor:self]];
|
|
[alert runModal];
|
|
} else {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[[MGMController sharedController] setPassword:[passwordField stringValue]];
|
|
[defaults setObject:[hostField stringValue] forKey:MGMSFTPHost];
|
|
[defaults setObject:[[userField stringValue] replace:@"@" with:@"+"] forKey:MGMSFTPUser];
|
|
[defaults setObject:[pathField stringValue] forKey:MGMSFTPPath];
|
|
[defaults setObject:[urlField stringValue] forKey:MGMSFTPURL];
|
|
[self lockLogin];
|
|
|
|
SFTPTask = [NSTask new];
|
|
[SFTPTask setLaunchPath:@"/usr/bin/ssh"];
|
|
NSString *user = [defaults objectForKey:MGMSFTPUser];
|
|
if (![[[MGMController sharedController] password] isEqual:@""])
|
|
user = [user stringByAppendingFormat:@":%@", [[MGMController sharedController] password]];
|
|
user = [user stringByAppendingFormat:@"@%@", [defaults objectForKey:MGMSFTPHost]];
|
|
[SFTPTask setArguments:[NSArray arrayWithObjects:@"-v", user, nil]];
|
|
|
|
SFTPPipe = [NSPipe new];
|
|
SFTPInputPipe = [NSPipe new];
|
|
[SFTPTask setStandardError:SFTPPipe];
|
|
[SFTPTask setStandardOutput:SFTPPipe];
|
|
[SFTPTask setStandardInput:SFTPInputPipe];
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter addObserver:self selector:@selector(loginTestExit:) name:NSTaskDidTerminateNotification object:SFTPTask];
|
|
[notificationCenter addObserver:self selector:@selector(loginTestRead:) name:NSFileHandleReadCompletionNotification object:[SFTPPipe fileHandleForReading]];
|
|
[[SFTPPipe fileHandleForReading] readInBackgroundAndNotify];
|
|
|
|
[SFTPTask launch];
|
|
}
|
|
}
|
|
- (void)loginTestExit:(NSNotification *)theNotification {
|
|
NSLog(@"SFTP Exited");
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter removeObserver:self name:NSTaskDidTerminateNotification object:SFTPTask];
|
|
[SFTPTask release];
|
|
SFTPTask = nil;
|
|
[notificationCenter removeObserver:self name:NSFileHandleReadCompletionNotification object:[SFTPPipe fileHandleForReading]];
|
|
[SFTPPipe release];
|
|
SFTPPipe = nil;
|
|
[SFTPInputPipe release];
|
|
SFTPInputPipe = nil;
|
|
|
|
if (![loginButton isEnabled]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:[@"Incorrect login info." localizedFor:self]];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
}
|
|
}
|
|
- (void)loginTestProcessSFTPString:(NSString *)theString {
|
|
//NSLog(@"%@", theString);
|
|
if ([theString rangeOfString:@"Entering interactive session"].location!=NSNotFound) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
if ([[defaults objectForKey:MGMSFTPPath] isEqual:@""]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Login Successful" localizedFor:self]];
|
|
[alert setInformativeText:[@"You have successfully logged into your account." localizedFor:self]];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
} else {
|
|
[[SFTPInputPipe fileHandleForWriting] writeData:[[NSString stringWithFormat:@"cd %@\n", [[defaults objectForKey:MGMSFTPPath] escapePath]] dataUsingEncoding:NSUTF8StringEncoding]];
|
|
[[SFTPInputPipe fileHandleForWriting] writeData:[@"echo $PWD\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
}
|
|
} else if ([theString hasPrefix:@"/"]) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
if ([[defaults objectForKey:MGMSFTPPath] hasPrefix:theString]) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Login Successful" localizedFor:self]];
|
|
[alert setInformativeText:[@"You have successfully logged into your account." localizedFor:self]];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
} else {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:[@"You have successfully logged into your account, but the path you have entered does not exist." localizedFor:self]];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
}
|
|
[[SFTPInputPipe fileHandleForWriting] writeData:[@"exit\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
|
} else if ([theString rangeOfString:@"Permission denied"].location!=NSNotFound) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:theString];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
} else if ([theString rangeOfString:@"Could not resolve"].location!=NSNotFound) {
|
|
NSAlert *alert = [[NSAlert new] autorelease];
|
|
[alert setMessageText:[@"Account Error" localizedFor:self]];
|
|
[alert setInformativeText:theString];
|
|
[alert runModal];
|
|
[self unlockLogin];
|
|
}
|
|
}
|
|
- (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 loginTestProcessSFTPString:[[components objectAtIndex:i] stringByTrimmingCharactersInSet:newline]];
|
|
}
|
|
[[theNotification object] readInBackgroundAndNotify];
|
|
}
|
|
|
|
- (void)sendFileAtPath:(NSString *)thePath withName:(NSString *)theName {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
if ([defaults objectForKey:MGMSFTPHost]==nil || [defaults objectForKey:MGMSFTPUser]==nil || [defaults objectForKey:MGMSFTPURL]==nil) {
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:5 userInfo:[NSDictionary dictionaryWithObject:[@"Account is not logged in." localizedFor:self] forKey:NSLocalizedDescriptionKey]];
|
|
[[MGMController sharedController] upload:thePath receivedError:error];
|
|
return;
|
|
}
|
|
|
|
[filePath release];
|
|
filePath = [thePath retain];
|
|
[fileName release];
|
|
fileName = [theName retain];
|
|
SFTPTask = [NSTask new];
|
|
[SFTPTask setLaunchPath:@"/usr/bin/scp"];
|
|
[SFTPTask setCurrentDirectoryPath:[filePath stringByDeletingLastPathComponent]];
|
|
NSString *user = [defaults objectForKey:MGMSFTPUser];
|
|
if (![[[MGMController sharedController] password] isEqual:@""])
|
|
user = [user stringByAppendingFormat:@":%@", [[MGMController sharedController] password]];
|
|
user = [user stringByAppendingFormat:@"@%@", [defaults objectForKey:MGMSFTPHost]];
|
|
user = [user stringByAppendingFormat:@":%@", ([[defaults objectForKey:MGMSFTPPath] isEqual:@""] ? fileName : [[defaults objectForKey:MGMSFTPPath] stringByAppendingPathComponent:fileName])];
|
|
[SFTPTask setArguments:[NSArray arrayWithObjects:@"-v", [filePath lastPathComponent], user, nil]];
|
|
|
|
SFTPPipe = [NSPipe new];
|
|
SFTPInputPipe = [NSPipe new];
|
|
[SFTPTask setStandardError:SFTPPipe];
|
|
[SFTPTask setStandardOutput:SFTPPipe];
|
|
[SFTPTask setStandardInput:SFTPInputPipe];
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter addObserver:self selector:@selector(uploadExit:) name:NSTaskDidTerminateNotification object:SFTPTask];
|
|
[notificationCenter addObserver:self selector:@selector(uploadRead:) name:NSFileHandleReadCompletionNotification object:[SFTPPipe fileHandleForReading]];
|
|
[[SFTPPipe fileHandleForReading] readInBackgroundAndNotify];
|
|
|
|
[SFTPTask launch];
|
|
}
|
|
- (void)uploadExit:(NSNotification *)theNotification {
|
|
NSLog(@"SFTP Exited");
|
|
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
|
[notificationCenter removeObserver:self name:NSTaskDidTerminateNotification object:SFTPTask];
|
|
[SFTPTask release];
|
|
SFTPTask = nil;
|
|
[notificationCenter removeObserver:self name:NSFileHandleReadCompletionNotification object:[SFTPPipe fileHandleForReading]];
|
|
[SFTPPipe release];
|
|
SFTPPipe = nil;
|
|
[SFTPInputPipe release];
|
|
SFTPInputPipe = nil;
|
|
|
|
if (theNotification!=nil) {
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:[@"Incorrect login info" localizedFor:self] forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
}
|
|
}
|
|
- (void)uploadProcessSFTPString:(NSString *)theString {
|
|
//NSLog(@"%@", theString);
|
|
if ([theString rangeOfString:@"exit-status"].location!=NSNotFound) {
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
|
[self uploadExit:nil];
|
|
NSString *url = [defaults objectForKey:MGMSFTPURL];
|
|
if (![url hasSuffix:@"/"])
|
|
url = [url stringByAppendingFormat:@"/%@", [fileName addPercentEscapes]];
|
|
else
|
|
url = [url stringByAppendingString:[fileName addPercentEscapes]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] uploadFinished:finishPath url:[NSURL URLWithString:url]];
|
|
} else if ([theString rangeOfString:@"Permission denied"].location!=NSNotFound) {
|
|
[self uploadExit:nil];
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:theString forKey:NSLocalizedDescriptionKey]];
|
|
NSString *finishPath = [[filePath retain] autorelease];
|
|
[filePath release];
|
|
filePath = nil;
|
|
[fileName release];
|
|
fileName = nil;
|
|
[[MGMController sharedController] upload:finishPath receivedError:error];
|
|
} else if ([theString rangeOfString:@"Could not resolve"].location!=NSNotFound) {
|
|
[self uploadExit:nil];
|
|
NSError *error = [NSError errorWithDomain:[[NSBundle bundleForClass:[self class]] bundleIdentifier] code:1 userInfo:[NSDictionary dictionaryWithObject:theString 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 uploadProcessSFTPString:[[components objectAtIndex:i] stringByTrimmingCharactersInSet:newline]];
|
|
}
|
|
[[theNotification object] readInBackgroundAndNotify];
|
|
}
|
|
@end |