osx: let prefpane knows where binaries can be found
[openafs.git] / src / platform / DARWIN / AFSPreference / TaskUtil.m
1 //
2 //  TaskUtil.m
3 //  AFSCommander
4 //
5 //  Created by Claudio Bisegni on 25/06/07.
6 //  Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved.
7 //
8
9 #import "TaskUtil.h"
10 #import "AuthUtil.h"
11
12
13 @implementation TaskUtil
14
15 // -------------------------------------------------------------------------------
16 //  executeTaskSearchingPath:
17 // -------------------------------------------------------------------------------
18 +(NSString*) executeTaskSearchingPath:(NSString*)unixCommand args:(NSArray*)args
19 {
20         NSString *commResult = nil;
21         NSString *commPath = [self searchExecutablePath:unixCommand];
22         if(commPath != nil){
23                 commResult = [self executeTask:commPath
24                                                    arguments:args];
25         }
26         return commResult;      
27 }
28
29 // -------------------------------------------------------------------------------
30 //  executeTask:
31 // -------------------------------------------------------------------------------
32 +(NSString*) searchExecutablePath:(NSString*)unixCommand
33 {
34         NSString *commPath = [self executeTask:@"/usr/bin/which" arguments:[NSArray arrayWithObjects:unixCommand, nil]];
35         return commPath;        
36 }
37
38 // -------------------------------------------------------------------------------
39 //  executeTask:
40 // -------------------------------------------------------------------------------
41 +(NSString*) executeTask:(NSString*) taskName arguments:(NSArray *)args{
42         NSString *result = nil;
43         int status = 0;
44         NSFileHandle *file = nil;
45         NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys: @"$PATH:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/opt/openafs/bin:/opt/openafs/sbin",@"PATH",nil];
46                 
47         NSPipe *pipe = [NSPipe pipe];
48         NSTask *taskToRun  = [[NSTask alloc] init];
49         
50         [taskToRun setLaunchPath: taskName];
51         [taskToRun setArguments: args];
52         [taskToRun setEnvironment:environment];
53         [taskToRun setStandardOutput: pipe];
54         file = [pipe fileHandleForReading];
55         [taskToRun launch];
56         [taskToRun waitUntilExit];
57         status = [taskToRun terminationStatus];
58         if (status == 0){
59                 NSData *data = [file readDataToEndOfFile];
60                 // remove the \n character from unix command
61                 if([data length] > 0){
62                         NSData *realData = [NSData dataWithBytes:[data bytes] 
63                                                                                           length:[data length]-1];
64                 
65                         [taskToRun release];
66                         result = [[NSString alloc] initWithData: realData 
67                                                                                    encoding: NSUTF8StringEncoding];
68                 }
69         } else {
70                 NSLog(@"Task failed.");
71         }
72         return [result autorelease];
73 }
74
75
76 // -------------------------------------------------------------------------------
77 //  executeTask:
78 // -------------------------------------------------------------------------------
79 +(int) executeTaskWithAuth:(NSString*) taskName arguments:(NSArray *)args helper:(NSString *)helper withAuthRef:(AuthorizationRef)authRef {
80     const char *rootHelperApp = [helper fileSystemRepresentation];
81     OSStatus status;
82     AuthorizationFlags flags = kAuthorizationFlagDefaults;
83     int count = [args count];
84     char **myArguments = calloc(count + 2, sizeof(char *));
85     int i=0;
86
87     myArguments[0] = strdup([taskName UTF8String]);
88     for(i=0;i < count;i++) {
89         const char *string = [[args objectAtIndex:i] UTF8String];
90         if(!string)
91             break;
92         myArguments[1+i] = strdup(string);
93     }
94     myArguments[1+i] = NULL;
95
96     // should use SMJobBless but we need to sign things...
97     status = AuthorizationExecuteWithPrivileges(authRef, rootHelperApp, flags, myArguments, NULL);
98
99     i = 0;
100     while (myArguments[i] != NULL) {
101         free(myArguments[i]);
102         i++;
103     }
104
105     free(myArguments);
106     return status;
107 }
108
109 +(int) executeTaskWithAuth:(NSString*) taskName arguments:(NSArray *)args authExtForm:(NSData*)auth {
110         NSString *result = nil;
111         int status = 0;
112         NSFileHandle *file = nil;
113         NSDictionary *environment =  [NSDictionary dictionaryWithObjectsAndKeys: @"$PATH:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin",@"PATH",nil];
114         
115         NSPipe *pipe = [NSPipe pipe];
116         NSPipe *pipeIn = [NSPipe pipe];
117         NSTask *taskToRun  = [[NSTask alloc] init];
118         
119         [taskToRun setLaunchPath: taskName];
120         [taskToRun setArguments: args];
121         [taskToRun setEnvironment:environment];
122         [taskToRun setStandardOutput: pipe];
123         [taskToRun setStandardInput: pipeIn];
124         file = [pipe fileHandleForReading];
125         //Write to standard in
126         [taskToRun launch];
127         
128         NSFileHandle* taskInput = [[ taskToRun standardInput ] fileHandleForWriting ];
129         [taskInput writeData:auth];
130         [taskToRun waitUntilExit];
131         status = [taskToRun terminationStatus];
132         if (status == 0){
133                 NSData *data = [file readDataToEndOfFile];
134                 // remove the \n character from unix command
135                 if([data length] > 0){
136                         NSData *realData = [NSData dataWithBytes:[data bytes] 
137                                                                                           length:[data length]-1];
138                         
139                         [taskToRun release];
140                         result = [[NSString alloc] initWithData: realData 
141                                                                                    encoding: NSUTF8StringEncoding];
142                         [result release];
143                 }
144         } else {
145         }
146         
147         return status;
148 }
149 @end