macos: update AFS prefs pane
[openafs.git] / src / platform / DARWIN / AFSPreference / AFSBackgrounder / AFSMenuExtra.m
1 //
2 //  AFSMenuExtra.m
3 //  AFSCommander
4 //
5 //  Created by Claudio on 10/07/07.
6 //  Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved.
7 //
8
9 #import "AFSMenuExtra.h"
10 #import "AFSMenuExtraView.h"
11 #import "AFSPropertyManager.h"
12 #import "TaskUtil.h"
13 #import "TokenCredentialController.h"
14 #include <sys/param.h>
15 #include <sys/stat.h>
16 #include <sys/wait.h>
17 #include <sys/types.h>
18 #include <sys/fcntl.h>
19 #include <sys/errno.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 @implementation AFSMenuExtra
25 // -------------------------------------------------------------------------------
26 //  -(id) initWithBundle
27 // -------------------------------------------------------------------------------
28 - (id) initWithBundle:(NSBundle *)bundle
29 {
30     self = [super initWithBundle:bundle];
31     if( self == nil )
32         return nil;
33         
34         // allocate the lock
35         tokensLock = [[NSLock alloc] init];
36         // inizialize the afspath
37         afsSysPath = nil;
38         credentialMenuController = nil;
39
40     theView = [[AFSMenuExtraView alloc] initWithFrame:[[self view] frame] 
41                                                                                         menuExtra:self];
42         [self setView:theView];
43     
44         
45     // Get the imge for menu
46         //Load image for menu rappresentation
47         hasTokenImage = [self getImageFromBundle:@"hasToken" 
48                                                                                          fileExt:@"png"];
49         
50         noTokenImage = [self getImageFromBundle:@"noToken" 
51                                                                                         fileExt:@"png"];
52         
53     theMenu = [[NSMenu alloc] initWithTitle: @""];
54     [theMenu setAutoenablesItems: NO];
55     startStopMenu = [theMenu addItemWithTitle: kAfsOff action: @selector(startStopAfs:)  keyEquivalent: @""];
56         [startStopMenu setTarget:self];
57         
58         loginMenu = [theMenu addItemWithTitle: kMenuLogin action: @selector(getToken:)  keyEquivalent: @""];
59         [loginMenu setTarget:self];
60
61         unlogMenu = [theMenu addItemWithTitle: kMenuUnlog action: @selector(releaseToken:)  keyEquivalent: @""];
62         [unlogMenu setTarget:self];
63
64         // Register for preference user change
65         [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(readPreferenceFile:) 
66                                                                                                                         name:kAFSMenuExtraID object:kPrefChangeNotification];
67         
68         // Register for afs state change
69         [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(afsVolumeMountChange:) 
70                                                                                                                         name:kAFSMenuExtraID object:kMExtraAFSStateChange];
71         
72         
73         //Register for mount/unmount afs volume
74         [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self 
75                                                                                                                    selector:@selector(afsVolumeMountChange:) 
76                                                                                                                            name:NSWorkspaceDidMountNotification object:nil];
77         
78         [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self 
79                                                                                                                    selector:@selector(afsVolumeMountChange:) 
80                                                                                                                            name:NSWorkspaceDidUnmountNotification object:nil];
81         //Start to read the afs path
82         [self readPreferenceFile:nil];  
83         [self startTimer];
84     return self;
85 }
86
87 // -------------------------------------------------------------------------------
88 //  -(void) willUnload
89 // -------------------------------------------------------------------------------
90 - (void) willUnload {
91         //release the lock
92         [self stopTimer];
93         
94         if(hasTokenImage) [hasTokenImage release];
95         if(noTokenImage) [noTokenImage release];
96         
97         // Unregister for preference change
98         [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kAFSMenuExtraID object:kPrefChangeNotification];
99         [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kAFSMenuExtraID object:kMExtraAFSStateChange];
100         [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidMountNotification object:nil];
101         [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidUnmountNotification object:nil];
102
103         
104         [tokensLock release];
105 }
106
107 // -------------------------------------------------------------------------------
108 //  startTimer:
109 // -------------------------------------------------------------------------------
110 - (void)startTimer{
111         //start the time for check tokens validity
112         if(timerForCheckTokensList) return;
113         timerForCheckTokensList = [NSTimer scheduledTimerWithTimeInterval:TOKENS_REFRESH_TIME_IN_SEC 
114                                                                                                                            target:self 
115                                                                                                                          selector:@selector(updateAfsStatus:) 
116                                                                                                                          userInfo:nil 
117                                                                                                                           repeats:YES];
118         [timerForCheckTokensList fire]; 
119 }
120
121 // -------------------------------------------------------------------------------
122 //  stopTimer:
123 // -------------------------------------------------------------------------------
124 - (void)stopTimer{
125         if(!timerForCheckTokensList) return;
126         [timerForCheckTokensList invalidate];   
127         timerForCheckTokensList = nil;
128 }
129 // -------------------------------------------------------------------------------
130 //  -(void) dealloc
131 // -------------------------------------------------------------------------------
132 - (void) dealloc
133 {
134     [theMenu release];
135     [theView release];
136         if(afsSysPath) [afsSysPath release];
137         // send notify that menuextra has closed
138         [[NSDistributedNotificationCenter defaultCenter] postNotificationName:afsCommanderID object:kPrefChangeNotification];
139     [super dealloc];
140 }
141
142 // -------------------------------------------------------------------------------
143 //  -(NSMenu*) menu
144 // -------------------------------------------------------------------------------
145 - (NSMenu *) menu
146 {
147     return theMenu;
148 }
149
150
151 // -------------------------------------------------------------------------------
152 //  -(void) readPreferenceFile
153 // -------------------------------------------------------------------------------
154 - (void) readPreferenceFile:(NSNotification *)notification
155 {
156         NSLog(@"Reading preference file");
157         //CFPreferencesSynchronize((CFStringRef)afsCommanderID,  kCFPreferencesAnyUser, kCFPreferencesAnyHost);
158         //CFPreferencesSynchronize((CFStringRef)afsCommanderID,  kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
159         
160         if(afsSysPath) {
161                 [afsSysPath release];
162                 afsSysPath = nil;
163         }
164         
165         afsSysPath = PREFERENCE_AFS_SYS_PAT_STATIC;
166                 
167         // read the preference for aklog use
168         
169         useAklogPrefValue = [[NSUserDefaults standardUserDefaults] boolForKey:PREFERENCE_USE_AKLOG];
170         NSLog(@"NSUserDefaults:%d", useAklogPrefValue);
171         useAklogPrefValue = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_USE_AKLOG, 
172                                                                                                                   (CFStringRef)afsCommanderID, 
173                                                                                                                   kCFPreferencesCurrentUser, 
174                                                                                                                   kCFPreferencesAnyHost);
175         NSLog(@"CFPreferencesCopyValue:%d", useAklogPrefValue);
176         [self updateAfsStatus:nil];
177 }
178
179 // -------------------------------------------------------------------------------
180 //  -(void) getToken
181 // -------------------------------------------------------------------------------
182 - (void)getToken:(id)sender
183 {
184         
185         NSRect globalRect;
186         globalRect.origin = [[[self view] window] convertBaseToScreen:[[self view] frame].origin];
187         globalRect.size = [[self view] frame].size;
188         AFSPropertyManager *afsPropMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath ];
189         [afsPropMngr loadConfiguration]; 
190         
191         
192         if([useAklogPrefValue intValue]==NSOnState ) {
193                 [afsPropMngr getTokens:false 
194                                                    usr:nil 
195                                                    pwd:nil];
196                 [self klogUserEven:nil];
197         } else {
198                 // register for user event
199                 [[NSDistributedNotificationCenter defaultCenter] addObserver:self 
200                                                                                                                         selector:@selector(klogUserEven:) 
201                                                                                                                                 name:kAFSMenuExtraID 
202                                                                                                                           object:kLogWindowClosed];
203         
204                 credentialMenuController = [[AFSMenuCredentialContoller alloc] initWhitRec:globalRect 
205                                                                                                                                         afsPropManager:afsPropMngr];
206                 [credentialMenuController showWindow];
207         }
208         
209         //Dispose afs manager
210         [afsPropMngr release];
211 }
212
213 // -------------------------------------------------------------------------------
214 //  -(void) releaseToken
215 // -------------------------------------------------------------------------------
216 - (void)releaseToken:(id)sender
217 {
218         AFSPropertyManager *afsMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath];
219         [afsMngr unlog:nil];
220         [afsMngr release];
221         [self updateAfsStatus:nil];
222 }
223
224
225 // -------------------------------------------------------------------------------
226 //  -(void) afsVolumeMountChange - Track for mount unmount afs volume
227 // -------------------------------------------------------------------------------
228 - (void) afsVolumeMountChange:(NSNotification *)notification{
229         [self updateAfsStatus:nil];
230 }
231
232 // -------------------------------------------------------------------------------
233 //  -(void) updateAfsStatus
234 // -------------------------------------------------------------------------------
235 - (void)updateAfsStatus:(NSTimer*)timer
236 {
237         //Try to locking
238         if(![tokensLock tryLock]) return;
239         
240         // check the afs state in esclusive mode
241         AFSPropertyManager *afsMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath];
242         afsState = [afsMngr checkAfsStatus];
243         
244         NSArray *tokens = [afsMngr getTokenList];
245         [afsMngr release];
246         gotToken = [tokens count] > 0;
247         [tokens release];
248         // update the menu item title
249         [startStopMenu setTitle:afsState?kAfsButtonShutdown:kAfsButtonStartup];
250         
251         [self updateMenu];
252         
253         [theView setNeedsDisplay:YES];
254         
255         //unlock
256         [tokensLock unlock];
257 }
258
259 // -------------------------------------------------------------------------------
260 //  -(void) klogUserEven
261 // -------------------------------------------------------------------------------
262 -(void) klogUserEven:(NSNotification *)notification
263 {
264         if(credentialMenuController) {
265                 [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kAFSMenuExtraID object:kLogWindowClosed];
266                 [credentialMenuController closeWindow];
267                 [credentialMenuController release];
268                 credentialMenuController = nil;
269         }
270         //Send notification to PreferencePane
271         [[NSDistributedNotificationCenter defaultCenter] postNotificationName:afsCommanderID object:kMenuExtraEventOccured];
272         
273         [self updateAfsStatus:nil];
274 }
275
276 // -------------------------------------------------------------------------------
277 //  -(void) getImageFromBundle
278 // -------------------------------------------------------------------------------
279 - (NSImage*)getImageFromBundle:(NSString*)fileName fileExt:(NSString*)ext
280 {
281         return [[NSImage alloc]initWithContentsOfFile:[[self bundle] pathForResource:fileName 
282                                                                                                                                    ofType:ext]];
283 }
284
285 // -------------------------------------------------------------------------------
286 //  -(void) imageToRender
287 // -------------------------------------------------------------------------------
288 - (NSImage*)imageToRender
289 {
290         if(gotToken){
291                 return hasTokenImage;
292         } else {
293                 return noTokenImage;
294         }
295 }
296
297
298 // -------------------------------------------------------------------------------
299 //  -(void) updateMenu
300 // -------------------------------------------------------------------------------
301 - (void)updateMenu{
302         [loginMenu setEnabled:afsState];
303         [unlogMenu setEnabled:afsState];
304 }
305
306
307 // -------------------------------------------------------------------------------
308 //  -(void) useAklogPrefValue
309 // -------------------------------------------------------------------------------
310 - (BOOL)useAklogPrefValue
311 {
312         if(useAklogPrefValue) return [useAklogPrefValue intValue] == NSOnState; 
313         else return NSOffState;
314 }
315 @end