PageRenderTime 33ms CodeModel.GetById 1ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/app/utils/CLI.m

http://github.com/tgunr/passengerpane
Objective C | 201 lines | 170 code | 30 blank | 1 comment | 30 complexity | 92213dc68d2dd1d5a55f2916de6697e5 MD5 | raw file
  1#import "CLI.h"
  2
  3@implementation CLI
  4
  5static id sharedCLI = nil;
  6
  7+ (id)sharedInstance{
  8  if (sharedCLI == nil) {
  9    sharedCLI = [[CLI alloc] init];
 10  }
 11  return sharedCLI;
 12}
 13
 14@synthesize appDelegate, pathToCLI;
 15
 16- (id)init {
 17  if ((self = [super init])) {
 18    authorizationRef = NULL;
 19  }
 20  return self;
 21}
 22
 23- (NSMutableArray *)listApplications {
 24  NSArray *result;
 25  Application *application;
 26  NSDictionary *attributes;
 27  NSMutableArray *applications;
 28  
 29  NSLog(@"Retrieving a list of configured applications");
 30  result = [self execute:[NSArray arrayWithObjects:@"list", @"-m", nil] elevated:NO];
 31  applications = [NSMutableArray arrayWithCapacity:[result count]];
 32  
 33  if ([result count] > 0) {
 34    for (attributes in result) {
 35      application = [[Application alloc] initWithAttributes:attributes];
 36      [application setDelegate:appDelegate];
 37      [applications addObject:application];
 38    }
 39  }
 40  
 41  return applications;
 42}
 43
 44- (void) add:(Application *)application {
 45  NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"add", application.path, nil];
 46  [arguments addObjectsFromArray:[application toArgumentArray]];
 47  NSLog(@"Adding application with hostname %@ using %@", application.host, arguments);
 48  [self execute:arguments elevated:YES];
 49  [application didApplyChanges];
 50}
 51
 52- (void) update:(Application *)application {
 53  NSDictionary *beforeChanges = [application beforeChanges];
 54  NSString *currentHost = [beforeChanges valueForKey:@"host"];
 55  NSMutableArray *arguments = [NSMutableArray arrayWithObjects:@"update", currentHost, nil];
 56  [arguments addObjectsFromArray:[application toArgumentArray]];
 57  NSLog(@"Updating application with hostname %@ using %@", application.host, arguments);
 58  [self execute:arguments elevated:YES];
 59  [application didApplyChanges];
 60}
 61
 62- (void) delete:(Application *)application {
 63  NSLog(@"Deleting application with hostname: %@", application.host);
 64  [self execute:[NSArray arrayWithObjects:@"delete", application.host, nil] elevated:YES];
 65}
 66
 67- (void) restart:(Application *)application {
 68  NSLog(@"Restarting application with hostname: %@", application.host);
 69  [self execute:[NSArray arrayWithObjects:@"restart", application.host, nil] elevated:NO];
 70}
 71
 72- (void) restart {
 73  NSLog(@"Restarting Apache");
 74  [self execute:[NSArray arrayWithObject:@"restart"] elevated:YES];
 75}
 76
 77- (BOOL) isPassengerModuleInstalled {
 78  NSLog(@"Checking if the Passenger module is installed");
 79  NSDictionary *info = [self execute:[NSArray arrayWithObjects:@"info", @"-m", nil] elevated:NO];
 80  if (info) {
 81    NSNumber *isInstalled = [info objectForKey:@"passenger_module_installed"];
 82    return [isInstalled boolValue];
 83  } else {
 84    NSLog(@"Failed to read info, assuming Passenger module isn't installed.");
 85    return NO;
 86  }
 87}
 88
 89// Inspired by: http://svn.kismac-ng.org/kmng/trunk/Subprojects/BIGeneric/BLAuthentication.m
 90- (id) execute:(NSArray *)arguments elevated:(BOOL)elevated {
 91  OSStatus status;
 92  char **argumentsAsCArray = NULL;
 93  unsigned int index;
 94  
 95  FILE *communicationPipe;
 96  NSFileHandle *file;
 97  NSData *data;
 98  NSError *error = nil;
 99  id result = nil;
100  
101  if (elevated) {
102    if ([self isAuthorized]) {
103      if ([arguments count] > 0) {
104        index = 0;
105        argumentsAsCArray = NSAllocateCollectable(sizeof(char*)*([arguments count]+1), 0);
106        while(index < [arguments count]) {
107          argumentsAsCArray[index++] = (char*)[[arguments objectAtIndex:index] UTF8String];
108        }
109        argumentsAsCArray[index] = NULL;
110      }
111      
112      status = AuthorizationExecuteWithPrivileges(authorizationRef, [pathToCLI UTF8String],
113                                                  kAuthorizationFlagDefaults, argumentsAsCArray,
114                                                  &communicationPipe);
115      
116      if (status == PPANE_SUCCESS) {
117        if (communicationPipe) {
118          file = [[NSFileHandle alloc] initWithFileDescriptor:fileno(communicationPipe)];
119          data = [file readDataToEndOfFile];
120          [file closeFile];
121          if ([data length] > 0) {
122            result = [[CJSONDeserializer deserializer] deserialize:data error:&error];
123            if (error) {
124              NSLog(@"ppane returned invalid JSON: %@", [error description]);
125            } else {
126              return result;
127            }
128         } else {
129            NSLog(@"ppane didn't return any information");
130          }
131        }
132      } else {
133        NSLog(@"AuthorizationExecuteWithPrivileges failed to execute ppane (%d)", status);
134      }
135    } else {
136      NSLog(@"Ignoring a privileged command because the pane isn't authorized");
137    }
138    return [NSDictionary dictionary];
139  } else {
140    return [self execute:arguments];
141  }
142}
143
144- (id)execute:(NSArray *)arguments {
145  NSData *data;
146  NSError *error = nil;
147  id result = nil;
148  
149  NSPipe *stdout = [NSPipe pipe];
150  NSTask *ppane;
151  
152  ppane = [[NSTask alloc] init];
153  [ppane setLaunchPath:pathToCLI];
154  [ppane setArguments:arguments];
155  [ppane setStandardOutput:stdout];
156  [ppane launch];
157  [ppane waitUntilExit];
158  
159  if ([ppane terminationStatus] == PPANE_SUCCESS) {
160    data = [[stdout fileHandleForReading] readDataToEndOfFile];
161    if ([data length] > 0) {
162      result = [[CJSONDeserializer deserializer] deserialize:data error:&error];
163      if (error) {
164        NSLog(@"ppane returned invalid JSON: %@", [error description]);
165      } else {
166        return result;
167      }
168    } else {
169      NSLog(@"ppane didn't return any data");
170    }
171  } else {
172    NSLog(@"NSTask failed to execute the command");
173  }
174  return [NSDictionary dictionary];
175}
176
177- (AuthorizationRef) authorizationRef {
178  return authorizationRef;
179}
180
181- (void) setAuthorizationRef:(AuthorizationRef)ref {
182  authorizationRef = ref;
183}
184
185- (void) deauthorize {
186  authorizationRef = NULL;
187}
188
189- (BOOL) isAuthorized {
190  if (authorizationRef == NULL) {
191    return NO;
192  } else  {
193    return YES;
194  }
195}
196
197- (void) fakeAuthorize {
198  AuthorizationCreate(nil, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
199}
200
201@end