5 // Created by Claudio Bisegni on 10/05/07.
6 // Copyright (c) 2007 INFN - National Institute of Nuclear Physics. All rights reserved.
9 #import "AFSCommanderPref.h"
10 #import "IpConfiguratorCommander.h"
11 #import "TokenCredentialController.h"
12 #import "InfoController.h"
14 #import "PListManager.h"
15 #import "DialogUtility.h"
16 #import "NSString+search.h"
17 #include <sys/param.h>
20 #include <sys/types.h>
21 #include <sys/fcntl.h>
22 #include <sys/errno.h>
26 #import <CoreServices/CoreServices.h>
29 #define ADD_CELL_CONTROL_TAG 1
30 #define REMOVE_CELL_CONTROL_TAG 2
32 #define TABLE_TOKENS_LIST 1
33 #define TABLE_CELL_LIST 2
34 #define TABLE_LINK_LIST 3
37 #define TAB_CELL_SERV_DB 2
42 #define CELLSRVDB_TABLE_USR_DFLT_CHECK_COLUMN 0
43 #define CELLSRVDB_TABLE_DFLT_CHECK_COLUMN 1
44 #define CELLSRVDB_TABLE_NAME_COLUMN 2
45 #define CELLSRVDB_TABLE_DESCRIPTION_COLUMN 3
48 #define TABLE_COLUMN_LINK_NAME 0
49 #define TABLE_COLUMN_LINK_PATH 1
52 @implementation AFSCommanderPref
54 // -------------------------------------------------------------------------------
56 // -------------------------------------------------------------------------------
57 - (id)initWithBundle:(NSBundle *)bundle
59 if ( ( self = [super initWithBundle:bundle] ) != nil ) {
60 //appID = kAfsCommanderID;
66 // -------------------------------------------------------------------------------
68 // -------------------------------------------------------------------------------
69 - (NSView *) mainView {
70 if (prefStartUp == 1){
73 if (Gestalt(gestaltSystemVersionMajor, &osxMJVers) == noErr && Gestalt(gestaltSystemVersionMinor, &osxMnVers) == noErr) {
74 if (osxMJVers == 10 && osxMnVers>= 5) {
75 [afsCommanderView setFrameSize:NSMakeSize(668, [afsCommanderView frame].size.height)];
81 return afsCommanderView;
84 // -------------------------------------------------------------------------------
86 // -------------------------------------------------------------------------------
87 - (void) mainViewDidLoad
90 [cellList setDelegate:self];
91 [cellList setTarget:self];
92 [cellList setDoubleAction:@selector(tableDoubleAction:)];
95 AuthorizationItem items = {kAuthorizationRightExecute, 0, NULL, 0};
96 AuthorizationRights rights = {1, &items};
97 [authView setAuthorizationRights:&rights];
98 authView.delegate = self;
99 [authView updateStatus:nil];
102 // -------------------------------------------------------------------------------
104 // -------------------------------------------------------------------------------
107 //try to install the launchd file for backgrounder
108 //Remove launchd ctrl file
110 [PListManager installBackgrounderLaunchdFile:YES
111 resourcePath:[[self bundle] resourcePath]];
113 @catch (NSException * e) {
114 NSDictionary *excecptDic = [e userInfo];
115 NSNumber *keyNum = [excecptDic objectForKey:@"agent_folder_error"];
116 if(keyNum && [keyNum boolValue]) {
117 // the dir HOME_LAUNCHD_AGENT_FOLDER (PListManager.h) must be created
118 NSBeginAlertSheet([[NSString stringWithString:kDoYouWantCreateTheDirectory] stringByAppendingString:HOME_LAUNCHD_AGENT_FOLDER],
119 @"Create", @"Cancel", nil,
120 [[self mainView] window], self, @selector(credentialAtLoginTimeEventCreationLaunchAgentDir:returnCode:contextInfo:), NULL,
129 // Set Developer info
130 [textFieldDevInfoLabel setStringValue:kDevelopInfo];
132 tokensLock = [[NSLock alloc] init];
134 //Initialization cellservdb and token list
135 filteredCellDB = nil;
138 [self readPreferenceFile];
140 // alloc the afs property mananger
141 afsProperty = [[AFSPropertyManager alloc] init];
143 // register preference pane to detect menuextra killed by user
144 [[NSDistributedNotificationCenter defaultCenter] addObserver:self
145 selector:@selector(refreshTokensNotify:)
147 object:kMExtraTokenOperation];
149 [[NSDistributedNotificationCenter defaultCenter] addObserver:self
150 selector:@selector(refreshGui:)
152 object:kMenuExtraEventOccured];
154 //Register for mount/unmount afs volume
155 [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
156 selector:@selector(afsVolumeMountChange:)
157 name:NSWorkspaceDidMountNotification object:nil];
159 [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
160 selector:@selector(afsVolumeMountChange:)
161 name:NSWorkspaceDidUnmountNotification object:nil];
163 // set self as table data source
164 [cellList setDataSource:self];
165 [tokensTable setDataSource:self];
166 //[tableViewLink setDataSource:self];
167 //check the afs state
170 // let show the configuration after prefpane is open
171 [self refreshConfiguration:nil];
173 // refresh the token list
174 //[self refreshTokens:nil];
176 //refresh table to reflect the NSSearchField contained text
177 [self searchCellTextEvent:nil];
180 // -------------------------------------------------------------------------------
181 // credentialAtLoginTimeEventCreationLaunchAgentDir:
182 // -------------------------------------------------------------------------------
183 - (void) credentialAtLoginTimeEventCreationLaunchAgentDir:(NSWindow*)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo {
185 switch (returnCode) {
187 if([[NSFileManager defaultManager] createDirectoryAtPath:[HOME_LAUNCHD_AGENT_FOLDER stringByExpandingTildeInPath]
188 withIntermediateDirectories:NO
193 [PListManager installBackgrounderLaunchdFile:YES
194 resourcePath:[[self bundle] resourcePath]];
195 [self showMessage:kDirectoryCreated];
197 [self showMessage:kErrorCreatingDirectory];
206 // -------------------------------------------------------------------------------
208 // -------------------------------------------------------------------------------
211 // remove self as datasource
212 [cellList setDataSource:nil];
213 [tokensTable setDataSource:nil];
215 //release the afs property manager
216 if(afsProperty) [afsProperty release];
217 //release tokens list
218 if(tokenList) [tokenList release];
219 //Remove the cell temp array
220 if(filteredCellDB) [filteredCellDB release];
222 [self writePreferenceFile];
224 // unregister preference pane to detect menuextra killed by user
225 [[NSDistributedNotificationCenter defaultCenter] removeObserver:self
227 object:kMExtraClosedNotification];
228 [[NSDistributedNotificationCenter defaultCenter] removeObserver:self
230 object:kMExtraTokenOperation];
231 [[NSDistributedNotificationCenter defaultCenter] removeObserver:self
233 object:kMenuExtraEventOccured];
234 [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self
235 name:NSWorkspaceDidMountNotification object:nil];
236 [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self
237 name:NSWorkspaceDidUnmountNotification object:nil];
240 [tokensLock release];
244 // -------------------------------------------------------------------------------
246 // -------------------------------------------------------------------------------
248 //start the time for check tokens validity
249 if(timerForCheckTokensList) return;
250 timerForCheckTokensList = [NSTimer scheduledTimerWithTimeInterval:TOKENS_REFRESH_TIME_IN_SEC
252 selector:@selector(refreshTokens:)
255 [timerForCheckTokensList fire];
258 // -------------------------------------------------------------------------------
260 // -------------------------------------------------------------------------------
262 if(!timerForCheckTokensList) return;
263 [timerForCheckTokensList invalidate];
264 timerForCheckTokensList = nil;
268 // -------------------------------------------------------------------------------
269 // readPreferenceFile:
270 // -------------------------------------------------------------------------------
271 - (void) readPreferenceFile
273 // read the preference for aklog use
274 NSNumber *useAklogPrefValue = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_USE_AKLOG, (CFStringRef)kAfsCommanderID,
275 kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
276 NSNumber *aklogTokenAtLogin = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_AKLOG_TOKEN_AT_LOGIN, (CFStringRef)kAfsCommanderID,
277 kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
278 [useAklogCheck setState:[useAklogPrefValue intValue]];
279 [aklogCredentialAtLoginTime setEnabled:useAklogPrefValue && [useAklogPrefValue boolValue]];
280 [aklogCredentialAtLoginTime setState:aklogTokenAtLogin && [aklogTokenAtLogin boolValue]];
282 //check krb5 at login time
283 [installKRB5AuthAtLoginButton setState:[PListManager checkKrb5AtLoginTimeLaunchdEnable]];
285 //check for AFS enable at startup
286 NSNumber *afsEnableStartupTime = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_START_AFS_AT_STARTUP,
287 (CFStringRef)kAfsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
288 if(afsEnableStartupTime)
289 startAFSAtLogin = [afsEnableStartupTime boolValue];
291 startAFSAtLogin = false;
292 //set the check button state
293 [checkButtonAfsAtBootTime setState:startAFSAtLogin];
295 NSNumber *showStatusMenu = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_SHOW_STATUS_MENU, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
296 [(NSButton*)afsMenucheckBox setState: [showStatusMenu boolValue]];
299 [backgrounderActivationCheck setState:[PListManager launchdJobState:BACKGROUNDER_P_FILE]];
301 //link enabled status
302 NSNumber *linkEnabledStatus = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_USE_LINK, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
303 [checkEnableLink setState:[linkEnabledStatus boolValue]];
305 //check the user preference for manage the renew
306 NSNumber *checkRenew = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_KRB5_CHECK_ENABLE, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
307 if(checkRenew)[nsButtonEnableDisableKrb5RenewCheck setState:[checkRenew intValue]];
309 NSNumber *renewTime = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_KRB5_RENEW_TIME, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
310 if(!renewTime) renewTime = [NSNumber numberWithInt:PREFERENCE_KRB5_RENEW_TIME_DEFAULT_VALUE];
313 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
314 NSDateComponents *weekdayComponents = [gregorian components:(NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit)
315 fromDate:[NSDate dateWithTimeIntervalSince1970:[renewTime intValue]]];
316 [nsTextFieldKrb5RenewTimeD setIntValue:[weekdayComponents day]-1];
317 [nsTextFieldKrb5RenewTimeH setIntValue:[weekdayComponents hour]-1];
318 [nsTextFieldKrb5RenewTimeM setIntValue:[weekdayComponents minute]];
319 [nsTextFieldKrb5RenewTimeS setIntValue:[weekdayComponents second]];
320 [nsStepperKrb5RenewTimeD setIntValue:[weekdayComponents day]-1];
321 [nsStepperKrb5RenewTimeH setIntValue:[weekdayComponents hour]-1];
322 [nsStepperKrb5RenewTimeM setIntValue:[weekdayComponents minute]];
323 [nsStepperKrb5RenewTimeS setIntValue:[weekdayComponents second]];
325 NSNumber *renewCheckTimeInterval = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_KRB5_RENEW_CHECK_TIME_INTERVALL, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
326 if(renewCheckTimeInterval && [renewCheckTimeInterval intValue])[nsTextFieldKrb5RenewCheckIntervall setIntValue:[renewCheckTimeInterval intValue]];
327 else [nsTextFieldKrb5RenewCheckIntervall setIntValue:PREFERENCE_KRB5_RENEW_CHECK_TIME_INTERVALL_DEFAULT_VALUE];
329 NSNumber *expireTimeForRenew = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_KRB5_SEC_TO_EXPIRE_TIME_FOR_RENEW, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
330 if(expireTimeForRenew && [expireTimeForRenew intValue])[nsTextFieldKrb5SecToExpireDateForRenew setIntValue:[expireTimeForRenew intValue]];
331 else [nsTextFieldKrb5SecToExpireDateForRenew setIntValue:PREFERENCE_KRB5_SEC_TO_EXPIRE_TIME_FOR_RENEW_DEFAULT_VALUE];
334 NSData *prefData = (NSData*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_LINK_CONFIGURATION, (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
335 linkConfiguration = (NSMutableDictionary*)[NSPropertyListSerialization propertyListFromData:prefData
336 mutabilityOption:NSPropertyListMutableContainers
338 errorDescription:nil];
341 // -------------------------------------------------------------------------------
343 // -------------------------------------------------------------------------------
344 - (void) writePreferenceFile
346 //Set the preference for afs path
347 //Set the preference for aklog use
348 CFPreferencesSetValue((CFStringRef)PREFERENCE_USE_AKLOG,
349 (CFNumberRef)[NSNumber numberWithInt:[useAklogCheck state]],
350 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
352 //set AFS enable state at startup
353 CFPreferencesSetValue((CFStringRef)PREFERENCE_START_AFS_AT_STARTUP,
354 (CFNumberRef)[NSNumber numberWithBool:startAFSAtLogin],
355 (CFStringRef)kAfsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
358 CFPreferencesSetValue((CFStringRef)PREFERENCE_AKLOG_TOKEN_AT_LOGIN,
359 (CFNumberRef)[NSNumber numberWithBool:[aklogCredentialAtLoginTime state]],
360 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
363 CFPreferencesSetValue((CFStringRef)PREFERENCE_SHOW_STATUS_MENU,
364 (CFNumberRef)[NSNumber numberWithBool:[(NSButton*)afsMenucheckBox state]],
365 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
367 //preference for link
368 CFPreferencesSetValue((CFStringRef)PREFERENCE_USE_LINK,
369 (CFNumberRef)[NSNumber numberWithBool:[checkEnableLink state]],
370 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
372 //preference for renew time
373 //NSLog(@"%d %d %d %d", [nsTextFieldKrb5RenewTimeD intValue],[nsTextFieldKrb5RenewTimeH intValue],[nsTextFieldKrb5RenewTimeM intValue],[nsTextFieldKrb5RenewTimeS intValue]);
374 NSInteger totalSeconds = ([nsTextFieldKrb5RenewTimeD intValue]*24*60*60)+
375 ([nsTextFieldKrb5RenewTimeH intValue]*60*60)+
376 ([nsTextFieldKrb5RenewTimeM intValue]*60)+
377 [nsTextFieldKrb5RenewTimeS intValue];
379 CFPreferencesSetValue((CFStringRef)PREFERENCE_KRB5_RENEW_TIME,
380 (CFNumberRef)[NSNumber numberWithInt:totalSeconds],
381 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
383 //expire time for renew
384 CFPreferencesSetValue((CFStringRef)PREFERENCE_KRB5_SEC_TO_EXPIRE_TIME_FOR_RENEW,
385 (CFNumberRef)[NSNumber numberWithInt:[nsTextFieldKrb5SecToExpireDateForRenew intValue]],
386 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
388 //sec to expiretime for renew job
389 CFPreferencesSetValue((CFStringRef)PREFERENCE_KRB5_RENEW_CHECK_TIME_INTERVALL,
390 (CFNumberRef)[NSNumber numberWithInt:[nsTextFieldKrb5RenewCheckIntervall intValue]],
391 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
393 CFPreferencesSynchronize((CFStringRef)kAfsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
394 CFPreferencesSynchronize((CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
395 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kPrefChangeNotification];
398 // -------------------------------------------------------------------------------
399 // saveConfiguration:
400 // -------------------------------------------------------------------------------
401 - (IBAction) saveConfiguration:(id) sender
404 [afsProperty setCellName:[afsProperty getDefaultCellName]];
406 //save configurations
407 [afsProperty saveConfigurationFiles:YES];
409 //Reload all configuration
410 [self refreshConfiguration:nil];
412 //refresh table to reflect the NSSearchField contained text
413 [self searchCellTextEvent:nil];
415 //Show dialog for notifity al saving process ar gone ell
416 [self showMessage:kConfigurationSaved];
417 }@catch(NSException *e){
418 [self showMessage:[e reason]];
420 [cellList reloadData];
424 // -------------------------------------------------------------------------------
425 // saveCacheManagerParam:
426 // -------------------------------------------------------------------------------
427 - (IBAction) saveCacheManagerParam:(id) sender
430 //Update the value form view to afs property manager class
431 [self updateCacheParamFromView];
432 [afsProperty saveCacheConfigurationFiles:YES];
433 [self showMessage:kSavedCacheConfiguration];
434 }@catch(NSException *e){
435 [self showMessage:[e reason]];
437 [cellList reloadData];
441 // -------------------------------------------------------------------------------
442 // refreshConfiguration:
443 // -------------------------------------------------------------------------------
444 - (IBAction) refreshConfiguration:(id) sender
446 NSString *afsBasePath = PREFERENCE_AFS_SYS_PAT_STATIC;
449 [afsProperty setPath:afsBasePath];
451 // load configuration
452 [afsProperty loadConfiguration];
454 //set the afs version label
455 [afsVersionLabel setStringValue:[afsProperty getAfsVersion]];
457 //set the current default cell
458 [afsDefaultCellLabel setStringValue:[afsProperty getDefaultCellName]];
461 [self fillCacheParamView];
463 //Filter the cellServDb and allocate filtered array
464 [self filterCellServDB:nil];
466 }@catch(NSException *e){
467 [self showMessage:[e reason]];
469 [cellList reloadData];
473 // -------------------------------------------------------------------------------
474 // fillCacheParamView:
475 // -------------------------------------------------------------------------------
476 -(void) fillCacheParamView
478 [dynRoot setState:[afsProperty dynRoot]?NSOnState:NSOffState];
479 [afsDB setState:[afsProperty afsDB]?NSOnState:NSOffState];
480 [statCacheEntry setIntValue:[afsProperty statCacheEntry]];
481 [dCacheDim setIntValue:[afsProperty dCacheDim]];
482 [cacheDimension setIntValue:[afsProperty cacheDimension]];
483 [daemonNumber setIntValue:[afsProperty daemonNumber]];
484 [afsRootMountPoint setStringValue:[afsProperty afsRootMountPoint]];
485 [nVolEntry setIntValue:[afsProperty nVolEntry]];
487 //new version property
488 //[verbose setEnabled:[afsProperty useAfsdConfConfigFile]];
489 [verbose setState:[afsProperty verbose]?NSOnState:NSOffState];
493 // -------------------------------------------------------------------------------
494 // updateCacheParamFromView:
495 // -------------------------------------------------------------------------------
496 -(void) updateCacheParamFromView
498 NSString *tmpAfsPath = [afsRootMountPoint stringValue];
499 if(!tmpAfsPath || ([tmpAfsPath length] == 0) || ([tmpAfsPath characterAtIndex:0] != '/'))
500 @throw [NSException exceptionWithName:@"updateCacheParamFromView"
501 reason:kBadAfsRootMountPoint
504 [afsProperty setDynRoot:[dynRoot state]==NSOnState];
505 [afsProperty setAfsDB:[afsDB state]==NSOnState];
506 [afsProperty setStatCacheEntry:[statCacheEntry intValue]];
507 [afsProperty setDCacheDim:[dCacheDim intValue]];
508 [afsProperty setCacheDimension:[cacheDimension intValue]];
509 [afsProperty setDaemonNumber:[daemonNumber intValue]];
510 [afsProperty setAfsRootMountPoint:tmpAfsPath];
511 [afsProperty setNVolEntry:[nVolEntry intValue]];
512 [afsProperty setVerbose:[verbose state]==NSOnState];
516 // -------------------------------------------------------------------------------
518 // -------------------------------------------------------------------------------
519 - (IBAction) showCellIP:(id) sender
521 int rowSelected = [((NSTableView *) cellList) selectedRow];
522 [self modifyCellByIDX:rowSelected];
525 // -------------------------------------------------------------------------------
527 // -------------------------------------------------------------------------------
528 -(void) modifyCellByIDX:(int) idx
530 [self modifyCell:[self getCellByIDX:idx]];
533 // -------------------------------------------------------------------------------
535 // -------------------------------------------------------------------------------
536 -(void) modifyCell:(DBCellElement*) cellElement
538 [NSBundle loadNibNamed:@"IpPanel" owner:self];
539 [((IpConfiguratorCommander*) ipConfControllerCommander) setWorkCell:cellElement];
540 [NSApp beginSheet: ipConfigurationSheet
541 modalForWindow: [[self mainView] window]
543 didEndSelector: @selector(didEndSheet:returnCode:contextInfo:)
547 // -------------------------------------------------------------------------------
549 // -------------------------------------------------------------------------------
550 - (IBAction) addRemoveCell:(id) sender
552 switch([((NSControl*) sender) tag]){
553 case ADD_CELL_CONTROL_TAG:
555 DBCellElement *newCell = [[DBCellElement alloc] init];
558 [newCell setCellName:kNewCellName];
559 [newCell setCellComment:kNewCellComment];
561 [[afsProperty getCellList] addObject:newCell];
565 [self modifyCell:newCell];
569 case REMOVE_CELL_CONTROL_TAG:
572 NSIndexSet *selectedIndex = [(NSTableView*)cellList selectedRowIndexes];
573 if( [selectedIndex count] > 0) {
574 index = [selectedIndex firstIndex];
576 DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:index];
577 [[afsProperty getCellList] removeObject:cellElement];
578 } while ((index = [selectedIndex indexGreaterThanIndex:index]) != NSNotFound);
583 //Filter the cellServDb and allocate filtered array
584 [self searchCellTextEvent:nil];
585 [cellList deselectAll:nil];
586 [cellList reloadData];
589 // -------------------------------------------------------------------------------
591 // -------------------------------------------------------------------------------
592 - (IBAction) startStopAfs:(id) sender
594 BOOL currentAfsState = NO;
596 currentAfsState = [afsProperty checkAfsStatus];
597 // make the parameter to call the root helper app
600 NSLog(@"Shutting down afs");
601 [afsProperty shutdown];
604 NSLog(@"Starting up afs");
605 [afsProperty startup];
607 [self refreshGui:nil];
609 @catch (NSException * e) {
610 [self showMessage:[e reason]];
616 // -------------------------------------------------------------------------------
618 // -------------------------------------------------------------------------------
619 - (void) refreshGui:(NSNotification *)notification{
620 BOOL afsIsUp = [afsProperty checkAfsStatus];
622 [tokensButton setEnabled:afsIsUp];
623 [unlogButton setEnabled:afsIsUp];
627 // -------------------------------------------------------------------------------
628 // -(void) refreshTokensNotify:(NSNotification*)notification
629 // -------------------------------------------------------------------------------
630 -(void) refreshTokensNotify:(NSNotification*)notification {
631 [self refreshTokens:nil];
634 // -------------------------------------------------------------------------------
635 // afsVolumeMountChange: Track the afs volume state change
636 // -------------------------------------------------------------------------------
637 // XXX should use mountdir not /afs
638 - (void) afsVolumeMountChange:(NSNotification *)notification{
639 // Check if is mounted or unmounted afs
640 if([[[notification userInfo] objectForKey:@"NSDevicePath"] isEqualToString:@"/afs"]){
642 [self refreshTokens:nil];
646 // -------------------------------------------------------------------------------
648 // -------------------------------------------------------------------------------
649 - (IBAction) info:(id) sender
651 [infoController showHtmlResource:[[self bundle] pathForResource:@"license" ofType:@"rtf"]];
653 [NSApp beginSheet: infoSheet
654 modalForWindow: [[self mainView] window]
656 didEndSelector: @selector(didEndInfoSheet:returnCode:contextInfo:)
660 // -------------------------------------------------------------------------------
661 // tableDoubleAction:
662 // -------------------------------------------------------------------------------
663 - (IBAction) tableDoubleAction:(id) sender
665 [self showCellIP:nil];
668 // -------------------------------------------------------------------------------
670 // -------------------------------------------------------------------------------
671 - (IBAction) getNewToken:(id) sender
673 BOOL useAklog = [useAklogCheck state] == NSOnState;
675 //[AFSPropertyManager aklog];
676 [afsProperty getTokens:false
679 [self refreshTokens:nil];
680 //Inform afs menuextra to updata afs status
681 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange];
684 [NSBundle loadNibNamed:@"CredentialPanel" owner:self];
685 [NSApp beginSheet: credentialSheet
686 modalForWindow: [[self mainView] window]
688 didEndSelector: @selector(didEndCredentialSheet:returnCode:contextInfo:)
694 // -------------------------------------------------------------------------------
695 // getCurrentCellInDB:
696 // -------------------------------------------------------------------------------
697 - (IBAction) unlog:(id) sender
700 NSIndexSet *selectedIndex = [tokensTable selectedRowIndexes];
701 if( [selectedIndex count] > 0) {
702 index = [selectedIndex firstIndex];
704 NSString *tokenDesc = [tokenList objectAtIndex:index];
705 NSString *cellToUnlog = [tokenDesc estractTokenByDelimiter:@"afs@"
707 [afsProperty unlog:cellToUnlog];
708 } while ((index = [selectedIndex indexGreaterThanIndex: index]) != NSNotFound);
710 [afsProperty unlog:nil];
712 [self refreshTokens:nil];
713 //Inform afs menuextra to updata afs status
714 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange];
718 // -------------------------------------------------------------------------------
720 // -------------------------------------------------------------------------------
721 - (IBAction) aklogSwitchEvent:(id) sender
723 //afs menu extra is loaded inform it to read preference
725 if(![useAklogCheck state]) {
726 //deselect the checkbox
727 [aklogCredentialAtLoginTime setState:NO];
730 [self writePreferenceFile];
732 //Enable disable aklog at login time checkbox according the useAklog checkbox
733 [aklogCredentialAtLoginTime setEnabled:[useAklogCheck state]];
736 @catch (NSException * e) {
737 [self showMessage:[e reason]];
741 // -------------------------------------------------------------------------------
742 // credentialAtLoginTimeEvent:
743 // -------------------------------------------------------------------------------
744 - (IBAction) credentialAtLoginTimeEvent:(id) sender {
745 [self writePreferenceFile];
748 // -------------------------------------------------------------------------------
749 // afsStartupSwitchEvent:
750 // -------------------------------------------------------------------------------
751 - (IBAction) afsStartupSwitchEvent:(id) sender {
752 NSString *rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""];
754 startAFSAtLogin = [checkButtonAfsAtBootTime state];
755 [PListManager launchctlStringCommandAuth:startAFSAtLogin?@"load":@"unload"
756 option:[NSArray arrayWithObjects:@"-w", nil]
757 plistName:@AFS_DAEMON_PATH
759 withAuthRef:[[authView authorization] authorizationRef]];
763 // -------------------------------------------------------------------------------
764 // afsMenuActivationEvent:
765 // -------------------------------------------------------------------------------
766 - (IBAction) krb5KredentialAtLoginTimeEvent:(id) sender {
767 NSString *rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""];
768 [PListManager krb5TiketAtLoginTime:[installKRB5AuthAtLoginButton state] helper:rootHelperApp];
770 //check if all is gone well
771 [installKRB5AuthAtLoginButton setState:[PListManager checkKrb5AtLoginTimeLaunchdEnable]];
774 // -------------------------------------------------------------------------------
775 // afsMenuActivationEvent:
776 // -------------------------------------------------------------------------------
777 -(IBAction) afsMenuActivationEvent:(id) sender
779 CFPreferencesSetValue((CFStringRef)PREFERENCE_SHOW_STATUS_MENU,
780 (CFNumberRef)[NSNumber numberWithBool:[(NSButton*)afsMenucheckBox state]],
781 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
783 CFPreferencesSynchronize((CFStringRef)kAfsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
784 CFPreferencesSynchronize((CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
786 //notify the backgrounder
787 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSMenuChangeState];
790 // -------------------------------------------------------------------------------
791 // searchCellTextEvent:
792 // Fileter the CellServDB list according to NSSearch content
793 // -------------------------------------------------------------------------------
794 - (IBAction) searchCellTextEvent:(id) sender
796 NSString *searchText = [[textSearchField stringValue] lowercaseString]; //filter string
797 [self filterCellServDB:searchText];
798 [((NSTableView*)cellList) reloadData];
801 // -------------------------------------------------------------------------------
802 // clearCellServDBFiltering:
803 // clear the NSSearchField and showw all CellServDB table
804 // -------------------------------------------------------------------------------
805 - (void) clearCellServDBFiltering {
806 //Clear the text search
807 [textSearchField setStringValue:@""];
808 //load the temp array with all cell servdb
809 [self searchCellTextEvent:nil];
811 // --------------------------------------o-----------------------------------------
813 // make the NSMutableArray with all cellservdb or filtered element
814 // -------------------------------------------------------------------------------
815 - (void) filterCellServDB:(NSString*)textToFilter {
816 DBCellElement *cellElement; //Filtered element
817 BOOL doFilter = !(textToFilter == nil || ([textToFilter length] == 0));
819 // We can do filtering and make the temp array
821 [filteredCellDB release];
823 filteredCellDB = [[NSMutableArray alloc] init];
824 NSEnumerator *e = [[afsProperty getCellList] objectEnumerator];
825 while(cellElement = (DBCellElement*)[e nextObject]) {
826 // check if the element can be get
828 //Get the CellServDB array enumerator
829 NSRange rsltRng = [[[cellElement getCellName] lowercaseString] rangeOfString:textToFilter];
830 if(rsltRng.location != NSNotFound) {
831 //we can add this cell to filtered
832 [filteredCellDB addObject:[cellElement retain]];
835 [filteredCellDB addObject:[cellElement retain]];
841 // -------------------------------------------------------------------------------
842 // getCurrentCellInDB:
843 // -------------------------------------------------------------------------------
844 - (DBCellElement*) getCurrentCellInDB
846 int rowSelected = [cellList selectedRow];
847 return [self getCellByIDX:rowSelected];
850 // -------------------------------------------------------------------------------
851 // getCurrentCellInDB:
852 // -------------------------------------------------------------------------------
853 - (DBCellElement*) getCellByIDX:(int) idx
855 DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:idx];
859 // -------------------------------------------------------------------------------
861 // -------------------------------------------------------------------------------
862 -(void) showMessage:(NSString*) message{
863 NSAlert *alert = [[NSAlert alloc] init];
865 [alert setMessageText:message];
866 [alert beginSheetModalForWindow:[[self mainView] window]
873 // -------------------------------------------------------------------------------
875 // -------------------------------------------------------------------------------
878 BOOL afsIsUp = [afsProperty checkAfsStatus];
879 BOOL afsEnabledAtStartup = NO;
880 NSString *rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""];
882 if ([self isUnlocked]) {
883 afsEnabledAtStartup = (
884 [TaskUtil executeTaskWithAuth:@"/bin/launchctl"
885 arguments:[NSArray arrayWithObjects:@"list",
886 @"org.openafs.filesystems.afs", nil]
888 withAuthRef:[[authView authorization] authorizationRef]
890 [checkButtonAfsAtBootTime setState:afsEnabledAtStartup];
893 [startStopButton setTitle: (afsIsUp?kAfsButtonShutdown:kAfsButtonStartup)];
895 NSMutableAttributedString *colorTitle =[[NSMutableAttributedString alloc] initWithAttributedString:[startStopButton attributedTitle]];
896 NSRange titleRange = NSMakeRange(0, [colorTitle length]);
898 [colorTitle addAttribute:NSForegroundColorAttributeName
899 value:(afsIsUp?[NSColor redColor]:[NSColor blackColor])
902 [startStopButton setAttributedTitle:colorTitle];
910 // -------------------------------------------------------------------------------
912 // -------------------------------------------------------------------------------
913 - (void) refreshTokens:(NSTimer*)theTimer;
915 if(![tokensLock tryLock]) return;
920 tokenList = [afsProperty getTokenList];
921 [tokensTable reloadData];
925 // -------------------------------------------------------------------------------
927 // -------------------------------------------------------------------------------
928 - (IBAction) addLink:(id) sender {
929 [NSBundle loadNibNamed:@"SymLinkEdit" owner:self];
931 [NSApp beginSheet: lyncCreationSheet
932 modalForWindow: [[self mainView] window]
934 didEndSelector: @selector(didEndSymlinkSheet:returnCode:contextInfo:)
938 // -------------------------------------------------------------------------------
940 // -------------------------------------------------------------------------------
941 - (IBAction) removeLink:(id) sender {
942 if(!linkConfiguration) return;
944 NSArray *keys = [linkConfiguration allKeys];
945 NSIndexSet *linkToRemove = [tableViewLink selectedRowIndexes];
946 if( [linkToRemove count] > 0) {
947 index = [linkToRemove firstIndex];
949 [linkConfiguration removeObjectForKey:[keys objectAtIndex:index]];
950 } while ((index = [linkToRemove indexGreaterThanIndex:index]) != -1);
953 //write the new configuration
954 NSData *prefData = nil;
955 if([linkConfiguration count] > 0) {
956 prefData = [NSPropertyListSerialization dataWithPropertyList:linkConfiguration
957 format:NSPropertyListXMLFormat_v1_0
961 CFPreferencesSetValue((CFStringRef)PREFERENCE_LINK_CONFIGURATION,
963 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
965 CFPreferencesSynchronize((CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
967 //reload the new data
968 [tableViewLink reloadData];
971 // -------------------------------------------------------------------------------
973 // -------------------------------------------------------------------------------
974 - (IBAction) enableLink:(id) sender {
975 [self writePreferenceFile];
978 // -------------------------------------------------------------------------------
980 // -------------------------------------------------------------------------------
981 - (IBAction) manageBackgrounderActivation:(id)sender {
982 [PListManager launchctlCommand:[(NSButton*)sender state]
984 option:[NSArray arrayWithObjects:@"-S", @"Aqua", nil]
985 plistName:[NSString stringWithFormat:@"%@.plist", BACKGROUNDER_P_FILE]];
986 //read the status to check that all is gone well
987 [backgrounderActivationCheck setState:[PListManager launchdJobState:BACKGROUNDER_P_FILE]];
990 // -------------------------------------------------------------------------------
991 // tableViewLinkPerformClick:
992 // -------------------------------------------------------------------------------
993 - (IBAction) tableViewLinkPerformClick:(id) sender {
994 NSLog(@"tableViewLinkPerformClick");
997 // -------------------------------------------------------------------------------
998 // - (void)tabView:(NSTabView *)tabView willSelectTabViewItem: (NSTabViewItem *)tabViewItem
999 // -------------------------------------------------------------------------------
1000 - (void)tabView:(NSTabView *)tabView willSelectTabViewItem: (NSTabViewItem *)tabViewItem
1002 //check to see if the cache param tab is the tab that will be selected
1003 if([((NSString*)[tabViewItem identifier]) intValue] == TAB_LINK)
1005 [tableViewLink reloadData];
1008 // -------------------------------------------------------------------------------
1009 // tableViewLinkPerformClick:
1010 // -------------------------------------------------------------------------------
1011 - (IBAction) enableDisableKrb5RenewCheck:(id) sender {
1012 //NSLog(@"enableDisableKrb5RenewCheck");
1013 CFPreferencesSetValue((CFStringRef)PREFERENCE_KRB5_CHECK_ENABLE,
1014 (CFNumberRef) [NSNumber numberWithInt:[(NSButton*)sender intValue]],
1015 (CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
1016 CFPreferencesSynchronize((CFStringRef)kAfsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
1017 //notify the backgrounder
1018 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kPrefChangeNotification];
1020 // -------------------------------------------------------------------------------
1021 // tableViewLinkPerformClick:
1022 // -------------------------------------------------------------------------------
1023 - (IBAction) krb5RenewParamChange:(id) sender {
1027 - (BOOL)isUnlocked {
1028 return [authView authorizationState] == SFAuthorizationViewUnlockedState;
1031 - (void)authorizationViewDidAuthorize:(SFAuthorizationView *)view {
1033 [startStopButton setEnabled:[self isUnlocked]];
1034 [checkButtonAfsAtBootTime setEnabled:[self isUnlocked]];
1035 [self setAfsStatus];
1036 [installKRB5AuthAtLoginButton setEnabled:[self isUnlocked]];
1039 - (void)authorizationViewDidDeauthorize:(SFAuthorizationView *)view {
1041 [startStopButton setEnabled:[self isUnlocked]];
1042 [checkButtonAfsAtBootTime setEnabled:[self isUnlocked]];
1043 [installKRB5AuthAtLoginButton setEnabled:[self isUnlocked]];
1047 @implementation AFSCommanderPref (NSTableDataSource)
1050 // -------------------------------------------------------------------------------
1052 // Manage the checkbox of CellServDB Table
1054 // -------------------------------------------------------------------------------
1055 - (void)tableView:(NSTableView *)table
1056 setObjectValue:(id)data
1057 forTableColumn:(NSTableColumn *)col
1060 NSString *identifier = (NSString*)[col identifier];
1061 switch([table tag]){
1062 case TABLE_TOKENS_LIST:
1065 case TABLE_CELL_LIST:
1066 // we are editing checkbox for cellservdb table
1067 if([identifier intValue] == CELLSRVDB_TABLE_USR_DFLT_CHECK_COLUMN) {
1068 // set the user default cell
1069 DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:row];
1070 [afsProperty setDefaultCellByName:[cellElement getCellName]];
1071 //[afsDefaultCellLabel setStringValue:[afsProperty getDefaultCellName]];
1072 [((NSTableView*)cellList) reloadData];
1073 } else if([identifier intValue] == CELLSRVDB_TABLE_DFLT_CHECK_COLUMN) {
1074 // set the cell for wich the user want to get token
1075 DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:row];
1076 [cellElement setUserDefaultForToken:![cellElement userDefaultForToken]];
1083 // -------------------------------------------------------------------------------
1085 // refresh delegate method for two AFSCommander table
1086 // -------------------------------------------------------------------------------
1087 - (id) tableView:(NSTableView *) aTableView
1088 objectValueForTableColumn:(NSTableColumn *) aTableColumn
1092 NSString *identifier = (NSString*)[aTableColumn identifier];
1093 switch([aTableView tag]){
1094 case TABLE_TOKENS_LIST:
1095 //We are refreshing tokens table
1096 result = [self getTableTokensListValue:[identifier intValue] row:rowIndex];
1099 case TABLE_CELL_LIST:
1100 //We are refreshing cell db table
1101 result = [self getTableCelListValue:[identifier intValue] row:rowIndex];
1104 case TABLE_LINK_LIST:
1105 result = [self getTableLinkValue:[identifier intValue] row:rowIndex];
1112 // -------------------------------------------------------------------------------
1113 // getTableCelListValue:
1114 // -------------------------------------------------------------------------------
1115 - (id)getTableTokensListValue:(int) colId row:(int)row
1118 if(!tokenList) return nil;
1121 result = (NSString*)[tokenList objectAtIndex:row];
1128 // -------------------------------------------------------------------------------
1129 // getTableCelListValue:
1130 // -------------------------------------------------------------------------------
1131 - (id)getTableCelListValue:(int) colId row:(int)row
1134 //NSMutableArray *cellArray = [afsProperty getCellList];
1135 DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:row];
1137 case CELLSRVDB_TABLE_USR_DFLT_CHECK_COLUMN:
1138 result = [NSNumber numberWithInt:[cellElement userDefaultForCell]];
1141 case CELLSRVDB_TABLE_DFLT_CHECK_COLUMN:
1142 result = [NSNumber numberWithInt:[cellElement userDefaultForToken]];
1144 case CELLSRVDB_TABLE_NAME_COLUMN:
1145 result = [cellElement getCellName];
1148 case CELLSRVDB_TABLE_DESCRIPTION_COLUMN:
1149 result = [cellElement getCellComment];
1155 // -------------------------------------------------------------------------------
1156 // getTableCelListValue:
1157 // -------------------------------------------------------------------------------
1158 - (id)getTableLinkValue:(int) colId row:(int)row
1161 NSArray *allKey = [linkConfiguration allKeys];
1163 case TABLE_COLUMN_LINK_NAME:
1164 result = [allKey objectAtIndex:row];
1167 case TABLE_COLUMN_LINK_PATH:
1168 result = [linkConfiguration objectForKey:[allKey objectAtIndex:row]];
1175 // -------------------------------------------------------------------------------
1176 // numberOfRowsInTableView:
1177 // -------------------------------------------------------------------------------
1178 - (int)numberOfRowsInTableView:(NSTableView *)aTableView
1181 switch([aTableView tag]){
1182 case TABLE_TOKENS_LIST:
1183 if(tokenList) rowCount = [tokenList count];
1186 case TABLE_CELL_LIST:
1187 if(filteredCellDB) rowCount = [filteredCellDB count];
1190 case TABLE_LINK_LIST:
1191 if(linkConfiguration) rowCount = [linkConfiguration count];
1199 @implementation AFSCommanderPref (TableDelegate)
1200 // -------------------------------------------------------------------------------
1201 // selectionShouldChangeInTableView:
1202 // -------------------------------------------------------------------------------
1203 - (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTable
1205 switch([aTable tag]){
1206 case TABLE_TOKENS_LIST:
1209 case TABLE_CELL_LIST:
1210 [self tableViewCellmanageButtonState:[aTable selectedRow]];
1213 case TABLE_LINK_LIST:
1222 // -------------------------------------------------------------------------------
1224 // -------------------------------------------------------------------------------
1225 - (BOOL)tableView:(NSTableView *)aTable shouldSelectRow:(int)aRow
1227 switch([aTable tag]){
1228 case TABLE_TOKENS_LIST:
1231 case TABLE_CELL_LIST:
1232 [self tableViewCellmanageButtonState:aRow];
1235 case TABLE_LINK_LIST:
1241 // -------------------------------------------------------------------------------
1243 // -------------------------------------------------------------------------------
1244 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
1245 NSTableView *aTable = [aNotification object];
1246 switch([aTable tag]){
1247 case TABLE_TOKENS_LIST:
1250 case TABLE_CELL_LIST:
1253 case TABLE_LINK_LIST:
1254 [self tableViewLinkmanageButtonState:[aTable selectedRowIndexes]];
1258 // -------------------------------------------------------------------------------
1259 // manageButtonState:
1260 // -------------------------------------------------------------------------------
1261 -(void) tableViewCellmanageButtonState:(int) rowSelected {
1262 [cellIpButton setEnabled:rowSelected >= 0];
1263 [removeCellButton setEnabled:rowSelected >= 0];
1266 // -------------------------------------------------------------------------------
1267 // manageButtonState:
1268 // -------------------------------------------------------------------------------
1269 -(void) tableViewLinkmanageButtonState:(NSIndexSet *) rowsSelectedIndex {
1270 [buttonRemoveLink setEnabled:[rowsSelectedIndex count]>0];
1275 @implementation AFSCommanderPref (ModalDelegate)
1276 // -------------------------------------------------------------------------------
1278 // -------------------------------------------------------------------------------
1279 - (void)didEndSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1281 [sheet orderOut:self];
1282 //Filter the cellServDb and allocate filtered array
1283 [self searchCellTextEvent:nil];
1284 [cellList reloadData];
1287 // -------------------------------------------------------------------------------
1288 // Klog credential request
1289 // -------------------------------------------------------------------------------
1290 - (void)didEndCredentialSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1292 if([((TokenCredentialController*)credentialCommander) takenToken] == YES){
1293 /*[AFSPropertyManager klog:[((TokenCredentialController*)credentialCommander) uName]
1294 uPwd:[((TokenCredentialController*)credentialCommander) uPwd] ];*/
1295 [afsProperty getTokens:true
1296 usr:[((TokenCredentialController*)credentialCommander) uName]
1297 pwd:[((TokenCredentialController*)credentialCommander) uPwd]];
1299 [sheet orderOut:self];
1300 [self refreshTokens:nil];
1301 //Inform afs menuextra to updata afs status
1302 [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange];
1305 // -------------------------------------------------------------------------------
1306 // Klog credential request
1307 // -------------------------------------------------------------------------------
1308 - (void)didEndInfoSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1310 [sheet orderOut:self];
1313 // -------------------------------------------------------------------------------
1315 // -------------------------------------------------------------------------------
1316 - (void)didEndSymlinkSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
1318 [lyncCreationSheet orderOut:self];
1319 [self readPreferenceFile];
1320 [tableViewLink reloadData];