/.attic/sshfs-gui/AppController.m

http://macfuse.googlecode.com/ · Objective C · 190 lines · 135 code · 31 blank · 24 comment · 14 complexity · 121f35172e8538c8621f0744bb0425dd MD5 · raw file

  1. // Copyright (C) 2007 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import "AppController.h"
  15. #import "DiskImageUtilities.h"
  16. #import <Cocoa/Cocoa.h>
  17. #import "GoogleShared_SystemVersion.h"
  18. #include <stdlib.h>
  19. #include <sys/param.h>
  20. #include <sys/mount.h>
  21. #define kRecentCount 10 // NSDocumentController's _recentsLimit ivar
  22. #define kRecentServers @"recentservers"
  23. #define kServerName @"server"
  24. #define kUsernameName @"username"
  25. #define kPathName @"pathname"
  26. @implementation AppController
  27. - (void)applicationWillFinishLaunching:(NSNotification *)notification {
  28. [DiskImageUtilities handleApplicationLaunchFromReadOnlyDiskImage];
  29. }
  30. - (void)applicationDidFinishLaunching:(NSNotification *)notification {
  31. [self showConnect:self];
  32. }
  33. - (IBAction)showConnect:(id)sender {
  34. int connectResult = [NSApp runModalForWindow:connectPanel_];
  35. if (connectResult == NSRunAbortedResponse) {
  36. [connectPanel_ orderOut:self];
  37. return;
  38. }
  39. NSString *server = [serverField_ stringValue];
  40. NSString *username = [usernameField_ stringValue];
  41. NSString *path = [pathField_ stringValue];
  42. [connectPanel_ orderOut:self];
  43. [self sshConnect:server username:username path:path];
  44. }
  45. - (IBAction)connectCancel:(id)sender {
  46. [NSApp abortModal];
  47. }
  48. - (IBAction)connectOK:(id)sender {
  49. [NSApp stopModal];
  50. }
  51. - (void)sshConnect:(NSString *)server
  52. username:(NSString *)username
  53. path:(NSString *)path {
  54. // create a folder in /Volumes
  55. NSFileManager *fileManager = [NSFileManager defaultManager];
  56. NSString *mountpoint = [NSString stringWithFormat:@"/Volumes/%@", server];
  57. int tries = 0;
  58. while ([fileManager fileExistsAtPath:mountpoint])
  59. mountpoint = [NSString stringWithFormat:@"/Volumes/%@ %d", server, ++tries];
  60. [fileManager createDirectoryAtPath:mountpoint attributes:nil];
  61. // setup for task
  62. NSString *askPassPath = [[NSBundle mainBundle] pathForResource:@"askpass"
  63. ofType:@""];
  64. NSString *sshfsPath = [[NSBundle mainBundle] pathForResource:@"sshfs-static"
  65. ofType:@""];
  66. if ([GoogleShared_SystemVersion isLeopard]) {
  67. sshfsPath = [sshfsPath stringByAppendingString:@"-10.5"];
  68. }
  69. NSDictionary *sshfsEnv = [NSDictionary dictionaryWithObjectsAndKeys:
  70. @"NONE", @"DISPLAY", // I know "NONE" is bogus; I just need something
  71. askPassPath, @"SSH_ASKPASS",
  72. nil];
  73. NSArray *sshfsArgs = [NSArray arrayWithObjects:
  74. [NSString stringWithFormat:@"%@@%@:%@", username, server, path],
  75. [NSString stringWithFormat:@"-ovolname=%@", server],
  76. @"-oping_diskarb",
  77. @"-oreconnect",
  78. @"-oNumberOfPasswordPrompts=1",
  79. mountpoint,
  80. nil
  81. ];
  82. // fire it off
  83. NSTask *sshfsTask = [[[NSTask alloc] init] autorelease];
  84. [sshfsTask setLaunchPath:sshfsPath];
  85. [sshfsTask setArguments:sshfsArgs];
  86. [sshfsTask setEnvironment:sshfsEnv];
  87. [sshfsTask launch];
  88. [sshfsTask waitUntilExit];
  89. if ([sshfsTask terminationStatus]) {
  90. [fileManager removeFileAtPath:mountpoint handler:nil];
  91. }
  92. else {
  93. [self addToRecents:server username:username path:path];
  94. }
  95. }
  96. - (IBAction)clearRecents:(id)sender {
  97. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  98. [userDefaults setObject:[NSArray array] forKey:kRecentServers];
  99. }
  100. - (void)addToRecents:(NSString *)server
  101. username:(NSString *)username
  102. path:(NSString *)path {
  103. // make the item
  104. NSDictionary *newRecentItem = [NSDictionary dictionaryWithObjectsAndKeys:
  105. server, kServerName, username, kUsernameName, path, kPathName, nil];
  106. // get our list
  107. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  108. NSArray *oldRecents = [userDefaults arrayForKey:kRecentServers];
  109. if (!oldRecents)
  110. oldRecents = [NSArray array];
  111. // we don't want dups, so remove it if it's already there
  112. NSMutableArray *newRecents = [NSMutableArray arrayWithArray:oldRecents];
  113. [newRecents removeObject:newRecentItem];
  114. // insert and save
  115. [newRecents insertObject:newRecentItem atIndex:0];
  116. if ([newRecents count] > kRecentCount)
  117. [newRecents removeObjectsInRange:
  118. NSMakeRange(kRecentCount, [newRecents count] - kRecentCount)];
  119. [userDefaults setObject:newRecents forKey:kRecentServers];
  120. }
  121. - (void)menuNeedsUpdate:(NSMenu *)menu {
  122. // pull out all the old menu items
  123. NSMenuItem *item = [menu itemAtIndex:0];
  124. while ([item representedObject] != nil || [item isSeparatorItem]) {
  125. [menu removeItemAtIndex:0];
  126. item = [menu itemAtIndex:0];
  127. }
  128. // get the new items
  129. NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
  130. NSArray *recents = [userDefaults arrayForKey:kRecentServers];
  131. if (!recents)
  132. recents = [NSArray array];
  133. // put them in
  134. for (int i=0; i < [recents count]; ++i) {
  135. NSDictionary *recent = [recents objectAtIndex:i];
  136. NSString *recentName = [NSString stringWithFormat:@"%@ %C %@ %C %@",
  137. [recent objectForKey:kServerName], 0x00B7,
  138. [recent objectForKey:kUsernameName], 0x00B7,
  139. [recent objectForKey:kPathName]];
  140. NSMenuItem *recentMenuItem =
  141. [[[NSMenuItem alloc] initWithTitle:recentName
  142. action:@selector(connectToRecent:)
  143. keyEquivalent:@""] autorelease];
  144. [recentMenuItem setTarget:self];
  145. [recentMenuItem setRepresentedObject:recent];
  146. [menu insertItem:recentMenuItem atIndex:i];
  147. }
  148. // put in a separator if we put any items in
  149. if ([recents count]) {
  150. [menu insertItem:[NSMenuItem separatorItem] atIndex:[recents count]];
  151. }
  152. }
  153. - (void)connectToRecent:(id)sender {
  154. NSDictionary *connect = [sender representedObject];
  155. [self sshConnect:[connect objectForKey:kServerName]
  156. username:[connect objectForKey:kUsernameName]
  157. path:[connect objectForKey:kPathName]];
  158. }
  159. @end