From 689fa16bdd5ea57e09453c4be2183289feb6f5a2 Mon Sep 17 00:00:00 2001 From: Claudio Bisegni Date: Sat, 11 Jul 2009 00:18:56 +0200 Subject: [PATCH] OSX Preference Pane Source Import Reviewed-on: http://gerrit.openafs.org/http://gerrit.openafs.org/196 Tested-by: Derrick Brashear Reviewed-by: Derrick Brashear (cherry picked from commit 694c5ca3f400ce88219f60edec75249bf73cc8fc) Change-Id: I4078bfc6004431c2dd277cbc2a665b4c6cc412a3 Reviewed-on: http://gerrit.openafs.org/937 --- .../AFSPreference/AFSCommanderIcon.icns | Bin 0 -> 130674 bytes .../DARWIN/AFSPreference/AFSCommanderPref.h | 145 + .../DARWIN/AFSPreference/AFSCommanderPref.m | 1292 +++++ .../AFSPreference/AFSCommander_Prefix.pch | 9 + .../AFSMenuCredentialContoller.h | 24 + .../AFSMenuCredentialContoller.m | 67 + .../AFSPreference/AFSMenuExtra-Info.plist | 22 + .../DARWIN/AFSPreference/AFSMenuExtra.h | 57 + .../DARWIN/AFSPreference/AFSMenuExtra.m | 435 ++ .../DARWIN/AFSPreference/AFSMenuExtraView.h | 18 + .../DARWIN/AFSPreference/AFSMenuExtraView.m | 72 + .../DARWIN/AFSPreference/AFSPropertyManager.h | 397 ++ .../DARWIN/AFSPreference/AFSPropertyManager.m | 1418 ++++++ .../CredentialWindow.nib/classes.nib | 62 + .../CredentialWindow.nib/info.nib | 20 + .../CredentialWindow.nib/keyedobjects.nib | Bin 0 -> 5498 bytes .../AfsMenuExtraResource/Info.plist | 22 + src/platform/DARWIN/AFSPreference/AuthUtil.h | 29 + src/platform/DARWIN/AFSPreference/AuthUtil.m | 186 + src/platform/DARWIN/AFSPreference/CellIp.h | 23 + src/platform/DARWIN/AFSPreference/CellIp.m | 76 + .../CredentialWindowController.h | 30 + .../CredentialWindowController.m | 71 + .../DARWIN/AFSPreference/DBCellElement.h | 134 + .../DARWIN/AFSPreference/DBCellElement.m | 143 + .../DARWIN/AFSPreference/DialogUtility.h | 16 + .../DARWIN/AFSPreference/DialogUtility.m | 26 + .../English.lproj/CredentialPanel.xib | 710 +++ .../English.lproj/InfoPlist.strings | Bin 0 -> 204 bytes .../AFSPreference/English.lproj/IpPanel.xib | 1199 +++++ .../English.lproj/Localizable.strings | 50 + .../English.lproj/OpenAFSPreference.xib | 4335 +++++++++++++++++ .../English.lproj/SymLinkEdit.xib | 728 +++ src/platform/DARWIN/AFSPreference/FileUtil.h | 24 + src/platform/DARWIN/AFSPreference/FileUtil.m | 91 + src/platform/DARWIN/AFSPreference/Info.plist | 34 + .../DARWIN/AFSPreference/InfoController.h | 21 + .../DARWIN/AFSPreference/InfoController.m | 42 + .../AFSPreference/IpConfiguratorCommander.h | 42 + .../AFSPreference/IpConfiguratorCommander.m | 238 + .../AFSPreference/LynkCreationController.h | 23 + .../AFSPreference/LynkCreationController.m | 44 + .../MenuCracker.menu/Contents/Info.plist | 28 + .../Contents/MacOS/MenuCracker | Bin 0 -> 47328 bytes .../Contents/Resources/ReadMe.rtf | 51 + .../DARWIN/AFSPreference/NSString+search.h | 28 + .../DARWIN/AFSPreference/NSString+search.m | 26 + .../OpenAFS.xcodeproj/bisegni.mode1 | 1439 ++++++ .../OpenAFS.xcodeproj/project.pbxproj | 1254 +++++ .../DARWIN/AFSPreference/PListManager.h | 71 + .../DARWIN/AFSPreference/PListManager.m | 266 + .../DARWIN/AFSPreference/SystemUIPlugin.h | 220 + src/platform/DARWIN/AFSPreference/TaskUtil.h | 19 + src/platform/DARWIN/AFSPreference/TaskUtil.m | 126 + src/platform/DARWIN/AFSPreference/TestLib.m | 35 + .../AFSPreference/TokenCredentialController.h | 32 + .../AFSPreference/TokenCredentialController.m | 69 + .../DARWIN/AFSPreference/ViewUtility.h | 16 + .../DARWIN/AFSPreference/ViewUtility.m | 30 + .../DARWIN/AFSPreference/afscommlogo.png | Bin 0 -> 8019 bytes src/platform/DARWIN/AFSPreference/afshlp.m | 199 + src/platform/DARWIN/AFSPreference/afslogo.psd | Bin 0 -> 428255 bytes src/platform/DARWIN/AFSPreference/afsltd.m | 85 + src/platform/DARWIN/AFSPreference/global.h | 57 + .../DARWIN/AFSPreference/hasToken.png | Bin 0 -> 3679 bytes src/platform/DARWIN/AFSPreference/licenza.rtf | 11 + src/platform/DARWIN/AFSPreference/noToken.png | Bin 0 -> 4066 bytes .../DARWIN/AFSPreference/start_afs.sh | 111 + src/platform/DARWIN/AFSPreference/stop_afs.sh | 21 + 69 files changed, 16569 insertions(+) create mode 100644 src/platform/DARWIN/AFSPreference/AFSCommanderIcon.icns create mode 100644 src/platform/DARWIN/AFSPreference/AFSCommanderPref.h create mode 100644 src/platform/DARWIN/AFSPreference/AFSCommanderPref.m create mode 100644 src/platform/DARWIN/AFSPreference/AFSCommander_Prefix.pch create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.h create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.m create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuExtra-Info.plist create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuExtra.h create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuExtra.m create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuExtraView.h create mode 100644 src/platform/DARWIN/AFSPreference/AFSMenuExtraView.m create mode 100644 src/platform/DARWIN/AFSPreference/AFSPropertyManager.h create mode 100644 src/platform/DARWIN/AFSPreference/AFSPropertyManager.m create mode 100644 src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/classes.nib create mode 100644 src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/info.nib create mode 100644 src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/keyedobjects.nib create mode 100644 src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/Info.plist create mode 100644 src/platform/DARWIN/AFSPreference/AuthUtil.h create mode 100644 src/platform/DARWIN/AFSPreference/AuthUtil.m create mode 100644 src/platform/DARWIN/AFSPreference/CellIp.h create mode 100644 src/platform/DARWIN/AFSPreference/CellIp.m create mode 100644 src/platform/DARWIN/AFSPreference/CredentialWindowController.h create mode 100644 src/platform/DARWIN/AFSPreference/CredentialWindowController.m create mode 100644 src/platform/DARWIN/AFSPreference/DBCellElement.h create mode 100644 src/platform/DARWIN/AFSPreference/DBCellElement.m create mode 100644 src/platform/DARWIN/AFSPreference/DialogUtility.h create mode 100644 src/platform/DARWIN/AFSPreference/DialogUtility.m create mode 100644 src/platform/DARWIN/AFSPreference/English.lproj/CredentialPanel.xib create mode 100644 src/platform/DARWIN/AFSPreference/English.lproj/InfoPlist.strings create mode 100644 src/platform/DARWIN/AFSPreference/English.lproj/IpPanel.xib create mode 100644 src/platform/DARWIN/AFSPreference/English.lproj/Localizable.strings create mode 100644 src/platform/DARWIN/AFSPreference/English.lproj/OpenAFSPreference.xib create mode 100644 src/platform/DARWIN/AFSPreference/English.lproj/SymLinkEdit.xib create mode 100644 src/platform/DARWIN/AFSPreference/FileUtil.h create mode 100644 src/platform/DARWIN/AFSPreference/FileUtil.m create mode 100644 src/platform/DARWIN/AFSPreference/Info.plist create mode 100644 src/platform/DARWIN/AFSPreference/InfoController.h create mode 100644 src/platform/DARWIN/AFSPreference/InfoController.m create mode 100644 src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.h create mode 100644 src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.m create mode 100644 src/platform/DARWIN/AFSPreference/LynkCreationController.h create mode 100644 src/platform/DARWIN/AFSPreference/LynkCreationController.m create mode 100644 src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Info.plist create mode 100755 src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/MacOS/MenuCracker create mode 100644 src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Resources/ReadMe.rtf create mode 100644 src/platform/DARWIN/AFSPreference/NSString+search.h create mode 100644 src/platform/DARWIN/AFSPreference/NSString+search.m create mode 100644 src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/bisegni.mode1 create mode 100644 src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/project.pbxproj create mode 100644 src/platform/DARWIN/AFSPreference/PListManager.h create mode 100644 src/platform/DARWIN/AFSPreference/PListManager.m create mode 100644 src/platform/DARWIN/AFSPreference/SystemUIPlugin.h create mode 100644 src/platform/DARWIN/AFSPreference/TaskUtil.h create mode 100644 src/platform/DARWIN/AFSPreference/TaskUtil.m create mode 100644 src/platform/DARWIN/AFSPreference/TestLib.m create mode 100644 src/platform/DARWIN/AFSPreference/TokenCredentialController.h create mode 100644 src/platform/DARWIN/AFSPreference/TokenCredentialController.m create mode 100644 src/platform/DARWIN/AFSPreference/ViewUtility.h create mode 100644 src/platform/DARWIN/AFSPreference/ViewUtility.m create mode 100644 src/platform/DARWIN/AFSPreference/afscommlogo.png create mode 100644 src/platform/DARWIN/AFSPreference/afshlp.m create mode 100644 src/platform/DARWIN/AFSPreference/afslogo.psd create mode 100644 src/platform/DARWIN/AFSPreference/afsltd.m create mode 100644 src/platform/DARWIN/AFSPreference/global.h create mode 100644 src/platform/DARWIN/AFSPreference/hasToken.png create mode 100644 src/platform/DARWIN/AFSPreference/licenza.rtf create mode 100644 src/platform/DARWIN/AFSPreference/noToken.png create mode 100755 src/platform/DARWIN/AFSPreference/start_afs.sh create mode 100755 src/platform/DARWIN/AFSPreference/stop_afs.sh diff --git a/src/platform/DARWIN/AFSPreference/AFSCommanderIcon.icns b/src/platform/DARWIN/AFSPreference/AFSCommanderIcon.icns new file mode 100644 index 0000000000000000000000000000000000000000..b07e4843f60edc2586257eacfaa44aa0353986bf GIT binary patch literal 130674 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 T8*0({wVUDNlNq3Rf`;}VH9g({ literal 0 HcmV?d00001 diff --git a/src/platform/DARWIN/AFSPreference/AFSCommanderPref.h b/src/platform/DARWIN/AFSPreference/AFSCommanderPref.h new file mode 100644 index 000000000..a6e03f2fc --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSCommanderPref.h @@ -0,0 +1,145 @@ +// +// AFSCommanderPref.h +// AFSCommander +// +// Created by Claudio Bisegni on 10/05/07. +// Copyright (c) 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "AFSPropertyManager.h" +#import "global.h" +#import "ViewUtility.h" +#import "LynkCreationController.h" + +// the way to load and unload the menuextra was inspired by MenuMeters developed by Alex Harper +// Routines to handle adding and remove menu extras in HIServices (from ASM source) +int CoreMenuExtraGetMenuExtra(CFStringRef identifier, void *menuExtra); +int CoreMenuExtraAddMenuExtra(CFURLRef path, int position, int whoCares, int whoCares2, int whoCares3, int whoCares4); +int CoreMenuExtraRemoveMenuExtra(void *menuExtra, int whoCares); + + + +@interface AFSCommanderPref : NSPreferencePane +{ + //for check system version + int prefStartUp; + // Main View + IBOutlet NSView *afsCommanderView; + IBOutlet NSSearchField *textSearchField; + IBOutlet NSTextField *afsDefaultCellLabel; + IBOutlet NSButton *tokensButton; + IBOutlet NSButton *unlogButton; + IBOutlet NSButton *aklogCredentialAtLoginTime; + IBOutlet NSButton *installKRB5AuthAtLoginButton; + IBOutlet NSButton *useAklogCheck; + IBOutlet NSTextField *afsVersionLabel; + BOOL startAFSAtLogin; + IBOutlet NSButton *checkButtonAfsAtBootTime; + IBOutlet NSTextField *textFieldDevInfoLabel; + + //NSString *appID; + //id installationPathTextField; + id startStopButton; + id cellList; + //id cellNameTextEdit; + id cellIpButton; + id addCellButton; + id removeCellButton; + //id refreshConfigurationButton; + id saveConfigurationButton; + id labelSaveResult; + id tokensTable; + id afsMenucheckBox; + + //cache manager IBOutlet + IBOutlet NSTextField *statCacheEntry; + IBOutlet NSTextField *dCacheDim; + IBOutlet NSTextField *cacheDimension; + IBOutlet NSTextField *daemonNumber; + IBOutlet NSTextField *afsRootMountPoint; + IBOutlet NSTextField *nVolEntry; + IBOutlet NSButton *dynRoot; + IBOutlet NSButton *afsDB; + IBOutlet NSButton *verbose; + IBOutlet NSBox *groupsBox; + + //Configuration sheet + id ipConfigurationSheet; + id ipConfControllerCommander; + + //Token sheet + id credentialSheet; + id credentialCommander; + + + //Info Sheet + id infoSheet; + id infoController; + + //lynk creation + id lyncCreationSheet; + IBOutlet LynkCreationController *lynkCreationController; + + //manage link + IBOutlet NSButton *checkEnableLink; + IBOutlet NSButton *buttonAddLink; + IBOutlet NSButton *buttonRemoveLink; + bool enableLink; + + AFSPropertyManager *afsProperty; //AFS Property managment class + NSMutableArray *filteredCellDB; //Filtered CellServDB + NSArray *tokenList; + NSTimer *timerForCheckTokensList; + NSLock *tokensLock; +} + +- (void) mainViewDidLoad; +- (void) willUnselect; +- (void) didSelect; +- (id) initWithBundle:(NSBundle *)bundle; +- (void)startTimer; +- (void)stopTimer; +//View Action +- (IBAction) refreshConfiguration:(id) sender; +- (void) fillCacheParamView; +- (void) updateCacheParamFromView; +- (IBAction) showCellIP:(id) sender; +- (IBAction) addRemoveCell:(id) sender; +- (IBAction) addLink:(id) sender; +- (IBAction) removeLink:(id) sender; +- (IBAction) enableLink:(id) sender; +- (IBAction) saveConfiguration:(id) sender; +- (IBAction) saveCacheManagerParam:(id) sender; +- (IBAction) startStopAfs:(id) sender; +- (IBAction) info:(id) sender; +- (IBAction) tableDoubleAction:(id) sender; +- (IBAction) getNewToken:(id) sender; +- (IBAction) unlog:(id) sender; +- (IBAction) afsMenuActivationEvent:(id) sender; +- (IBAction) aklogSwitchEvent:(id) sender; +- (IBAction) credentialAtLoginTimeEvent:(id) sender; +- (IBAction) afsStartupSwitchEvent:(id) sender; +- (void) credentialAtLoginTimeEventCreationLaunchAgentDir:(NSWindow*)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo; +- (IBAction) krb5KredentialAtLoginTimeEvent:(id) sender; +- (IBAction) searchCellTextEvent:(id) sender; +- (void) clearCellServDBFiltering; +- (void) filterCellServDB:(NSString*)textToFilter; +- (DBCellElement*) getCurrentCellInDB; +- (DBCellElement*) getCellByIDX:(int) idx; +- (void) modifyCell:(DBCellElement*) cellElement; +- (void) modifyCellByIDX:(int) idx; +- (void) showMessage:(NSString*) message; +- (void) manageButtonState:(int) rowSelected; +- (void) setAfsStatus; +- (void) refreshTokens:(NSTimer*)theTimer; +- (BOOL) isAFSMenuExtraLoaded; +- (void) addAFSMenuExtra; +- (void) removeAFSMenuExtra; +- (void) repairHelperTool; +- (void) writePreferenceFile; +- (void) readPreferenceFile; +- (void) mextraChangeActivation:(NSNotification *)notification; +- (void) refreshGui:(NSNotification *)notification; +- (void) afsVolumeMountChange:(NSNotification *)notification; +@end \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/AFSCommanderPref.m b/src/platform/DARWIN/AFSPreference/AFSCommanderPref.m new file mode 100644 index 000000000..09b65b0f7 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSCommanderPref.m @@ -0,0 +1,1292 @@ +// +// AFSCommanderPref.m +// AFSCommander +// +// Created by Claudio Bisegni on 10/05/07. +// Copyright (c) 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "AFSCommanderPref.h" +#import "IpConfiguratorCommander.h" +#import "TokenCredentialController.h" +#import "InfoController.h" +#import "TaskUtil.h" +#import "PListManager.h" +#import "DialogUtility.h" +#import "NSString+search.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#import + + +#define ADD_CELL_CONTROL_TAG 1 +#define REMOVE_CELL_CONTROL_TAG 2 + +#define TABLE_TOKENS_LIST 1 +#define TABLE_CELL_LIST 2 + +#define TAB_TOKENS 1 +#define TAB_CELL_SERV_DB 2 +#define TAB_CACHE 3 +#define TAB_GROUP 4 + +//CellServDB table id +#define CELLSRVDB_TABLE_USR_DFLT_CHECK_COLUMN 0 +#define CELLSRVDB_TABLE_DFLT_CHECK_COLUMN 1 +#define CELLSRVDB_TABLE_NAME_COLUMN 2 +#define CELLSRVDB_TABLE_DESCRIPTION_COLUMN 3 + +@implementation AFSCommanderPref + +// ------------------------------------------------------------------------------- +// initWithBundle: +// ------------------------------------------------------------------------------- +- (id)initWithBundle:(NSBundle *)bundle +{ + if ( ( self = [super initWithBundle:bundle] ) != nil ) { + //appID = afsCommanderID; + prefStartUp = 1; + } + return self; +} + +// ------------------------------------------------------------------------------- +// mainView: +// ------------------------------------------------------------------------------- +- (NSView *) mainView { + if (prefStartUp == 1){ + SInt32 osxMJVers = 0; + SInt32 osxMnVers = 0; + if (Gestalt(gestaltSystemVersionMajor, &osxMJVers) == noErr && Gestalt(gestaltSystemVersionMinor, &osxMnVers) == noErr) { + if (osxMJVers == 10 && osxMnVers>= 5) { + // we are working on leopard + NSLog(@"Leopard AFSCommander adapting"); + [afsCommanderView setFrameSize:NSMakeSize(668, [afsCommanderView frame].size.height)]; + prefStartUp = 0; + } + } + } + + return afsCommanderView; +} + +// ------------------------------------------------------------------------------- +// mainViewDidLoad: +// ------------------------------------------------------------------------------- +- (void) mainViewDidLoad +{ + //CellServDB Table + [((NSTableView*)cellList) setDelegate:self]; + [((NSTableView*)cellList) setTarget:self]; + [((NSTableView*)cellList) setDoubleAction:@selector(tableDoubleAction:)]; + + +} + +// ------------------------------------------------------------------------------- +// didSelect: +// ------------------------------------------------------------------------------- +- (void) didSelect +{ + // Set Developer info + [textFieldDevInfoLabel setStringValue:kDevelopInfo]; + // creating the lock + tokensLock = [[NSLock alloc] init]; + + //Initialization cellservdb and token list + filteredCellDB = nil; + tokenList = nil; + + [self readPreferenceFile]; + + // alloc the afs property mananger + afsProperty = [[AFSPropertyManager alloc] init]; + + // register preference pane to detect menuextra killed by user + [[NSDistributedNotificationCenter defaultCenter] addObserver:self + selector:@selector(mextraChangeActivation:) + name:afsCommanderID + object:kMExtraClosedNotification]; + + [[NSDistributedNotificationCenter defaultCenter] addObserver:self + selector:@selector(refreshGui:) + name:afsCommanderID + object:kMenuExtraEventOccured]; + + //Register for mount/unmount afs volume + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self + selector:@selector(afsVolumeMountChange:) + name:NSWorkspaceDidMountNotification object:nil]; + + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self + selector:@selector(afsVolumeMountChange:) + name:NSWorkspaceDidUnmountNotification object:nil]; + + // set self as table data source + [((NSTableView*)cellList) setDataSource:self]; + [((NSTableView*)tokensTable) setDataSource:self]; + + //check the afs state + [self setAfsStatus]; + + // check the MenuExtra state + [self mextraChangeActivation:nil]; + + // let show the configuration after prefpane is open + [self refreshConfiguration:nil]; + + // refresh the token list + //[self refreshTokens:nil]; + + //refresh table to reflect the NSSearchField contained text + [self searchCellTextEvent:nil]; +} + +// ------------------------------------------------------------------------------- +// willUnselect: +// ------------------------------------------------------------------------------- +- (void)willUnselect +{ + NSLog(@"willUnselect"); + // remove self as datasource + [((NSTableView*)cellList) setDataSource:nil]; + [((NSTableView*)tokensTable) setDataSource:nil]; + + //release the afs property manager + if(afsProperty) [afsProperty release]; + //release tokens list + if(tokenList) [tokenList release]; + //Remove the cell temp array + if(filteredCellDB) [filteredCellDB release]; + + [self writePreferenceFile]; + + // unregister preference pane to detect menuextra killed by user + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self + name:afsCommanderID + object:kMExtraClosedNotification]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self + name:afsCommanderID + object:kMenuExtraEventOccured]; + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self + name:NSWorkspaceDidMountNotification object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self + name:NSWorkspaceDidUnmountNotification object:nil]; + + [self stopTimer]; + [tokensLock release]; +} + + +// ------------------------------------------------------------------------------- +// startTimer: +// ------------------------------------------------------------------------------- +- (void)startTimer{ + //start the time for check tokens validity + if(timerForCheckTokensList) return; + timerForCheckTokensList = [NSTimer scheduledTimerWithTimeInterval:TOKENS_REFRESH_TIME_IN_SEC + target:self + selector:@selector(refreshTokens:) + userInfo:nil + repeats:YES]; + [timerForCheckTokensList fire]; +} + +// ------------------------------------------------------------------------------- +// stopTimer: +// ------------------------------------------------------------------------------- +- (void)stopTimer{ + if(!timerForCheckTokensList) return; + [timerForCheckTokensList invalidate]; + timerForCheckTokensList = nil; +} + + +// ------------------------------------------------------------------------------- +// readPreferenceFile: +// ------------------------------------------------------------------------------- +- (void) readPreferenceFile +{ + + // read the preference for afs path + //NSString *afsSysPath = PREFERENCE_AFS_SYS_PAT_STATIC;/*(NSString*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_AFS_SYS_PAT, (CFStringRef)afsCommanderID, + // kCFPreferencesAnyUser, kCFPreferencesAnyHost);*/ + /*if(afsSysPath){ + [((NSTextField*) installationPathTextField ) setStringValue:afsSysPath]; + }*/ + + // read the preference for aklog use + NSNumber *useAklogPrefValue = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_USE_AKLOG, (CFStringRef)afsCommanderID, + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + if(useAklogPrefValue){ + [useAklogCheck setState:[useAklogPrefValue intValue]]; + [aklogCredentialAtLoginTime setEnabled:[useAklogPrefValue intValue]]; + } else { + [useAklogCheck setState:NSOffState]; + [aklogCredentialAtLoginTime setEnabled:NSOffState]; + [aklogCredentialAtLoginTime setState:NSOffState]; + [PListManager installLaunchdFile:NO + resourcePath:nil]; + } + + //check if krb5 at startup is enable at system level + [installKRB5AuthAtLoginButton setState:[PListManager checkKrb5AtLoginTimeLaunchdEnable]]; + + //check if the user has installed and enabled the afs agent + [aklogCredentialAtLoginTime setState:[PListManager checkAklogAtLoginTimeLaunchdEnable]]; + + //check for AFS enable at startup + NSNumber *afsEnableStartupTime = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_START_AFS_AT_STARTUP, + (CFStringRef)afsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + if(afsEnableStartupTime) + startAFSAtLogin = [afsEnableStartupTime boolValue]; + else + startAFSAtLogin = false; + //set the check button state + [checkButtonAfsAtBootTime setState:startAFSAtLogin]; +} + +// ------------------------------------------------------------------------------- +// willUnselect: +// ------------------------------------------------------------------------------- +- (void) writePreferenceFile +{ + //Set the preference for afs path + /*CFPreferencesSetValue((CFStringRef)PREFERENCE_AFS_SYS_PAT, + (CFStringRef)[((NSTextField*) installationPathTextField ) stringValue], + (CFStringRef)afsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost);*/ + + //Set the preference for aklog use + CFPreferencesSetValue((CFStringRef)PREFERENCE_USE_AKLOG, + (CFNumberRef)[NSNumber numberWithInt:[useAklogCheck state]], + (CFStringRef)afsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + + // Notify + if ([self isAFSMenuExtraLoaded]) [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kPrefChangeNotification]; + + //set AFS enable state at startup + CFPreferencesSetValue((CFStringRef)PREFERENCE_START_AFS_AT_STARTUP, + (CFNumberRef)[NSNumber numberWithBool:startAFSAtLogin], + (CFStringRef)afsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + + CFPreferencesSynchronize((CFStringRef)afsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + CFPreferencesSynchronize((CFStringRef)afsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); +} + +// ------------------------------------------------------------------------------- +// saveConfiguration: +// ------------------------------------------------------------------------------- +- (IBAction) saveConfiguration:(id) sender +{ + @try{ + + //[afsProperty setCellName:[cellNameTextEdit stringValue]]; + [afsProperty setCellName:[afsProperty getDefaultCellName]]; + + //save configurations + [afsProperty saveConfigurationFiles:YES]; + + + //Reload all configuration + [self refreshConfiguration:nil]; + + //refresh table to reflect the NSSearchField contained text + [self searchCellTextEvent:nil]; + + //Show dialog for notifity al saving process ar gone ell + [self showMessage:kConfigurationSaved]; + }@catch(NSException *e){ + [self showMessage:[e reason]]; + } @finally { + [((NSTableView*)cellList) reloadData]; + } + +} + +// ------------------------------------------------------------------------------- +// saveCacheManagerParam: +// ------------------------------------------------------------------------------- +- (IBAction) saveCacheManagerParam:(id) sender +{ + @try{ + NSLog(@"Backing up the cache configuration file"); + //Update the value form view to afs property manager class + [self updateCacheParamFromView]; + [afsProperty saveCacheConfigurationFiles:YES]; + NSLog(@"Cache configuration file backuped"); + [self showMessage:kSavedCacheConfiguration]; + }@catch(NSException *e){ + [self showMessage:[e reason]]; + } @finally { + [((NSTableView*)cellList) reloadData]; + } +} + +// ------------------------------------------------------------------------------- +// refreshConfiguration: +// ------------------------------------------------------------------------------- +- (IBAction) refreshConfiguration:(id) sender +{ + NSLog(@"refreshConfiguration"); + NSString *afsBasePath = PREFERENCE_AFS_SYS_PAT_STATIC; + + @try{ + // set the afs path + [afsProperty setPath:afsBasePath]; + + // load configuration + [afsProperty loadConfiguration]; + + //set the afs version label + [afsVersionLabel setStringValue:[afsProperty getAfsVersion]]; + + //set the current default cell + [afsDefaultCellLabel setStringValue:[afsProperty getDefaultCellName]]; + + // Update cache view + [self fillCacheParamView]; + + //Filter the cellServDb and allocate filtered array + [self filterCellServDB:nil]; + + }@catch(NSException *e){ + [self showMessage:[e reason]]; + } @finally { + [((NSTableView*)cellList) reloadData]; + } +} + +// ------------------------------------------------------------------------------- +// fillCacheParamView: +// ------------------------------------------------------------------------------- +-(void) fillCacheParamView +{ + [dynRoot setState:[afsProperty dynRoot]?NSOnState:NSOffState]; + [afsDB setState:[afsProperty afsDB]?NSOnState:NSOffState]; + [statCacheEntry setIntValue:[afsProperty statCacheEntry]]; + [dCacheDim setIntValue:[afsProperty dCacheDim]]; + [cacheDimension setIntValue:[afsProperty cacheDimension]]; + [daemonNumber setIntValue:[afsProperty daemonNumber]]; + [afsRootMountPoint setStringValue:[afsProperty afsRootMountPoint]]; + [nVolEntry setIntValue:[afsProperty nVolEntry]]; + + //new version property + //[verbose setEnabled:[afsProperty useAfsdConfConfigFile]]; + [verbose setState:[afsProperty verbose]?NSOnState:NSOffState]; + +} + +// ------------------------------------------------------------------------------- +// updateCacheParamFromView: +// ------------------------------------------------------------------------------- +-(void) updateCacheParamFromView +{ + NSString *tmpAfsPath = [afsRootMountPoint stringValue]; + if(!tmpAfsPath || ([tmpAfsPath length] == 0) || ([tmpAfsPath characterAtIndex:0] != '/')) + @throw [NSException exceptionWithName:@"updateCacheParamFromView" + reason:kBadAfsRootMountPoint + userInfo:nil]; + + + [afsProperty setDynRoot:[dynRoot state]==NSOnState]; + [afsProperty setAfsDB:[afsDB state]==NSOnState]; + [afsProperty setStatCacheEntry:[statCacheEntry intValue]]; + [afsProperty setDCacheDim:[dCacheDim intValue]]; + [afsProperty setCacheDimension:[cacheDimension intValue]]; + [afsProperty setDaemonNumber:[daemonNumber intValue]]; + [afsProperty setAfsRootMountPoint:tmpAfsPath]; + [afsProperty setNVolEntry:[nVolEntry intValue]]; + [afsProperty setVerbose:[verbose state]==NSOnState]; +} + + +// ------------------------------------------------------------------------------- +// showCellIP: +// ------------------------------------------------------------------------------- +- (IBAction) showCellIP:(id) sender +{ + int rowSelected = [((NSTableView *) cellList) selectedRow]; + [self modifyCellByIDX:rowSelected]; +} + +// ------------------------------------------------------------------------------- +// modifyCellByIDX: +// ------------------------------------------------------------------------------- +-(void) modifyCellByIDX:(int) idx +{ + [self modifyCell:[self getCellByIDX:idx]]; +} + +// ------------------------------------------------------------------------------- +// modifyCellByIDX: +// ------------------------------------------------------------------------------- +-(void) modifyCell:(DBCellElement*) cellElement +{ + [NSBundle loadNibNamed:@"IpPanel" owner:self]; + [((IpConfiguratorCommander*) ipConfControllerCommander) setWorkCell:cellElement]; + [NSApp beginSheet: ipConfigurationSheet + modalForWindow: [[self mainView] window] + modalDelegate: self + didEndSelector: @selector(didEndSheet:returnCode:contextInfo:) + contextInfo: nil]; +} + +// ------------------------------------------------------------------------------- +// addMoifyCell: +// ------------------------------------------------------------------------------- +- (IBAction) addRemoveCell:(id) sender +{ + switch([((NSControl*) sender) tag]){ + case ADD_CELL_CONTROL_TAG: + { + DBCellElement *newCell = [[DBCellElement alloc] init]; + if(!newCell) break; + + [newCell setCellName:kNewCellName]; + [newCell setCellComment:kNewCellComment]; + //cellArray = ; + [[afsProperty getCellList] addObject:newCell]; + [newCell release]; + + //Modify new cell + [self modifyCell:newCell]; + } + break; + + case REMOVE_CELL_CONTROL_TAG: + { + int index = 0; + NSIndexSet *selectedIndex = [(NSTableView*)cellList selectedRowIndexes]; + if( [selectedIndex count] > 0) { + index = [selectedIndex firstIndex]; + do { + DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:index]; + [[afsProperty getCellList] removeObject:cellElement]; + } while ((index = [selectedIndex indexGreaterThanIndex: index]) != NSNotFound); + } + } + break; + } + //Filter the cellServDb and allocate filtered array + [self searchCellTextEvent:nil]; + [(NSTableView*)cellList deselectAll:nil]; + [(NSTableView*)cellList reloadData]; +} + +// ------------------------------------------------------------------------------- +// repairHelperTool: +// ------------------------------------------------------------------------------- +- (void) repairHelperTool +{ + struct stat st; + int fdTool; + int status = 0; + NSLog(@"repairHelperTool"); + NSString *afshlpPath = [[self bundle] pathForResource:@"afshlp" ofType:nil]; + + + + // Open tool exclusively, so nobody can change it while we bless it. + fdTool = open([afshlpPath UTF8String], O_NONBLOCK | O_RDONLY | O_EXLOCK, 0); + + if(fdTool == -1) + { + NSLog(@"Exclusive open while repairing tool failed: %d.", errno); + exit(-1); + } + + if(fstat(fdTool, &st)) + { + NSLog(@"fstat failed."); + exit(-1); + } + + if(st.st_uid != 0) + { + status = [[AuthUtil shared] autorize]; + if(status == noErr){ + fchown(fdTool, 0, st.st_gid); + + // Disable group and world writability and make setuid root. + fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH)))/* | S_ISUID*/); + const char *args[] = {"root", [afshlpPath UTF8String],0L}; + [[AuthUtil shared] execUnixCommand:"/usr/sbin/chown" + args:args + output:nil]; + [[AuthUtil shared] deautorize]; + } + } else NSLog(@"st_uid = 0"); + + + + close(fdTool); + + NSLog(@"Self-repair done."); + +} + + +// ------------------------------------------------------------------------------- +// startStopAfs: +// ------------------------------------------------------------------------------- +- (IBAction) startStopAfs:(id) sender +{ + OSStatus status = noErr; + NSString *afsdPath = [TaskUtil searchExecutablePath:@"afsd"]; + //NSString *startStopScript = nil; + NSString *rootHelperApp = nil; + BOOL currentAfsState = NO; + + @try { + if(afsdPath == nil) return; + currentAfsState = [afsProperty checkAfsStatus]; + rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""]; + + //[startStopScript setString: resourcePath]; + NSLog(@"Launch repair HelperTool"); + //Check helper app + [self repairHelperTool]; + + // make the parameter to call the root helper app + status = [[AuthUtil shared] autorize]; + if(status == noErr){ + if(currentAfsState){ + //shutdown afs + NSLog(@"Shutting down afs"); + NSMutableString *afsKextPath = [[NSMutableString alloc] initWithCapacity:256]; + [afsKextPath setString:[afsProperty path]]; + [afsKextPath appendString:@"/etc/afs.kext"]; + + //Make the array for arguments + NSLog(@"executeTaskWithAuth"); + const char *stopAfsArgs[] = {"stop_afs", [afsKextPath UTF8String], [afsdPath UTF8String], 0L}; + [[AuthUtil shared] execUnixCommand:[rootHelperApp UTF8String] + args:stopAfsArgs + output:nil]; + + } else { + NSLog(@"Starting up afs"); + const char *startAfsArgs[] = {[[[self bundle] pathForResource:@"start_afs" ofType:@"sh"] UTF8String], [[afsProperty path] UTF8String], [afsdPath UTF8String], 0L}; + [[AuthUtil shared] execUnixCommand:[rootHelperApp UTF8String] + args:startAfsArgs + output:nil]; + } + } + [self refreshGui:nil]; + } + @catch (NSException * e) { + [self showMessage:[e reason]]; + } + @finally { + [[AuthUtil shared] deautorize]; + } +} + +// ------------------------------------------------------------------------------- +// info: +// ------------------------------------------------------------------------------- +- (void) refreshGui:(NSNotification *)notification{ + BOOL afsIsUp = [afsProperty checkAfsStatus]; + [self setAfsStatus]; + //[self refreshTokens:nil]; + [tokensButton setEnabled:afsIsUp]; + [unlogButton setEnabled:afsIsUp]; +} + +// ------------------------------------------------------------------------------- +// afsVolumeMountChange: Track the afs volume state change +// ------------------------------------------------------------------------------- +- (void) afsVolumeMountChange:(NSNotification *)notification{ + // Cehck if is mounted or unmounted afs + if([[[notification userInfo] objectForKey:@"NSDevicePath"] isEqualToString:@"/afs"]){ + [self setAfsStatus]; + [self refreshTokens:nil]; + } +} + +// ------------------------------------------------------------------------------- +// info: +// ------------------------------------------------------------------------------- +- (IBAction) info:(id) sender +{ + //NSLog(kDevelopInfo); + //[self showMessage:kDevelopInfo]; + [((InfoController*) infoController) showHtmlResource:[[self bundle] pathForResource:@"licenza" ofType:@"rtf"]]; + + [NSApp beginSheet: infoSheet + modalForWindow: [[self mainView] window] + modalDelegate: self + didEndSelector: @selector(didEndInfoSheet:returnCode:contextInfo:) + contextInfo: nil]; +} + +// ------------------------------------------------------------------------------- +// tableDoubleAction: +// ------------------------------------------------------------------------------- +- (IBAction) tableDoubleAction:(id) sender +{ + [self showCellIP:nil]; +} + +// ------------------------------------------------------------------------------- +// getNewToken: +// ------------------------------------------------------------------------------- +- (IBAction) getNewToken:(id) sender +{ + BOOL useAklog = [useAklogCheck state] == NSOnState; + if(useAklog){ + //[AFSPropertyManager aklog]; + [afsProperty getTokens:false + usr:nil + pwd:nil]; + [self refreshTokens:nil]; + //Inform afs menuextra to updata afs status + if ([self isAFSMenuExtraLoaded]) [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange]; + + } else { + [NSBundle loadNibNamed:@"CredentialPanel" owner:self]; + [NSApp beginSheet: credentialSheet + modalForWindow: [[self mainView] window] + modalDelegate: self + didEndSelector: @selector(didEndCredentialSheet:returnCode:contextInfo:) + contextInfo: nil]; + } +} + + +// ------------------------------------------------------------------------------- +// getCurrentCellInDB: +// ------------------------------------------------------------------------------- +- (IBAction) unlog:(id) sender +{ + int index = -1; + NSIndexSet *selectedIndex = [(NSTableView*)tokensTable selectedRowIndexes]; + if( [selectedIndex count] > 0) { + index = [selectedIndex firstIndex]; + do { + NSString *tokenDesc = [tokenList objectAtIndex:index]; + NSString *cellToUnlog = [tokenDesc estractTokenByDelimiter:@"afs@" + endToken:@" "]; + [afsProperty unlog:cellToUnlog]; + } while ((index = [selectedIndex indexGreaterThanIndex: index]) != NSNotFound); + } else { + [afsProperty unlog:nil]; + } + [self refreshTokens:nil]; + //Inform afs menuextra to updata afs status + if ([self isAFSMenuExtraLoaded]) [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange]; + +} + + +// ------------------------------------------------------------------------------- +// aklogSwitchEvent: +// ------------------------------------------------------------------------------- +- (IBAction) aklogSwitchEvent:(id) sender +{ + //afs menu extra is loaded inform it to read preference + @try { + if(![useAklogCheck state]) { + //Remove launchd ctrl file + [PListManager installLaunchdFile:NO resourcePath:[[self bundle] resourcePath]]; + + //deselect the checkbox + [aklogCredentialAtLoginTime setState:NO]; + } + + [self writePreferenceFile]; + + //Enable disable aklog at login time checkbox according the useAklog checkbox + [aklogCredentialAtLoginTime setEnabled:[useAklogCheck state]]; + + } + @catch (NSException * e) { + [self showMessage:[e reason]]; + } + + +} + + +// ------------------------------------------------------------------------------- +// credentialAtLoginTimeEvent: +// ------------------------------------------------------------------------------- +- (IBAction) credentialAtLoginTimeEvent:(id) sender { + @try { + [PListManager installLaunchdFile:[aklogCredentialAtLoginTime state] + resourcePath:[[self bundle] resourcePath]]; + + + + } + @catch (NSException * e) { + if([e userInfo] != nil && [[e userInfo] isKindOfClass:[NSNumber class]]) { + if([((NSNumber*)[e userInfo]) intValue] == 1) { + // the dir HOME_LAUNCHD_AGENT_FOLDER (PListManager.h) must be created + NSBeginAlertSheet([[NSString stringWithString:kDoYouWantCreateTheDirectory] stringByAppendingString:HOME_LAUNCHD_AGENT_FOLDER], + @"Create", @"Cancel", nil, + [[self mainView] window], self, @selector(credentialAtLoginTimeEventCreationLaunchAgentDir:returnCode:contextInfo:), NULL, + nil, @"", nil); + } + } else { + [self showMessage:[e reason]]; + } + } + @finally { + [aklogCredentialAtLoginTime setState:[PListManager checkAklogAtLoginTimeLaunchdEnable]]; + } + +} + +// ------------------------------------------------------------------------------- +// afsStartupSwitchEvent: +// ------------------------------------------------------------------------------- +- (IBAction) afsStartupSwitchEvent:(id) sender { + NSString *rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""]; + //get the new state + NSString *afsdPath = [TaskUtil searchExecutablePath:@"afsd"]; + NSString *afsStartupScriptPath = [[self bundle] pathForResource:@"start_afs" ofType:@"sh"]; + startAFSAtLogin = [checkButtonAfsAtBootTime state]; + const char *startAfsArgs[] = {"load", "-w", [AFS_STARTUP_CONTROL_FILE UTF8String], 0L}; + const char *stopAfsArgs[] = {"unload", "-w", [AFS_STARTUP_CONTROL_FILE UTF8String], 0L}; + const char *launchctlExecutable = "/bin/launchctl"; + /* [PListManager manageAfsStartupLaunchdFile:startAFSAtLogin + afsStartupScript:afsStartupScriptPath + afsBasePath:[afsProperty path] afsdPath:afsdPath]; + */ + const char *startupConfigureOption[] = {"start_afs_at_startup", [afsStartupScriptPath UTF8String], [afsdPath UTF8String], [[afsProperty path] UTF8String], 0L}; + if([[AuthUtil shared] autorize] == noErr) { + if(startAFSAtLogin) { + [[AuthUtil shared] execUnixCommand:[rootHelperApp UTF8String] + args:startupConfigureOption + output:nil]; + + [[AuthUtil shared] execUnixCommand:launchctlExecutable + args:startAfsArgs + output:nil]; + } else { + //now disable the launchd configuration + [[AuthUtil shared] execUnixCommand:launchctlExecutable + args:stopAfsArgs + output:nil]; + } + } +} + +// ------------------------------------------------------------------------------- +// credentialAtLoginTimeEventCreationLaunchAgentDir: +// ------------------------------------------------------------------------------- +- (void) credentialAtLoginTimeEventCreationLaunchAgentDir:(NSWindow*)alert returnCode:(int)returnCode contextInfo:(void *)contextInfo { + [alert close]; + switch (returnCode) { + case 1: + NSLog(@"Yes"); + if([[NSFileManager defaultManager] createDirectoryAtPath:[HOME_LAUNCHD_AGENT_FOLDER stringByExpandingTildeInPath] + attributes:nil]) { + + //Create the file + [PListManager installLaunchdFile:YES + resourcePath:[[self bundle] resourcePath]]; + + //refresh the check box + [aklogCredentialAtLoginTime setState:[PListManager checkAklogAtLoginTimeLaunchdEnable]]; + [self showMessage:kDirectoryCreated]; + } else { + [self showMessage:kErrorCreatingDirectory]; + } + break; + case 0: + NSLog(@"No"); + + break; + } +} + +// ------------------------------------------------------------------------------- +// afsMenuActivationEvent: +// ------------------------------------------------------------------------------- +- (IBAction) krb5KredentialAtLoginTimeEvent:(id) sender { + // + NSString *rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""]; + const char *args[] = {"enable_krb5_startup", [[installKRB5AuthAtLoginButton stringValue] UTF8String], "", 0L}; + + //Check helper app + [self repairHelperTool]; + if([[AuthUtil shared] autorize] == noErr) { + [[AuthUtil shared] execUnixCommand:[rootHelperApp UTF8String] + args:args + output:nil]; + + //check if all is gone well + [installKRB5AuthAtLoginButton setState:[PListManager checkKrb5AtLoginTimeLaunchdEnable]]; + } +} + +// ------------------------------------------------------------------------------- +// afsMenuActivationEvent: +// ------------------------------------------------------------------------------- +-(IBAction) afsMenuActivationEvent:(id) sender +{ + if([(NSButton*)afsMenucheckBox state] == NSOffState){ + // must remove the menu + [self removeAFSMenuExtra]; + } else { + // must add the menu + [self addAFSMenuExtra]; + } +} + +// ------------------------------------------------------------------------------- +// searchCellTextEvent: +// Fileter the CellServDB list according to NSSearch content +// ------------------------------------------------------------------------------- +- (IBAction) searchCellTextEvent:(id) sender +{ + + NSString *searchText = [[textSearchField stringValue] lowercaseString]; //filter string + [self filterCellServDB:searchText]; + [((NSTableView*)cellList) reloadData]; +} + +// ------------------------------------------------------------------------------- +// clearCellServDBFiltering: +// clear the NSSearchField and showw all CellServDB table +// ------------------------------------------------------------------------------- +- (void) clearCellServDBFiltering { + //Clear the text search + [textSearchField setStringValue:@""]; + //load the temp array with all cell servdb + [self searchCellTextEvent:nil]; +} +// --------------------------------------o----------------------------------------- +// filterCellServDB: +// make the NSMutableArray with all cellservdb or filtered element +// ------------------------------------------------------------------------------- +- (void) filterCellServDB:(NSString*)textToFilter { + DBCellElement *cellElement; //Filtered element + BOOL doFilter = !(textToFilter == nil || ([textToFilter length] == 0)); + + // We can do filtering and make the temp array + if(filteredCellDB){ + [filteredCellDB release]; + } + filteredCellDB = [[NSMutableArray alloc] init]; + NSEnumerator *e = [[afsProperty getCellList] objectEnumerator]; + while(cellElement = (DBCellElement*)[e nextObject]) { + // check if the element can be get + if(doFilter) { + //Get the CellServDB array enumerator + //NSLog(@"String for filtering: %s", [textToFilter UTF8String]); + NSRange rsltRng = [[[cellElement getCellName] lowercaseString] rangeOfString:textToFilter]; + if(rsltRng.location != NSNotFound) { + //we can add this cell to filtered + //NSLog(@"Element found during filter: %s", [[cellElement getCellName] UTF8String]); + [filteredCellDB addObject:[cellElement retain]]; + } + } else { + [filteredCellDB addObject:[cellElement retain]]; + + } + } +} + +// ------------------------------------------------------------------------------- +// getCurrentCellInDB: +// ------------------------------------------------------------------------------- +- (DBCellElement*) getCurrentCellInDB +{ + int rowSelected = [((NSTableView *) cellList) selectedRow]; + return [self getCellByIDX:rowSelected]; +} + +// ------------------------------------------------------------------------------- +// getCurrentCellInDB: +// ------------------------------------------------------------------------------- +- (DBCellElement*) getCellByIDX:(int) idx +{ + //NSMutableArray *cellArray = [afsProperty getCellList]; + DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:idx]; + return cellElement; +} + +// ------------------------------------------------------------------------------- +// showMessage: +// ------------------------------------------------------------------------------- +-(void) showMessage:(NSString*) message{ + NSAlert *alert = [[NSAlert alloc] init]; + + [alert setMessageText:message]; + [alert beginSheetModalForWindow:[[self mainView] window] + modalDelegate:nil + didEndSelector:nil + contextInfo:nil]; + [alert release]; +} + +// ------------------------------------------------------------------------------- +// manageButtonState: +// ------------------------------------------------------------------------------- +-(void) manageButtonState:(int) rowSelected { + [((NSControl*) cellIpButton) setEnabled:rowSelected >= 0]; + [((NSControl*) removeCellButton) setEnabled:rowSelected >= 0]; +} + +// ------------------------------------------------------------------------------- +// setAfsStatus: +// ------------------------------------------------------------------------------- +-(void) setAfsStatus +{ + BOOL afsIsUp = [afsProperty checkAfsStatus]; + NSLog(@"Afs is: %s", afsIsUp?"Up":"Down"); + [((NSButton *)startStopButton) setTitle: (afsIsUp?kAfsButtonShutdown:kAfsButtonStartup)]; + + NSMutableAttributedString *colorTitle =[[NSMutableAttributedString alloc] initWithAttributedString:[((NSButton *)startStopButton) attributedTitle]]; + NSRange titleRange = NSMakeRange(0, [colorTitle length]); + + [colorTitle addAttribute:NSForegroundColorAttributeName + value:(afsIsUp?[NSColor redColor]:[NSColor blackColor]) + range:titleRange]; + + [((NSButton *)startStopButton) setAttributedTitle:colorTitle]; + + if(afsIsUp) { + [self startTimer]; + } else { + [self stopTimer]; + } +} + +// ------------------------------------------------------------------------------- +// refreshToken: +// ------------------------------------------------------------------------------- +- (void) refreshTokens:(NSTimer*)theTimer; +{ + if(![tokensLock tryLock]) return; + if(tokenList){ + [tokenList release]; + } + + tokenList = [afsProperty getTokenList]; + [((NSTableView*)tokensTable) reloadData]; + [tokensLock unlock]; +} + + +// ------------------------------------------------------------------------------- +// isExtraMenuLoaded: +// ------------------------------------------------------------------------------- +- (BOOL) isAFSMenuExtraLoaded +{ + void *menu; + if ((CoreMenuExtraGetMenuExtra((CFStringRef)kAFSMenuExtraID, &menu) == 0) && menu) { + return YES; + } + else { + return NO; + } +} + +// ------------------------------------------------------------------------------- +// isExtraMenuLoaded: +// ------------------------------------------------------------------------------- +- (void)addAFSMenuExtra { + + void *menuCracker = 0L; + + //Check for MenuCracker + if ((CoreMenuExtraGetMenuExtra((CFStringRef)kMenuCrakerMenuExtraID, &menuCracker) != 0) || !menuCracker) { + NSLog(@"MenuCracker not present"); + + // load the MenuCracker.menu menu extra + CoreMenuExtraAddMenuExtra((CFURLRef)kMenuCrakerMenuExtra, 0, 0, 0, 0, 0); + } else NSLog(@"MenuCracker alredy loaded"); + + + //Load the AFSCommander menu extra + CoreMenuExtraAddMenuExtra((CFURLRef)kAFSMenuExtra, 0, 0, 0, 0, 0); +} + +// ------------------------------------------------------------------------------- +// removeExtra: +// ------------------------------------------------------------------------------- +- (IBAction) addLink:(id) sender { + [NSBundle loadNibNamed:@"SymLinkEdit" owner:self]; + + [NSApp beginSheet: lyncCreationSheet + modalForWindow: [[self mainView] window] + modalDelegate: self + didEndSelector: @selector(didEndSymlinkSheet:returnCode:contextInfo:) + contextInfo: nil]; + +} + +// ------------------------------------------------------------------------------- +// removeExtra: +// ------------------------------------------------------------------------------- +- (IBAction) removeLink:(id) sender { + +} + +// ------------------------------------------------------------------------------- +// removeExtra: +// ------------------------------------------------------------------------------- +- (IBAction) enableLink:(id) sender { + +} + + +// ------------------------------------------------------------------------------- +// removeExtra: +// ------------------------------------------------------------------------------- +- (void)removeAFSMenuExtra{ + void *menu; + if ((CoreMenuExtraGetMenuExtra((CFStringRef)kAFSMenuExtraID, &menu) == 0) && menu) { + CoreMenuExtraRemoveMenuExtra(menu, 0); + } +} + + +// ------------------------------------------------------------------------------- +// mextraChangeActivation: +// ------------------------------------------------------------------------------- +- (void)mextraChangeActivation:(NSNotification *)notification +{ + // set the afsmenu check state + [(NSButton*)afsMenucheckBox setState: [self isAFSMenuExtraLoaded]?NSOnState:NSOffState]; +} +@end + +@implementation AFSCommanderPref (NSTableDataSource) + + +// ------------------------------------------------------------------------------- +// tableView: +// Manage the checkbox of CellServDB Table + +// ------------------------------------------------------------------------------- +- (void)tableView:(NSTableView *)table + setObjectValue:(id)data + forTableColumn:(NSTableColumn *)col + row:(int)row +{ + NSString *identifier = (NSString*)[col identifier]; + switch([table tag]){ + case TABLE_TOKENS_LIST: + break; + + case TABLE_CELL_LIST: + // we are editing checkbox for cellservdb table + if([identifier intValue] == CELLSRVDB_TABLE_USR_DFLT_CHECK_COLUMN) { + // set the user default cell + DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:row]; + [afsProperty setDefaultCellByName:[cellElement getCellName]]; + //[afsDefaultCellLabel setStringValue:[afsProperty getDefaultCellName]]; + [((NSTableView*)cellList) reloadData]; + } else if([identifier intValue] == CELLSRVDB_TABLE_DFLT_CHECK_COLUMN) { + // set the cell for wich the user want to get token + DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:row]; + [cellElement setUserDefaultForToken:![cellElement userDefaultForToken]]; + } + break; + } + +} + + +// ------------------------------------------------------------------------------- +// tableView: +// refresh delegate method for two AFSCommander table +// ------------------------------------------------------------------------------- +- (id) tableView:(NSTableView *) aTableView + objectValueForTableColumn:(NSTableColumn *) aTableColumn + row:(int) rowIndex +{ + + id result = nil; + NSString *identifier = (NSString*)[aTableColumn identifier]; + switch([aTableView tag]){ + case TABLE_TOKENS_LIST: + //We are refreshing tokens table + result = [self getTableTokensListValue:[identifier intValue] row:rowIndex]; + break; + + case TABLE_CELL_LIST: + //We are refreshing cell db table + result = [self getTableCelListValue:[identifier intValue] row:rowIndex]; + break; + + } + return result; +} + + +// ------------------------------------------------------------------------------- +// getTableCelListValue: +// ------------------------------------------------------------------------------- +- (id)getTableTokensListValue:(int) colId row:(int)row +{ + id result = nil; + if(!tokenList) return nil; + switch(colId){ + case 0: + result = (NSString*)[tokenList objectAtIndex:row]; + break; + } + return result; +} + + +// ------------------------------------------------------------------------------- +// getTableCelListValue: +// ------------------------------------------------------------------------------- +- (id)getTableCelListValue:(int) colId row:(int)row +{ + id result = nil; + //NSMutableArray *cellArray = [afsProperty getCellList]; + DBCellElement *cellElement = (DBCellElement*)[filteredCellDB objectAtIndex:row]; + switch(colId){ + case CELLSRVDB_TABLE_USR_DFLT_CHECK_COLUMN: + result = [NSNumber numberWithInt:[cellElement userDefaultForCell]]; + break; + + case CELLSRVDB_TABLE_DFLT_CHECK_COLUMN: + result = [NSNumber numberWithInt:[cellElement userDefaultForToken]]; + break; + case CELLSRVDB_TABLE_NAME_COLUMN: + result = [cellElement getCellName]; + break; + + case CELLSRVDB_TABLE_DESCRIPTION_COLUMN: + result = [cellElement getCellComment]; + break; + } + return result; +} + +// ------------------------------------------------------------------------------- +// numberOfRowsInTableView: +// ------------------------------------------------------------------------------- +- (int)numberOfRowsInTableView:(NSTableView *)aTableView +{ + int rowCount = 0; + //NSMutableArray *cellArray = nil; + switch([aTableView tag]){ + case TABLE_TOKENS_LIST: + if(tokenList) rowCount = [tokenList count]; + break; + + case TABLE_CELL_LIST: + //cellArray = [afsProperty getCellList]; + if(filteredCellDB) rowCount = [filteredCellDB count]; + break; + + } + return rowCount; +} + + +@end + + +@implementation AFSCommanderPref (TableDelegate) +// ------------------------------------------------------------------------------- +// selectionShouldChangeInTableView: +// ------------------------------------------------------------------------------- +- (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTable +{ + [self manageButtonState:[aTable selectedRow]]; + return YES; +} + +// ------------------------------------------------------------------------------- +// tableView: +// ------------------------------------------------------------------------------- +- (BOOL)tableView:(NSTableView *)aTable shouldSelectRow:(int)aRow +{ + [self manageButtonState:aRow]; + return YES; +} + +@end + + +@implementation AFSCommanderPref (ModalDelegate) +// ------------------------------------------------------------------------------- +// didEndSheet: +// ------------------------------------------------------------------------------- +- (void)didEndSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + NSLog(@"didEndSheet"); + [sheet orderOut:self]; + //Filter the cellServDb and allocate filtered array + [self searchCellTextEvent:nil]; + [((NSTableView*)cellList) reloadData]; + NSLog(@"Has saved %s:", ([((IpConfiguratorCommander*) ipConfControllerCommander) saved])?"YES":"NO"); +} + +// ------------------------------------------------------------------------------- +// Klog credential request +// ------------------------------------------------------------------------------- +- (void)didEndCredentialSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + NSLog(@"didEndCredentialSheet"); + if([((TokenCredentialController*)credentialCommander) takenToken] == YES){ + /*[AFSPropertyManager klog:[((TokenCredentialController*)credentialCommander) uName] + uPwd:[((TokenCredentialController*)credentialCommander) uPwd] ];*/ + [afsProperty getTokens:true + usr:[((TokenCredentialController*)credentialCommander) uName] + pwd:[((TokenCredentialController*)credentialCommander) uPwd]]; + } + [sheet orderOut:self]; + [self refreshTokens:nil]; + //Inform afs menuextra to updata afs status + if ([self isAFSMenuExtraLoaded]) [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange]; + +} + +// ------------------------------------------------------------------------------- +// Klog credential request +// ------------------------------------------------------------------------------- +- (void)didEndInfoSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + NSLog(@"didEndInfoSheet"); + [sheet orderOut:self]; +} + +// ------------------------------------------------------------------------------- +// symlink edite +// ------------------------------------------------------------------------------- +- (void)didEndSymlinkSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo +{ + NSLog(@"didEndSymlinkSheet"); + [lyncCreationSheet orderOut:self]; +} +@end + +// ------------------------------------------------------------------------------- +// AFSCommanderPref(NSTabViewDelegator) - delegate for nstabview in +// main preference view +// ------------------------------------------------------------------------------- +@implementation AFSCommanderPref(NSTabViewDelegator) +- (void)tabView:(NSTabView *)tabView willSelectTabViewItem: (NSTabViewItem *)tabViewItem +{ + //check to see if the cache param tab is the tab that will be selected + if([((NSString*)[tabViewItem identifier]) intValue] == TAB_GROUP) + { + //get + NSLog(@"cache param tab"); + // [groupsBox setHidden:YES]; + NSLog([groupsBox title]); + [ViewUtility enbleDisableControlView:[groupsBox contentView] + controlState:NO]; + } +} +@end \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/AFSCommander_Prefix.pch b/src/platform/DARWIN/AFSPreference/AFSCommander_Prefix.pch new file mode 100644 index 000000000..4141e70ef --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSCommander_Prefix.pch @@ -0,0 +1,9 @@ +// +// Prefix header for all source files of the 'AFSCommander' target in the 'AFSCommander' project. +// + +#ifdef __OBJC__ + #import + #import + +#endif diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.h b/src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.h new file mode 100644 index 000000000..5dca5fae2 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.h @@ -0,0 +1,24 @@ +// +// AFSMenuCredentialContoller.h +// AFSCommander +// +// Created by Claudio on 14/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "CredentialWindowController.h" +#import "AFSPropertyManager.h" + +@interface AFSMenuCredentialContoller : NSObject { + NSRect viewRect; + id credentialView; + id credentialController; + NSPanel *credentialWindow; + id credWinController; + AFSPropertyManager *afsPropMngr; +} +-(id) initWhitRec:(NSRect)rect afsPropManager:(AFSPropertyManager*)afsPropManager; +-(void) showWindow; +-(void) closeWindow; +@end diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.m b/src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.m new file mode 100644 index 000000000..5775246f5 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuCredentialContoller.m @@ -0,0 +1,67 @@ +// +// AFSMenuCredentialContoller.m +// AFSCommander +// +// Created by Claudio on 14/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "AFSMenuCredentialContoller.h" +#import "CredentialWindowController.h" +#import "global.h" +#import "AFSPropertyManager.h" + +@implementation AFSMenuCredentialContoller + +-(id) initWhitRec:(NSRect)rect afsPropManager:(AFSPropertyManager*)afsPropManager; +{ + viewRect = rect; + credentialWindow = nil; + afsPropMngr = [afsPropManager retain]; + NSLog(@"init AFSMenuCredentialContoller"); + return [self init]; +} + +- (void)dealloc { + NSLog(@"dealloc AFSMenuCredentialContoller"); + if(credentialWindow) [credentialWindow release]; + [super dealloc]; + +} // dealloc + +-(void) showWindow +{ + // calculate the point where show the window + NSPoint topLeft = {viewRect.origin.x-160,[[NSScreen mainScreen] frame].size.height-kMenuBarHeight}; + NSLog(@"viewRect.origin.x=%d, topLeft.x=%d", viewRect.origin.x, topLeft.x); + // load the bundle for + [NSBundle loadNibNamed:@"CredentialWindow.nib" owner:self]; + NSLog(@"prepare to open window CredentialWindow"); + + credentialWindow = [[NSWindow alloc] initWithContentRect:[((NSView*) credentialView) frame] + styleMask:NSTitledWindowMask /*| NSUtilityWindowMask*/ + backing:NSBackingStoreBuffered + defer:YES screen:[NSScreen mainScreen]]; + NSLog(@"Finestra"); + [credentialWindow setTitle:@"Klog"]; + [credentialWindow setFrameTopLeftPoint:topLeft]; + [credentialWindow setContentView:credentialView]; + [credentialWindow makeKeyAndOrderFront:self]; + NSLog(@"creata"); + +} + +-(void) closeWindow +{ + NSLog(@"closeWindow"); + if([(CredentialWindowController*)credWinController takenToken] && afsPropMngr) { + [afsPropMngr getTokens:true + usr:[(CredentialWindowController*)credWinController uName] + pwd:[(CredentialWindowController*)credWinController uPwd]]; + [afsPropMngr release]; + afsPropMngr = nil; + } + [credentialWindow close]; + credentialWindow = nil; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuExtra-Info.plist b/src/platform/DARWIN/AFSPreference/AFSMenuExtra-Info.plist new file mode 100644 index 000000000..c50ffe108 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuExtra-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + it.infn.lnf.network.AFSMenuExtra + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + INFN + CFBundleVersion + 1.0 + NSPrincipalClass + AFSMenuExtra + + diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuExtra.h b/src/platform/DARWIN/AFSPreference/AFSMenuExtra.h new file mode 100644 index 000000000..1c41e242f --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuExtra.h @@ -0,0 +1,57 @@ +// +// AFSMenuExtra.h +// AFSCommander +// +// Created by Claudio on 10/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + + +#import +#import "SystemUIPlugin.h" +#import "global.h" +#import "AFSMenuCredentialContoller.h" +@class AFSMenuExtraView; +@interface AFSMenuExtra : NSMenuExtra { + @public + BOOL afsState; //0-off 1-on + BOOL gotToken; //0-no 1-one o more token + + @protected + NSString *afsSysPath; + NSNumber *useAklogPrefValue; + //menu extra + NSMenu *theMenu; + + //Menu extra view + AFSMenuExtraView *theView; + // menu reference + NSMenuItem *startStopMenu; + NSMenuItem *loginMenu; + NSMenuItem *unlogMenu; + + //Icon for state visualization + NSImage *hasTokenImage; + NSImage *noTokenImage; + + //credential windows mainWindow + AFSMenuCredentialContoller *credentialMenuController; + + //NSTimer for tokens refresh + NSTimer *timerForCheckTokensList; + NSLock *tokensLock; +} +- (void)startTimer; +- (void)stopTimer; +- (BOOL)useAklogPrefValue; +- (void)readPreferenceFile:(NSNotification *)notification; +- (void)getToken:(id)sender; +- (void)releaseToken:(id)sender; +- (void)updateAfsStatus:(NSTimer*)timer; +- (void)klogUserEven:(NSNotification *)notification; +- (NSImage*)getImageFromBundle:(NSString*)fileName fileExt:(NSString*)ext; +- (NSImage*)imageToRender; +- (void)updateMenu; +- (void)repairHelperTool; +- (void) afsVolumeMountChange:(NSNotification *)notification; +@end diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuExtra.m b/src/platform/DARWIN/AFSPreference/AFSMenuExtra.m new file mode 100644 index 000000000..76f079c50 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuExtra.m @@ -0,0 +1,435 @@ +// +// AFSMenuExtra.m +// AFSCommander +// +// Created by Claudio on 10/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "AFSMenuExtra.h" +#import "AFSMenuExtraView.h" +#import "AFSPropertyManager.h" +#import "TaskUtil.h" +#import "TokenCredentialController.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +@implementation AFSMenuExtra +// ------------------------------------------------------------------------------- +// -(id) initWithBundle +// ------------------------------------------------------------------------------- +- (id) initWithBundle:(NSBundle *)bundle +{ + self = [super initWithBundle:bundle]; + if( self == nil ) + return nil; + + // allocate the lock + tokensLock = [[NSLock alloc] init]; + // inizialize the afspath + afsSysPath = nil; + credentialMenuController = nil; + + theView = [[AFSMenuExtraView alloc] initWithFrame:[[self view] frame] + menuExtra:self]; + [self setView:theView]; + + + // Get the imge for menu + //Load image for menu rappresentation + hasTokenImage = [self getImageFromBundle:@"hasToken" + fileExt:@"png"]; + + noTokenImage = [self getImageFromBundle:@"noToken" + fileExt:@"png"]; + + theMenu = [[NSMenu alloc] initWithTitle: @""]; + [theMenu setAutoenablesItems: NO]; + startStopMenu = [theMenu addItemWithTitle: kAfsOff action: @selector(startStopAfs:) keyEquivalent: @""]; + [startStopMenu setTarget:self]; + + loginMenu = [theMenu addItemWithTitle: kMenuLogin action: @selector(getToken:) keyEquivalent: @""]; + [loginMenu setTarget:self]; + + unlogMenu = [theMenu addItemWithTitle: kMenuUnlog action: @selector(releaseToken:) keyEquivalent: @""]; + [unlogMenu setTarget:self]; + + // Register for preference user change + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(readPreferenceFile:) + name:kAFSMenuExtraID object:kPrefChangeNotification]; + + // Register for afs state change + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(afsVolumeMountChange:) + name:kAFSMenuExtraID object:kMExtraAFSStateChange]; + + + //Register for mount/unmount afs volume + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self + selector:@selector(afsVolumeMountChange:) + name:NSWorkspaceDidMountNotification object:nil]; + + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self + selector:@selector(afsVolumeMountChange:) + name:NSWorkspaceDidUnmountNotification object:nil]; + //Start to read the afs path + [self readPreferenceFile:nil]; + [self startTimer]; + return self; +} + +// ------------------------------------------------------------------------------- +// -(void) willUnload +// ------------------------------------------------------------------------------- +- (void) willUnload { + //release the lock + [self stopTimer]; + + if(hasTokenImage) [hasTokenImage release]; + if(noTokenImage) [noTokenImage release]; + + // Unregister for preference change + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kAFSMenuExtraID object:kPrefChangeNotification]; + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kAFSMenuExtraID object:kMExtraAFSStateChange]; + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidMountNotification object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self name:NSWorkspaceDidUnmountNotification object:nil]; + + + [tokensLock release]; +} + +// ------------------------------------------------------------------------------- +// startTimer: +// ------------------------------------------------------------------------------- +- (void)startTimer{ + //start the time for check tokens validity + if(timerForCheckTokensList) return; + timerForCheckTokensList = [NSTimer scheduledTimerWithTimeInterval:TOKENS_REFRESH_TIME_IN_SEC + target:self + selector:@selector(updateAfsStatus:) + userInfo:nil + repeats:YES]; + [timerForCheckTokensList fire]; +} + +// ------------------------------------------------------------------------------- +// stopTimer: +// ------------------------------------------------------------------------------- +- (void)stopTimer{ + if(!timerForCheckTokensList) return; + [timerForCheckTokensList invalidate]; + timerForCheckTokensList = nil; +} +// ------------------------------------------------------------------------------- +// -(void) dealloc +// ------------------------------------------------------------------------------- +- (void) dealloc +{ + [theMenu release]; + [theView release]; + if(afsSysPath) [afsSysPath release]; + // send notify that menuextra has closed + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:afsCommanderID object:kPrefChangeNotification]; + [super dealloc]; +} + +// ------------------------------------------------------------------------------- +// -(NSMenu*) menu +// ------------------------------------------------------------------------------- +- (NSMenu *) menu +{ + return theMenu; +} + + +// ------------------------------------------------------------------------------- +// -(void) readPreferenceFile +// ------------------------------------------------------------------------------- +- (void) readPreferenceFile:(NSNotification *)notification +{ + NSLog(@"Reading preference file"); + //CFPreferencesSynchronize((CFStringRef)afsCommanderID, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + //CFPreferencesSynchronize((CFStringRef)afsCommanderID, kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + if(afsSysPath) { + [afsSysPath release]; + afsSysPath = nil; + } + + afsSysPath = PREFERENCE_AFS_SYS_PAT_STATIC;/*(NSString*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_AFS_SYS_PAT, + (CFStringRef)afsCommanderID, + kCFPreferencesAnyUser, + kCFPreferencesAnyHost);*/ + //NSLog(@"Path readed %s", (afsSysPath==nil?[afsSysPath UTF8String]:@" no path found ")); + + // read the preference for aklog use + useAklogPrefValue = (NSNumber*)CFPreferencesCopyValue((CFStringRef)PREFERENCE_USE_AKLOG, + (CFStringRef)afsCommanderID, + kCFPreferencesCurrentUser, + kCFPreferencesAnyHost); + //set the menu name + //NSLog(@"Preference readed for useAklogPrefValue %d", [useAklogPrefValue intValue]); + + [self updateAfsStatus:nil]; +} + +// ------------------------------------------------------------------------------- +// -(void) readPreferenceFile +// ------------------------------------------------------------------------------- +- (void)startStopAfs:(id)sender +{ + NSLog(@"startStopAfs: %s",[afsSysPath UTF8String]); + if(!afsSysPath) return; + + OSStatus status = noErr; + NSString *afsdPath = [TaskUtil searchExecutablePath:@"afsd"]; + NSString *rootHelperApp = nil; + BOOL currentAfsState = NO; + + @try { + if(afsdPath == nil) return; + AFSPropertyManager *afsMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath]; + currentAfsState = [afsMngr checkAfsStatus]; + [afsMngr release]; + + rootHelperApp = [[self bundle] pathForResource:@"afshlp" ofType:@""]; + + //[startStopScript setString: resourcePath]; + //NSLog(@"LAunch repair HelperTool"); + //Check helper app + [self repairHelperTool]; + + // make the parameter to call the root helper app + //NSLog(@"Path installazione afs: %s",[afsSysPath UTF8String]); + //NSLog(@"Path installazione afsd: %s", [afsdPath UTF8String]); + status = [[AuthUtil shared] autorize]; + if(status == noErr){ + if(currentAfsState){ + //shutdown afs + //NSLog(@"Shutting down afs"); + NSMutableString *afsKextPath = [[NSMutableString alloc] initWithCapacity:256]; + [afsKextPath setString:afsSysPath]; + [afsKextPath appendString:@"/etc/afs.kext"]; + + //NSLog(@"executeTaskWithAuth"); + const char *stopAfsArgs[] = {"stop_afs", [afsKextPath UTF8String], [afsdPath UTF8String], 0L}; + [[AuthUtil shared] execUnixCommand:[rootHelperApp UTF8String] + args:stopAfsArgs + output:nil]; + } else { + //NSLog(@"Starting up afs"); + const char *startAfsArgs[] = {[[[self bundle] pathForResource:@"start_afs" ofType:@"sh"] UTF8String], [afsSysPath UTF8String], [afsdPath UTF8String], 0L}; + [[AuthUtil shared] execUnixCommand:[rootHelperApp UTF8String] + args:startAfsArgs + output:nil]; + } + } + } + @catch (NSException * e) { + NSLog([e reason]); + } + @finally { + [[AuthUtil shared] deautorize]; + [self updateAfsStatus:nil]; + //Send notification to preferencepane + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:afsCommanderID object:kMenuExtraEventOccured]; + } + +} + +// ------------------------------------------------------------------------------- +// -(void) getToken +// ------------------------------------------------------------------------------- +- (void)getToken:(id)sender +{ + + NSRect globalRect; + globalRect.origin = [[[self view] window] convertBaseToScreen:[[self view] frame].origin]; + globalRect.size = [[self view] frame].size; + AFSPropertyManager *afsPropMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath ]; + [afsPropMngr loadConfiguration]; + + + if([useAklogPrefValue intValue]==NSOnState ) { + NSLog(@"Use Aklog"); + [afsPropMngr getTokens:false + usr:nil + pwd:nil]; + [self klogUserEven:nil]; + } else { + NSLog(@"Use Klog"); + // register for user event + [[NSDistributedNotificationCenter defaultCenter] addObserver:self + selector:@selector(klogUserEven:) + name:kAFSMenuExtraID + object:kLogWindowClosed]; + + credentialMenuController = [[AFSMenuCredentialContoller alloc] initWhitRec:globalRect + afsPropManager:afsPropMngr]; + [credentialMenuController showWindow]; + } + + //Dispose afs manager + [afsPropMngr release]; +} + +// ------------------------------------------------------------------------------- +// -(void) releaseToken +// ------------------------------------------------------------------------------- +- (void)releaseToken:(id)sender +{ + AFSPropertyManager *afsMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath]; + [afsMngr unlog:nil]; + [afsMngr release]; + [self updateAfsStatus:nil]; +} + + +// ------------------------------------------------------------------------------- +// -(void) afsVolumeMountChange - Track for mount unmount afs volume +// ------------------------------------------------------------------------------- +- (void) afsVolumeMountChange:(NSNotification *)notification{ + [self updateAfsStatus:nil]; +} + +// ------------------------------------------------------------------------------- +// -(void) updateAfsStatus +// ------------------------------------------------------------------------------- +- (void)updateAfsStatus:(NSTimer*)timer +{ + //Try to locking + if(![tokensLock tryLock]) return; + + // check the afs state in esclusive mode + AFSPropertyManager *afsMngr = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath]; + afsState = [afsMngr checkAfsStatus]; + + NSArray *tokens = [afsMngr getTokenList]; + [afsMngr release]; + gotToken = [tokens count] > 0; + [tokens release]; + // update the menu item title + [startStopMenu setTitle:afsState?kAfsButtonShutdown:kAfsButtonStartup]; + + [self updateMenu]; + + [theView setNeedsDisplay:YES]; + + //unlock + [tokensLock unlock]; +} + +// ------------------------------------------------------------------------------- +// -(void) klogUserEven +// ------------------------------------------------------------------------------- +-(void) klogUserEven:(NSNotification *)notification +{ + if(credentialMenuController) { + [[NSDistributedNotificationCenter defaultCenter] removeObserver:self name:kAFSMenuExtraID object:kLogWindowClosed]; + [credentialMenuController closeWindow]; + [credentialMenuController release]; + credentialMenuController = nil; + } + //Send notification to PreferencePane + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:afsCommanderID object:kMenuExtraEventOccured]; + + [self updateAfsStatus:nil]; +} + +// ------------------------------------------------------------------------------- +// -(void) getImageFromBundle +// ------------------------------------------------------------------------------- +- (NSImage*)getImageFromBundle:(NSString*)fileName fileExt:(NSString*)ext +{ + return [[NSImage alloc]initWithContentsOfFile:[[self bundle] pathForResource:fileName + ofType:ext]]; +} + +// ------------------------------------------------------------------------------- +// -(void) imageToRender +// ------------------------------------------------------------------------------- +- (NSImage*)imageToRender +{ + if(gotToken){ + return hasTokenImage; + } else { + return noTokenImage; + } +} + + +// ------------------------------------------------------------------------------- +// -(void) updateMenu +// ------------------------------------------------------------------------------- +- (void)updateMenu{ + [loginMenu setEnabled:afsState]; + [unlogMenu setEnabled:afsState]; +} + + +// ------------------------------------------------------------------------------- +// -(void) useAklogPrefValue +// ------------------------------------------------------------------------------- +- (BOOL)useAklogPrefValue +{ + if(useAklogPrefValue) return [useAklogPrefValue intValue] == NSOnState; + else return NSOffState; +} + +// ------------------------------------------------------------------------------- +// repairHelperTool: +// ------------------------------------------------------------------------------- +- (void) repairHelperTool +{ + struct stat st; + int fdTool; + int status = 0; + NSLog(@"repairHelperTool"); + NSString *afshlpPath = [[self bundle] pathForResource:@"afshlp" ofType:nil]; + + + + // Open tool exclusively, so nobody can change it while we bless it. + fdTool = open([afshlpPath UTF8String], O_NONBLOCK | O_RDONLY | O_EXLOCK, 0); + + if(fdTool == -1) + { + NSLog(@"Exclusive open while repairing tool failed: %d.", errno); + exit(-1); + } + + if(fstat(fdTool, &st)) + { + NSLog(@"fstat failed."); + exit(-1); + } + + if(st.st_uid != 0) + { + status = [[AuthUtil shared] autorize]; + if(status == noErr){ + fchown(fdTool, 0, st.st_gid); + + // Disable group and world writability and make setuid root. + fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH)))/* | S_ISUID*/); + const char *args[] = {"root", [afshlpPath UTF8String],0L}; + [[AuthUtil shared] execUnixCommand:"/usr/sbin/chown" + args:args + output:nil]; + [[AuthUtil shared] deautorize]; + } + } else NSLog(@"st_uid = 0"); + + + + close(fdTool); + + NSLog(@"Self-repair done."); + +}@end diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuExtraView.h b/src/platform/DARWIN/AFSPreference/AFSMenuExtraView.h new file mode 100644 index 000000000..8869c1c71 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuExtraView.h @@ -0,0 +1,18 @@ +// +// AFSMenuExtraView.h +// AFSCommander +// +// Created by Claudio Bisegni on 11/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "SystemUIPlugin.h" +#import "AFSMenuExtra.h" + +@interface AFSMenuExtraView : NSMenuExtraView { + AFSMenuExtra *theMenuExtra; + +} +- (NSAttributedString*) makeKerberosIndicator:(int*)fontHeight; +@end diff --git a/src/platform/DARWIN/AFSPreference/AFSMenuExtraView.m b/src/platform/DARWIN/AFSPreference/AFSMenuExtraView.m new file mode 100644 index 000000000..0c6aee8a3 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSMenuExtraView.m @@ -0,0 +1,72 @@ +// +// AFSMenuExtraView.m +// AFSCommander +// +// Created by Claudio Bisegni on 11/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "AFSMenuExtraView.h" +#import "AFSPropertyManager.h" +@implementation AFSMenuExtraView + +- initWithFrame:(NSRect)myRect menuExtra:(AFSMenuExtra*)myExtra { + + // Have super init + self = [super initWithFrame:myRect]; + if(!self) { + return nil; + } + + // Store our extra + theMenuExtra = myExtra; + + // Send it on back + return self; + +} // initWithFrame + +- (void)dealloc { + + [super dealloc]; + +} // dealloc + +- (void)drawRect:(NSRect)rect +{ + NSImage *image = nil; + int fontHeight = 0; + NSAttributedString *kerberosStringIndicator = nil; + + image = [theMenuExtra imageToRender]; + if (image) { + // Live updating even when menu is down handled by making the extra + // draw the background if needed. + if ([theMenuExtra isMenuDown]) { + [theMenuExtra drawMenuBackground:YES]; + } + [image compositeToPoint:NSMakePoint(0, 0) operation:NSCompositeSourceOver]; + } + + //Draw, if necessary, the kerberos indicator for aklog usage for get token + if([theMenuExtra useAklogPrefValue] == NSOnState) { + kerberosStringIndicator = [[self makeKerberosIndicator:&fontHeight] autorelease]; + if(kerberosStringIndicator) [kerberosStringIndicator drawAtPoint:NSMakePoint(0, kMenuBarHeight-fontHeight)]; + } +} + +/*! + @method makeKerberosIndicator + @abstract Make the kerberos indicator + @discussion Make a letter to render in menu view to inform the user if is enable aklog use +*/ +- (NSAttributedString*) makeKerberosIndicator:(int*)fontHeight { + NSFont *font = [NSFont fontWithName:@"Palatino-Roman" size:9.0]; + NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObject:font + forKey:NSFontAttributeName]; + NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:@"K" + attributes:attrsDictionary]; + *fontHeight = [attrString size].height; + return attrString; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h new file mode 100644 index 000000000..9b1ab28ca --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h @@ -0,0 +1,397 @@ +// +// AFSPropertyManager.h +// AFSCommander +// +// Created by Claudio Bisegni on 21/05/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "DBCellElement.h" +#import "FileUtil.h" + +/*! + @class AFSPropertyManager + @abstract AFS Manage Class + @discussion This class manage the openafs param for celldbserv, cache param, group creation, get and release token +*/ + +@interface AFSPropertyManager : NSObject { + NSString *installationPath; + NSString *cellName; + NSMutableArray *cellList; + NSArray *userDefaultCellArray; + NSString *afsRootMountPoint; + int statCacheEntry; + int dCacheDim; + int cacheDimension; + int daemonNumber; + int nVolEntry; + bool dynRoot; + bool afsDB; + bool verbose; + + //------------------- + FileUtil *futil; + BOOL useAfsdConfVersion; +} + +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) +*/ +-(id) init; + +/*! +@function initWithAfsPath + @abstract (description) + @discussion (description) + @param path Path di installazione afs + @result Istanza della classe di gestione delle propieta' afs + */ +- (id)initWithAfsPath:(NSString*)path; + +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) +*/ +-(void) dealloc; +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) + */ +-(NSMutableArray*) getCellList; + + +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) + */ +-(NSArray*) getAllCellsName; +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) + */ +-(NSArray*) getUserDefaultForTokenCells; +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) + */ +-(NSArray*) getDefaultForTokenCellsName; +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) + */ +-(NSString*) getDefaultCellName; + +/*! + @method setDefaultCellByName + @abstract set the cell named "name" to be se user default + @discussion first clean the last one selected as default and then set the cell named "name" as default user cell + */ +-(void) setDefaultCellByName:(NSString*)name; + +/*! + @method + @abstract (brief description) + @discussion (comprehensive description) + */- (void) setCellName:(NSString*)cell; + +/*! + @method setPath + @abstract Imposta Path + @discussion Imposta il path dove e' installato afs, in modo da leggere e scrivere le configurazioni +*/ +-(void) setPath:(NSString*)path; + +/*! + @method path + @abstract Return the afs base + @discussion Return the Afs base installation path +*/ +-(NSString*) path; + +/*! + @function statCacheEntry + @abstract get the afs number of state cache entry + @discussion + @result Number of stat cache entry + */ +-(int) statCacheEntry; + + +/*! + @function setStatCacheEntry + @abstract Set the afs number of state cache entry + @discussion + @result Number of stat cache entry + */ +-(void) setStatCacheEntry:(int)statEntry; + +/*! +@function dCacheDim +@abstract return the dCacheDim param value for cache manager +@result dCacheDim value +*/ +-(int) dCacheDim; + +/*! + @function setDCacheDim + @abstract set the setDCacheDim value for cache manager param + @discussion <#(description)#> + @param dcacheDim cache param value + */ +-(void) setDCacheDim:(int)dcacheDim; + +/*! + @function cacheDimension + @abstract return the max size of the cache + @result Cache dimension + */ +-(int) cacheDimension; + +/*! + @function setCacheDimension + @abstract Set the max cache dimension + @discussion + @param cacheDim MAx Chace dimension + */ +-(void) setCacheDimension:(int)cacheDim; + +/*! + @function daemonNumber + @abstract Return the number of daemon for the cache manager + @result Number of daemon + */ +-(int) daemonNumber; + +/*! + @function setDaemonNumber + @abstract Set the daemon numbero for the cache manager + @param dNumber number of daemon + */ +-(void) setDaemonNumber:(int)dNumber; + +/*! + @function afsRootMountPoint + @abstract Return the path where afs root volume will be mounted + @result AFS mount point + */ +-(NSString*) afsRootMountPoint; + +/*! + @function setAfsRootMountPoint + @abstract Set the AFS mount point + @param mountPoint AFS mount point + */ +-(void) setAfsRootMountPoint:(NSString*)mountPoint; + +/*! + @function nVolEntry + @abstract Return the nVolEntry for cache manager + @result value for nVolEntry cache parameter + */ +-(int) nVolEntry; + +/*! + @function setNVolEntry + @abstract Set the nVolEntry parameter for cache manager + @param entry value for nVolEntry cache manager parameter + */ +-(void) setNVolEntry:(int)entry; + +/*! + @function dynRoot + @abstract Return the DynRoot parametr for cache manager + @result dynRoot parameter value + */ +-(bool) dynRoot; + +/*! + @function setDynRoot + @abstract Set the DynRoot flag value for cache manager + @param flag dynRoot state (enable/disable) + */ +-(void) setDynRoot:(bool)flag; +/*! + @function afsDB + @abstract Get the afsdb flag value for cache manager + @result Return the value of the flag + */ +-(bool) afsDB; + +/*! + @function setAfsDB + @abstract Set the flag value for afsdb cache manager + @param flag AfsDB state (enable/disable) + */ +-(void) setAfsDB:(bool)flag; +/*! + @function verbose + */ +-(bool) verbose; + +/*! + @function setVerbose + */ +-(void) setVerbose:(bool)flag; +/*! + @function readCacheInfo + @abstract Read the cache info + @discussion The cache info is read from the file pointed by filePath param + @param filePath file location for the CacheInfo + */ +-(void) readCacheInfo:(NSString*)filePath; + +/*! + @function writeCacheInfo + @abstract Write the cache info down the file + @param filePath where to write the CacheInfo + @result return the execution error + */ +-(int) writeCacheInfo:(NSString*)filePath; + +/*! + @function readAfsdOption + @abstract Read the afs option + @discussion Read the afs option checking firt the afs version so it can read the old afsd.option or afs.conf file. If any error accour an NSException wil be trown + @param filePath file where the parameter are store for default afsd.option or afs.conf + */ +-(void) readAfsdOption:(NSString*)filePath; + +/*! + @function readOldAfsdOption + @abstract Read the afsd.option file + @discussion Read the old afsd.option style afsd option file. If any error accour an NSException wil be trown22 + @param filePath file path to afsd.option like file + @result <#(description)#> + */ +-(void) readOldAfsdOption:(NSString*)filePath; +/*! + @function readAFSDParamLineContent + @abstract Try to decode one line of afsd.option or afs.conf + @param paramLine one line of file afsd.option(the only one that is present) os afs.conf + */ +-(void) readAFSDParamLineContent:(NSString*)paramLine; +/*! + @function readNewAfsdOption + @abstract Read the new afs.conf file format + @discussion Scann every line f the afs.conf file ad for each one call the readAFSDParamLineContent with it's content + @param filePath path of the new file with afs.conf file format + */ +-(void) readNewAfsdOption:(NSString*)filePath; +/*! + @function writeAfsdOption + @abstract <#(description)#> + @discussion <#(description)#> + @param <#(name) (description)#> + @result <#(description)#> + */ +-(int) writeAfsdOption:(NSString*)filePath; +/*! + @function writeOldAfsdOption + @abstract Write the cache manager parameter to file + @discussion First chech the version of afs installed then choice to save old o new file version(afsd.option or afs.conf) + @param filePath file path for file to write into + @result <#(description)#> + */ +-(int) writeOldAfsdOption:(NSString*)filePath; +/*! + @function writeNewAfsdOption + @abstract Write the cache parameter to a file with the new format + @param filePath file path where write into + */ +-(int) writeNewAfsdOption:(NSString*)filePath; +/*! + @function getAfsVersion + @abstract Return the string representing the afs version + @result The Enteir string returned from the call of fs -version + */ +-(NSString*) getAfsVersion; +/*! + @function getAfsMajorVersionVersion + @abstract Return the major version of afs Major.x.x + @result + */ +-(int) getAfsMajorVersionVersion; +/*! + @function getAfsMinorVersionVersion + @abstract Return the major version of afs x.Minor.x + @result + */ +-(int) getAfsMinorVersionVersion; + +/*! + @function getAfsPatchVersionVersion + @abstract Return the major version of afs x.x.Patch + @result + */ +-(int) getAfsPatchVersionVersion; + +/*! + @method clearConfiguration + @abstract Clear all structure or array that contain value for afs client setting(cells cache param etch) + @discussion + */ +-(void) clearConfiguration; + +/*! + @function exceptionOnInvalidPath + @abstract Check the validity of afs path + @discussion If the installationPath variable don't point to a valid path, will be fired an NSException + */ +-(void) exceptionOnInvalidPath; + +/*! + @method loadConfiguration + @abstract load the all afs configuration (ThisCell & CellServDB & cache parameter) +*/ +-(void) loadConfiguration; + +/*! + @method readCellInfo + @abstract Read the Main Cell Name +*/ +-(void) readCellInfo:(NSString*) configFile; +/*! + @method readCellDB + @abstract Read the CellServDB File + @discussion Read the file of all cellservbd ad make the NSArray containing a DBCellElement for aech cell found +*/ +-(void) readCellDB:(NSString*) configFile; +/*! + @function readTheseCell + @abstract Read the "These Cell" + @discussion Read the "These Cell" file that contains all the cell from which the user want to get the token + @param configFile TheseCell file path + @result NSAray with the cells name +*/ +-(NSArray*) readTheseCell:(NSString*) configFile; +/*! + @method shutdown + @abstract Stop The AFS +*/ +-(void) shutdown; + +-(void) scanIpForCell:(DBCellElement*) cellElement allIP:(NSString*)allIP; +-(void) backupConfigurationFiles; +-(void) backupFile:(NSString*)localAfsFilePath; +-(void) saveConfigurationFiles:(BOOL) makeBackup; +-(void) saveCacheConfigurationFiles:(BOOL) makeBackup; +-(void) installConfigurationFile:(NSString*)srcConfFile destPath:(NSString*) destPath; +-(NSArray*) getTokenList; +-(BOOL) checkAfsStatus; +-(void) klog:(NSString*)uName uPwd:(NSString*)uPwd cell:(NSString*)theCell; +-(void) aklog:(NSString*)theCell noKerberosCall:(BOOL)krb5CallEnable; +-(void) getTokens:(BOOL)klogAklogFlag usr:(NSString*)usr pwd:(NSString*)pwd; +-(void) unlog:(NSString*)cell; +-(NSString*) makeChaceParamString; +-(BOOL) useAfsdConfConfigFile; +@end diff --git a/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m new file mode 100644 index 000000000..aaefbd517 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m @@ -0,0 +1,1418 @@ +// +// AFSPropertyManager.m +// AFSCommander +// +// Created by Claudio Bisegni on 21/05/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "AFSPropertyManager.h" +#import "TaskUtil.h" + +#define kKerberosAuthError NSLocalizedStringFromTableInBundle(@"KerberosAuthError",nil,[NSBundle bundleForClass:[self class]],@"KerberosAuthError") +#define kPathNotEmpty NSLocalizedStringFromTableInBundle(@"PathNotEmpty",nil,[NSBundle bundleForClass:[self class]],@"PathNotEmpty") +#define kPathDontContainAfsInstallation NSLocalizedStringFromTableInBundle(@"PathDontContainAfsInstallation",nil,[NSBundle bundleForClass:[self class]],@"PathDontContainAfsInstallation") +#define kThisCellFOError NSLocalizedStringFromTableInBundle(@"ThisCellFOError",nil,[NSBundle bundleForClass:[self class]],@"ThisCellFOError") +#define kConfFileNotExits NSLocalizedStringFromTableInBundle(@"ConfFileNotExits",nil,[NSBundle bundleForClass:[self class]],@"ConfFileNotExits") +#define kUserNotAuth NSLocalizedStringFromTableInBundle(@"UserNotAuth",nil,[NSBundle bundleForClass:[self class]],@"UserNotAuth") +#define kBadAfsPath NSLocalizedStringFromTableInBundle(@"BadAfsPath",nil,[NSBundle bundleForClass:[self class]],@"BadAfsPath") + +#define AFS_TOOLS_DIRECTORY /Library/Openafs/ +#define AFS_TOOLS_BIN(x) "/Library/Openafs/bin/"#x +#define AFS_CACHE_PATH "/var/db/openafs/cache" + +#define AFSD_TMP_OLD_PREFERENCE_FILE @"/tmp/afsd.options" +#define AFSD_TMP_NEW_PREFERENCE_FILE @"/tmp/afs.conf" +#define AFSD_OLD_PREFERENCE_FILE @"/etc/config/afsd.options" +#define AFSD_NEW_PREFERENCE_FILE @"/etc/config/afs.conf" + + +//-afsdb -stat 2000 -dcache 800 -daemons 3 -volumes 70 -dynroot -fakestat-all +#define AFSD_OPTION_AFSDB_KEY "-afsdb" +#define AFSD_OPTION_VERBOSE_KEY "-verbose" +#define AFSD_OPTION_STAT_KEY "-stat" +#define AFSD_OPTION_DCACHE_KEY "-dcache" +#define AFSD_OPTION_DAEMONS_KEY "-daemons" +#define AFSD_OPTION_VOLUMES_KEY "-volumes" +#define AFSD_OPTION_DYNROOT_KEY "-dynroot" +#define AFSD_OPTION_FKESTAT_ALL "-fakestat-all" + +#define AFSD_CONF_VERBOSE @"VERBOSE" +#define AFSD_CONF_OPTION @"OPTIONS" +#define AFSD_CONF_SYSNAME @"AFS_SYSNAME" +#define AFSD_CONF_POST_INI @"AFS_POST_INIT" +#define AFSD_CONF_PRE_SHUTDOWN @"AFS_PRE_SHUTDOWN" + +#define AFS_CONF_CHANGE_FROM_Mj_VERSION 1 +#define AFS_CONF_CHANGE_FROM_Mi_VERSION 4 +#define AFS_DEV_CONF_CHANGE_FROM_Mi_VERSION 5 +#define AFS_CONF_CHANGE_FROM_Pa_VERSION 7 +#define AFS_DEV_CONF_CHANGE_FROM_Pa_VERSION 31 + +@implementation AFSPropertyManager + + +// ------------------------------------------------------------------------------- +// init: +// ------------------------------------------------------------------------------- +-(id) init +{ + [super init]; + cellList = [[NSMutableArray alloc] init]; + cellName = nil; + userDefaultCellArray = nil; + useAfsdConfVersion = NO; + dynRoot = NO; + afsDB = NO; + verbose = NO; + futil = [[FileUtil alloc] init]; + return self; +} + +// ------------------------------------------------------------------------------- +// initWithAfsPath: +// ------------------------------------------------------------------------------- +- (id)initWithAfsPath:(NSString*)path +{ + // avvio la creazione standard dell'oggetto + if([self init]){ + // imposto il path + [self setPath:path]; + } + return self; +} + +// ------------------------------------------------------------------------------- +// dealloc: +// ------------------------------------------------------------------------------- +-(void) dealloc +{ + if(installationPath){ [installationPath release]; NSLog(@"Released installationPath"); } + if(cellList) { NSLog(@"Released cellList");[cellList removeAllObjects];[cellList release];} + if(cellName) { NSLog(@"Released cellName");[cellName release];} + if(futil) { + [futil endAutorization]; + [futil release]; + futil = nil; + } + [super dealloc]; +} + +// ------------------------------------------------------------------------------- +// setPath: +// ------------------------------------------------------------------------------- +- (void) setPath:(NSString*)path { + if(installationPath)[installationPath release]; + + if(path) + installationPath = [path retain]; +} + +// ------------------------------------------------------------------------------- +// path: +// ------------------------------------------------------------------------------- +- (NSString*) path{ + return installationPath; +} + +// ------------------------------------------------------------------------------- +// statCacheEntry: +// ------------------------------------------------------------------------------- +-(int) statCacheEntry +{ + return statCacheEntry; +} + +// ------------------------------------------------------------------------------- +// setStatCacheEntry: +// ------------------------------------------------------------------------------- +-(void) setStatCacheEntry:(int)statEntry +{ + statCacheEntry = statEntry; +} + + +// ------------------------------------------------------------------------------- +// dCacheDim: +// ------------------------------------------------------------------------------- +-(int) dCacheDim +{ + return dCacheDim; +} + +// ------------------------------------------------------------------------------- +// setDCacheDim: +// ------------------------------------------------------------------------------- +-(void) setDCacheDim:(int)dcDim +{ + dCacheDim = dcDim; +} + +// ------------------------------------------------------------------------------- +// cacheDimension: +// ------------------------------------------------------------------------------- +-(int) cacheDimension +{ + return cacheDimension; +} + +// ------------------------------------------------------------------------------- +// setCacheDimension: +// ------------------------------------------------------------------------------- +-(void) setCacheDimension:(int)cacheDim +{ + cacheDimension = cacheDim; +} + +// ------------------------------------------------------------------------------- +// daemonNumber: +// ------------------------------------------------------------------------------- +-(int) daemonNumber +{ + return daemonNumber; +} + +// ------------------------------------------------------------------------------- +// setDaemonNumber: +// ------------------------------------------------------------------------------- +-(void) setDaemonNumber:(int)dNumber +{ + daemonNumber = dNumber; +} + +// ------------------------------------------------------------------------------- +// afsRootMountPoint: +// ------------------------------------------------------------------------------- +-(NSString*) afsRootMountPoint +{ + return afsRootMountPoint; +} + +// ------------------------------------------------------------------------------- +// setAfsRootMountPoint: +// ------------------------------------------------------------------------------- +-(void) setAfsRootMountPoint:(NSString*)mountPoint +{ + if(afsRootMountPoint)[afsRootMountPoint release]; + + if(mountPoint) + afsRootMountPoint = [mountPoint retain]; +} + +// ------------------------------------------------------------------------------- +// nVolEntry: +// ------------------------------------------------------------------------------- +-(int) nVolEntry +{ + return nVolEntry; +} + +// ------------------------------------------------------------------------------- +// setNVolEntry: +// ------------------------------------------------------------------------------- +-(void) setNVolEntry:(int)entry +{ + nVolEntry = entry; +} + +// ------------------------------------------------------------------------------- +// dynRoot: +// ------------------------------------------------------------------------------- +-(bool) dynRoot +{ + return dynRoot; +} + +// ------------------------------------------------------------------------------- +// setDynRoot: +// ------------------------------------------------------------------------------- +-(void) setDynRoot:(bool)flag +{ + dynRoot = flag; +} + +// ------------------------------------------------------------------------------- +// dynRoot: +// ------------------------------------------------------------------------------- +-(bool) afsDB +{ + return afsDB; +} + +// ------------------------------------------------------------------------------- +// setDynRoot: +// ------------------------------------------------------------------------------- +-(void) setAfsDB:(bool)flag +{ + afsDB = flag; +} + +// ------------------------------------------------------------------------------- +// setDynRoot: +// ------------------------------------------------------------------------------- +-(bool) verbose +{ + return verbose; +} + +// ------------------------------------------------------------------------------- +// setDynRoot: +// ------------------------------------------------------------------------------- +-(void) setVerbose:(bool)flag +{ + verbose = flag; +} + +// ------------------------------------------------------------------------------- +// useAfsdConfVersion: +// ------------------------------------------------------------------------------- +-(BOOL) useAfsdConfConfigFile +{ + return useAfsdConfVersion; +} + +// ------------------------------------------------------------------------------- +// exceptionOnInvalidPath: +// ------------------------------------------------------------------------------- +- (void) exceptionOnInvalidPath +{ + if(!installationPath || ([installationPath length] == 0)) { + @throw [NSException exceptionWithName:@"AFSPropertyManager:exceptionOnInvalidPath" + reason:kPathNotEmpty + userInfo:nil]; + } + if(![[NSFileManager defaultManager] fileExistsAtPath:installationPath]){ + @throw [NSException exceptionWithName:@"AFSPropertyManager:exceptionOnInvalidPath" + reason:kPathDontContainAfsInstallation + userInfo:nil]; + } + +} + +// ------------------------------------------------------------------------------- +// loadConfiguration: +// ------------------------------------------------------------------------------- +- (void) loadConfiguration { + int mjVersion = [self getAfsMajorVersionVersion]; + int miVersion = [self getAfsMinorVersionVersion]; + int paVersion = [self getAfsPatchVersionVersion]; + + NSMutableString *filePath = [[NSMutableString alloc] initWithCapacity:256]; + @try{ + + [self exceptionOnInvalidPath]; + [self clearConfiguration]; + + //chech the afs version for chioce wich afsd conf file usage + useAfsdConfVersion = mjVersion >= 1 && miVersion>=4 && paVersion>=7; + useAfsdConfVersion = useAfsdConfVersion || (mjVersion >= 1 && miVersion>=6 && paVersion>=31); + + // read thiscell config file + [filePath setString:installationPath]; + [filePath appendString: @"/etc/ThisCell"]; + NSLog(@"Search for cell name."); + [self readCellInfo:filePath]; + if(!cellName){ + @throw [NSException exceptionWithName:@"readCellInfo" + reason:kThisCellFOError + userInfo:nil]; + } + NSLog(@"Cell found: %s", [cellName cString]); + + //read TheseCell file + [filePath setString: installationPath]; + [filePath appendString: @"/etc/TheseCells"]; + userDefaultCellArray = [self readTheseCell:filePath]; + + //read cell serv db + NSLog(@"Scan for cell db"); + [filePath setString: installationPath]; + [filePath appendString: @"/etc/CellServDB"]; + [self readCellDB:filePath]; + NSLog(@"Server found: %d", [cellList count]); + + + + //Read cacheinfo + NSLog(@"Scan cacheinfo file"); + [filePath setString: installationPath]; + [filePath appendString: @"/etc/cacheinfo"]; + [self readCacheInfo:filePath]; + NSLog(@"End scan cacheinfo file"); + + //Read config/afsd.options + [filePath setString: installationPath]; + [filePath appendString: useAfsdConfVersion?AFSD_NEW_PREFERENCE_FILE:AFSD_OLD_PREFERENCE_FILE]; + [self readAfsdOption:filePath]; + + } @catch(NSException * e){ + @throw e; + } @finally { + [filePath release]; + } +} + +// ------------------------------------------------------------------------------- +// readCacheInfo: +// file template "/afs:/var/db/openafs/cache:30000" +// ------------------------------------------------------------------------------- +-(void) readCacheInfo:(NSString*)filePath +{ + int cicle = 0; + NSString *tmpString = nil; + NSCharacterSet *fullStopCS = [NSCharacterSet characterSetWithCharactersInString:@":"]; + NSMutableCharacterSet *chunkStartCS = [[NSMutableCharacterSet alloc] init]; + [chunkStartCS formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]]; + [chunkStartCS formUnionWithCharacterSet:[NSMutableCharacterSet characterSetWithCharactersInString:@"/"]]; + + NSCharacterSet *returnCS = [NSCharacterSet characterSetWithCharactersInString:@"\n"]; + NSFileHandle *fileH = [NSFileHandle fileHandleForReadingAtPath:filePath]; + NSData *fileHData = [fileH readDataToEndOfFile]; + NSString *cacheInfoStrData = [[NSString alloc] initWithData:fileHData + encoding:NSASCIIStringEncoding]; + NSScanner *cacheInfoS = [NSScanner scannerWithString:cacheInfoStrData]; + + @try{ + do { + cicle++; + switch(cicle){ + case 1: + // afs mount path + [cacheInfoS scanUpToCharactersFromSet:fullStopCS intoString:&tmpString]; + [self setAfsRootMountPoint:tmpString]; + [cacheInfoS scanUpToCharactersFromSet:chunkStartCS intoString:&tmpString]; + break; + + case 2: + //cache path default '/var/db/openafs/cache' + [cacheInfoS scanUpToCharactersFromSet:fullStopCS intoString:&tmpString]; + [cacheInfoS scanUpToCharactersFromSet:chunkStartCS intoString:&tmpString]; + break; + + case 3: + // cache dimension + [cacheInfoS scanUpToCharactersFromSet:returnCS intoString:&tmpString]; + [self setCacheDimension:[tmpString intValue]]; + break; + } + }while(cicle < 3 && ![cacheInfoS isAtEnd]); + }@catch(NSException *e){ + @throw e; + }@finally{ + //if(cacheInfoStrData) [cacheInfoStrData release]; + if(chunkStartCS) [chunkStartCS release]; + } + +} + + +// ------------------------------------------------------------------------------- +// writeCacheInfo: +// ------------------------------------------------------------------------------- +-(int) writeCacheInfo:(NSString*)filePath +{ + NSNumber *tmpNum = nil; + NSMutableString *cacheInfoContent = [[NSMutableString alloc] init]; + if(!cacheInfoContent) return -1; + + //Afs root mount point + if([[self afsRootMountPoint] rangeOfString:@"/"].location == NSNotFound || [[self afsRootMountPoint] length] == 0) + @throw [NSException exceptionWithName:@"AFSPropertyManager:writeCacheInfo" + reason:@"Bad afs path" + userInfo:nil]; + [cacheInfoContent appendString:[self afsRootMountPoint]]; + + //standard cache path + + [cacheInfoContent appendString:@":"]; [cacheInfoContent appendString:@AFS_CACHE_PATH]; [cacheInfoContent appendString:@":"]; + + //cache dimension + tmpNum = [NSNumber numberWithInt:[self cacheDimension]]; + if([tmpNum intValue] == 0) + @throw [NSException exceptionWithName:@"AFSPropertyManager:writeCacheInfo" + reason:@"Bad cache dimension" + userInfo:nil]; + [cacheInfoContent appendString:[tmpNum stringValue]]; + + [cacheInfoContent writeToFile: [filePath stringByExpandingTildeInPath] + atomically: YES + encoding: NSASCIIStringEncoding + error: nil]; + + [cacheInfoContent release]; + return noErr; +} + +// ------------------------------------------------------------------------------- +// readCacheInfo: +// file template "/afs:/var/db/openafs/cache:30000" +// ------------------------------------------------------------------------------- +-(void) readAfsdOption:(NSString*)filePath +{ + @try{ + if(useAfsdConfVersion) { + [self readNewAfsdOption:filePath]; + } else { + [self readOldAfsdOption:filePath]; + } + + }@catch(NSException *e){ + @throw e; + }@finally{ + + } + +} + +// ------------------------------------------------------------------------------- +// readOldAfsdOption: +// ------------------------------------------------------------------------------- +-(void) readOldAfsdOption:(NSString*)filePath +{ + + /*NSFileHandle *fileH = [NSFileHandle fileHandleForReadingAtPath:filePath]; + NSData *fileHData = [fileH readDataToEndOfFile]; + NSString *afsdOptionStrData = [[NSString alloc] initWithData:fileHData + encoding:NSASCIIStringEncoding];*/ + if(!filePath) return; + [self readAFSDParamLineContent:[[NSString stringWithContentsOfFile:filePath] stringByStandardizingPath]]; +} + +// ------------------------------------------------------------------------------- +// readAFSDParamLineContent: +// ------------------------------------------------------------------------------- +-(void) readAFSDParamLineContent:(NSString*) paramLine{ + NSString *tmpString = nil; + NSCharacterSet *space = [NSCharacterSet characterSetWithCharactersInString:@" "]; + NSScanner *afsdOptionS = [NSScanner scannerWithString:paramLine]; + + do{ + [afsdOptionS scanUpToCharactersFromSet:space intoString:&tmpString]; + if(!tmpString) continue; + + NSLog(tmpString); + //check parameter type + if([tmpString isEqualToString:@AFSD_OPTION_DAEMONS_KEY]) + { + // get number of daemon + [afsdOptionS scanUpToCharactersFromSet:space intoString:&tmpString]; + [self setDaemonNumber:[tmpString intValue]]; + } else + //check parameter type + if([tmpString isEqualToString:@AFSD_OPTION_DCACHE_KEY]) + { + //get dcache dimension + [afsdOptionS scanUpToCharactersFromSet:space intoString:&tmpString]; + [self setDCacheDim:[tmpString intValue]]; + } else + //check parameter type + if([tmpString isEqualToString:@AFSD_OPTION_DYNROOT_KEY]) + { + [self setDynRoot:true]; + } else + if([tmpString isEqualToString:@AFSD_OPTION_VERBOSE_KEY]) + { + [self setVerbose:true]; + } else if([tmpString isEqualToString:@AFSD_OPTION_AFSDB_KEY]) + { + [self setAfsDB:true]; + } else + //check parameter type + if([tmpString isEqualToString:@AFSD_OPTION_STAT_KEY]) + { + // get fstat entry num + [afsdOptionS scanUpToCharactersFromSet:space intoString:&tmpString]; + [self setStatCacheEntry:[tmpString intValue]]; + } else + + //check parameter type + if([tmpString isEqualToString:@AFSD_OPTION_VOLUMES_KEY]) + { + // get fstat entry num + [afsdOptionS scanUpToCharactersFromSet:space intoString:&tmpString]; + [self setNVolEntry:[tmpString intValue]]; + } + + + + }while(![afsdOptionS isAtEnd]); + +} + +// ------------------------------------------------------------------------------- +// readNewAfsdOption: +// ------------------------------------------------------------------------------- +-(void) readNewAfsdOption:(NSString*)filePath +{ + if(!filePath) return; + NSString *currentLines = nil; + NSString *paramValue = nil; + NSScanner *lineScanner = nil; + + //Get file content + NSString *newAFSDConfContent = [NSString stringWithContentsOfFile:filePath]; + + //get lines in array + NSArray *confLines = [newAFSDConfContent componentsSeparatedByString:@"\n"]; + + //Get the lines enumerator + NSEnumerator *lineEnumerator = [confLines objectEnumerator]; + + //scann all lines + while(currentLines = [lineEnumerator nextObject]) { + if([currentLines rangeOfString:@"#"].location != NSNotFound) continue; + + if([currentLines rangeOfString:AFSD_CONF_OPTION].location != NSNotFound) { + lineScanner = [NSScanner scannerWithString:currentLines]; + if(!lineScanner) continue; + + //scann the line + + [lineScanner scanUpToString:@"\"" intoString:¶mValue]; NSLog(paramValue);[lineScanner scanUpToString:@"-" intoString:¶mValue]; + [lineScanner scanUpToString:@"\"" intoString:¶mValue]; NSLog(paramValue); + + // read the asfd option param line + [self readAFSDParamLineContent:paramValue]; + } else if([currentLines rangeOfString:AFSD_CONF_SYSNAME].location != NSNotFound) { + + } else if([currentLines rangeOfString:AFSD_CONF_POST_INI].location != NSNotFound) { + + } else if([currentLines rangeOfString:AFSD_CONF_PRE_SHUTDOWN].location != NSNotFound) { + + } + } +} + + +// ------------------------------------------------------------------------------- +// writeCacheInfo: +// ------------------------------------------------------------------------------- +-(int) writeAfsdOption:(NSString*)filePath +{ + int result = 0; + @try{ + if(useAfsdConfVersion) { + result = [self writeNewAfsdOption:filePath]; + } else { + result = [self writeOldAfsdOption:filePath]; + } + + }@catch(NSException *e){ + @throw e; + }@finally{ + + } + return result; +} + +// ------------------------------------------------------------------------------- +// writeOldAfsdOption: +// ------------------------------------------------------------------------------- +-(int) writeOldAfsdOption:(NSString*)filePath; +{ + NSMutableString *oldConfFileContent = [[[NSMutableString alloc] init] autorelease]; + //add afsd param + [oldConfFileContent appendString:[self makeChaceParamString]]; + + //add cariage return at end of file + [oldConfFileContent appendString:@"\n"]; + + //write content on file + [oldConfFileContent writeToFile: [filePath stringByExpandingTildeInPath] + atomically: YES + encoding: NSASCIIStringEncoding + error: nil]; + return noErr; + +} + +// ------------------------------------------------------------------------------- +// writeNewAfsdOption: +// OPTIONS= +// AFS_SYSNAME= +// AFS_POST_INIT=afs_server_prefs +// AFS_PRE_SHUTDOWN= +// ------------------------------------------------------------------------------- +-(int) writeNewAfsdOption:(NSString*)filePath +{ + NSMutableString *newConfFileContent = [[[NSMutableString alloc] init] autorelease]; + + //Verbose + [newConfFileContent appendString:AFSD_CONF_VERBOSE]; [newConfFileContent appendString:@"="]; [newConfFileContent appendString:@"\n"]; + + //AFSD Option + [newConfFileContent appendString:AFSD_CONF_OPTION];[newConfFileContent appendString:@"=\""]; [newConfFileContent appendString:[self makeChaceParamString]]; [newConfFileContent appendString:@"\""]; [newConfFileContent appendString:@"\n"]; + + //AFS_SYSNAME + [newConfFileContent appendString:AFSD_CONF_SYSNAME];[newConfFileContent appendString:@"=\""];[newConfFileContent appendString:@"\""]; [newConfFileContent appendString:@"\n"]; + + //AFS_POST_INIT + [newConfFileContent appendString:AFSD_CONF_POST_INI];[newConfFileContent appendString:@"="]; [newConfFileContent appendString:@"\n"]; + + //AFS_PRE_SHUTDOWN + [newConfFileContent appendString:AFSD_CONF_PRE_SHUTDOWN];[newConfFileContent appendString:@"="]; [newConfFileContent appendString:@"\n"]; + + //add content on file + [newConfFileContent appendString:@"\n"]; + + //Write to file + [newConfFileContent writeToFile: [filePath stringByExpandingTildeInPath] + atomically: YES + encoding: NSASCIIStringEncoding + error: nil]; + return noErr; +} + +// ------------------------------------------------------------------------------- +// getAfsVersion: +// ------------------------------------------------------------------------------- +-(NSString*) getAfsVersion +{ + NSString *tmpString = nil; + NSString *result = [TaskUtil executeTaskSearchingPath:@"fs" args:[NSArray arrayWithObjects:@"-version", nil]]; + if(result) NSLog(@"fs -version return: %s", [result cString]); + + + NSCharacterSet *endVersionCS = [NSCharacterSet characterSetWithCharactersInString:@"qwertyuiopasdfghjklzxcvbnmMNBVCXZLKJHGFDSAPOIUYTREWQ"]; + + NSCharacterSet *spaceCS = [NSCharacterSet characterSetWithCharactersInString:@" "]; + NSScanner *versionS = [NSScanner scannerWithString:result]; + //go to start of version + [versionS scanUpToCharactersFromSet:spaceCS intoString:&tmpString]; + + //get the total version string + [versionS scanUpToCharactersFromSet:endVersionCS intoString:&tmpString]; + + return tmpString; +} + +// ------------------------------------------------------------------------------- +// getAfsMajorVersionVersion: +// ------------------------------------------------------------------------------- +-(int) getAfsMajorVersionVersion +{ + NSString *tmpString = nil; + NSString *totalVersion = [self getAfsVersion]; + NSCharacterSet *pointCS = [NSCharacterSet characterSetWithCharactersInString:@"."]; + NSScanner *versionMS = [NSScanner scannerWithString:totalVersion]; + [versionMS scanUpToCharactersFromSet:pointCS intoString:&tmpString]; + return [tmpString intValue]; +} + +// ------------------------------------------------------------------------------- +// getAfsMinorVersionVersion: +// ------------------------------------------------------------------------------- +-(int) getAfsMinorVersionVersion +{ + NSString *tmpString = nil; + NSString *totalVersion = [self getAfsVersion]; + NSCharacterSet *numCS = [NSCharacterSet characterSetWithCharactersInString:@"1234567890"]; + NSCharacterSet *pointCS = [NSCharacterSet characterSetWithCharactersInString:@"."]; + NSScanner *versionMS = [NSScanner scannerWithString:totalVersion]; + [versionMS scanUpToCharactersFromSet:pointCS intoString:&tmpString];[versionMS scanUpToCharactersFromSet:numCS intoString:&tmpString];[versionMS scanUpToCharactersFromSet:pointCS intoString:&tmpString]; + return [tmpString intValue]; +} + +// ------------------------------------------------------------------------------- +// getAfsPatchVersionVersion: +// ------------------------------------------------------------------------------- +-(int) getAfsPatchVersionVersion +{ + NSString *totalVersion = [self getAfsVersion]; + NSCharacterSet *pointCS = [NSCharacterSet characterSetWithCharactersInString:@"."]; + int lastPointIndex = [totalVersion rangeOfCharacterFromSet:pointCS + options:NSBackwardsSearch].location; + int patchVersion = [[totalVersion substringFromIndex:lastPointIndex+1] intValue]; + return patchVersion; +} + + +// ------------------------------------------------------------------------------- +// clearConfiguration: +// ------------------------------------------------------------------------------- +- (void) clearConfiguration{ + + // clear list of cell + [cellList removeAllObjects]; + + userDefaultCellArray= nil; + + // remove the old cell name + if(cellName) { + [cellName release]; + cellName = nil; + } +} + +// ------------------------------------------------------------------------------- +// getCellList: +// ------------------------------------------------------------------------------- +-(NSMutableArray*) getCellList +{ + return cellList; +} + + + +// ------------------------------------------------------------------------------- +// getAllCellName: +// ------------------------------------------------------------------------------- +-(NSArray*) getAllCellsName { + NSMutableArray *allCelListName = [[[NSMutableArray alloc] init] autorelease]; + for(int idx = 0; idx < [cellList count]; idx++){ + DBCellElement *elemnt = [cellList objectAtIndex:idx]; + [allCelListName addObject:[elemnt getCellName]]; + } + return allCelListName; +} + +// ------------------------------------------------------------------------------- +// getCellList: +// ------------------------------------------------------------------------------- +-(NSArray*) getUserDefaultForTokenCells { + return userDefaultCellArray; +} + +// ------------------------------------------------------------------------------- +// getDefaultCellName: +// ------------------------------------------------------------------------------- +-(NSArray*) getDefaultForTokenCellsName { + NSMutableArray *allCelListName = [[[NSMutableArray alloc] init] autorelease]; + for(int idx = 0; idx < [cellList count]; idx++){ + DBCellElement *elemnt = [cellList objectAtIndex:idx]; + if([elemnt userDefaultForToken]) [allCelListName addObject:[[elemnt getCellName] retain]]; + } + return allCelListName; +} + +// ------------------------------------------------------------------------------- +// getCellName: +// ------------------------------------------------------------------------------- +-(NSString*) getDefaultCellName +{ + return cellName; +} + +// ------------------------------------------------------------------------------- +// setDefaultCellByName: +// ------------------------------------------------------------------------------- +-(void) setDefaultCellByName:(NSString*)name +{ + DBCellElement *elementCell = nil; + BOOL cellFound = false; + if(!name) return; + + for(int idx = 0; idx < [cellList count]; idx++) { + // check every cell for delete as old user default cell or selected as neww cell + elementCell = [cellList objectAtIndex:idx]; + cellFound = [name compare:[elementCell getCellName]] == NSOrderedSame; + [elementCell setUserDefaultCell:cellFound]; + if(cellFound) { + [elementCell setUserDefaultForToken:YES]; + if(cellName)[cellName release]; + cellName = [name retain]; + } + } + +} + +// ------------------------------------------------------------------------------- +// setCellName: +// ------------------------------------------------------------------------------- +- (void) setCellName:(NSString*)cell { + [self setDefaultCellByName:cell]; +} + +// ------------------------------------------------------------------------------- +// readCellInfo: +// ------------------------------------------------------------------------------- +-(void) readCellInfo:(NSString*) configFile { + + + NSError *error = nil; + NSString *tmpStr = nil; + NSLog(@"Try to opening file: %s",[configFile cString] ); + NSString * result = [NSString stringWithContentsOfFile:configFile + encoding:NSASCIIStringEncoding + error:&error]; + if(!result && error){ + if([error domain] ) + @throw [NSException exceptionWithName:@"readCellInfo" + reason:kConfFileNotExits + userInfo:nil]; + } + NSScanner *scanner = [NSScanner scannerWithString:result]; + + [scanner scanUpToString:@"\n" + intoString:&tmpStr]; + + // make a copy of self created string + cellName = [tmpStr retain]; +} + +// ------------------------------------------------------------------------------- +// readCellDB: +// ------------------------------------------------------------------------------- +-(void) readCellDB:(NSString*) configFile { + NSString *tmpString = nil; + BOOL isInCellDefaultArray = NO; // the cell belong + BOOL isDefaultCell = NO; + DBCellElement *afsCellDBElement = nil; + NSCharacterSet *returnCS = [NSCharacterSet characterSetWithCharactersInString:@"\n"]; + NSCharacterSet *spaceCS = [NSCharacterSet characterSetWithCharactersInString:@" \t"]; + + NSFileHandle *fileH = [NSFileHandle fileHandleForReadingAtPath:configFile]; + NSData *dbCellData = [fileH readDataToEndOfFile]; + NSString *strData = [[NSString alloc] initWithData:dbCellData + encoding:NSASCIIStringEncoding]; + NSScanner *cellDBScanner = [NSScanner scannerWithString:strData]; + + @try{ + [cellDBScanner scanUpToCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:&tmpString]; + while([cellDBScanner isAtEnd] == NO) { + // make new cell + afsCellDBElement = [[DBCellElement alloc] init]; + + // get the name of cell + [cellDBScanner scanUpToCharactersFromSet:spaceCS intoString:&tmpString]; + [afsCellDBElement setCellName: tmpString]; + + //check if this cells is one of user has selected to get token + isInCellDefaultArray = [userDefaultCellArray containsObject:tmpString]; + //check if this cell is also the default cell + isDefaultCell = [cellName compare:tmpString]==NSOrderedSame; + + [afsCellDBElement setUserDefaultForToken:isInCellDefaultArray||isDefaultCell]; + [afsCellDBElement setUserDefaultCell:isDefaultCell]; + + + + + + // get the cell comment + [cellDBScanner scanUpToCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:nil]; + [cellDBScanner scanUpToCharactersFromSet:returnCS intoString:&tmpString]; + [afsCellDBElement setCellComment: tmpString]; + + // get all ip + [cellDBScanner scanUpToString:@">" intoString:&tmpString]; + // scann all ip in list + [self scanIpForCell:afsCellDBElement allIP:tmpString]; + + // add cell to list + [cellList addObject:afsCellDBElement]; + // release the object becasuse NSMutableArray make a retain on object + [afsCellDBElement release]; + //repeat + [cellDBScanner scanUpToCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:&tmpString]; + } + }@catch(NSException *e){ + @throw e; + }@finally{ + //if(strData) [strData release]; + } +} + +// ------------------------------------------------------------------------------- +// scanIpForCell: +// ------------------------------------------------------------------------------- +-(void) scanIpForCell:(DBCellElement*) cellElement allIP:(NSString*)allIP { + NSScanner *ipScann = [NSScanner scannerWithString:allIP]; + NSCharacterSet *returnCS = [NSCharacterSet characterSetWithCharactersInString:@"\n"]; + NSCharacterSet *spaceCS = [NSCharacterSet characterSetWithCharactersInString:@" \t"]; + NSCharacterSet *startCommentCS = [NSCharacterSet characterSetWithCharactersInString:@"#"]; + NSString *tmpString = nil; + while([ipScann isAtEnd] == NO){ + CellIp *cellIpDesc = [[CellIp alloc] init]; + + //ip string + [ipScann scanUpToCharactersFromSet:spaceCS + intoString:&tmpString]; + + [cellIpDesc setCellIp:tmpString]; + //[tmpString release]; + + // go to comment + [ipScann scanUpToCharactersFromSet:startCommentCS intoString:nil]; + // skip comment symbol + [ipScann scanUpToCharactersFromSet:[NSCharacterSet alphanumericCharacterSet] intoString:nil]; + // get comment + [ipScann scanUpToCharactersFromSet:returnCS intoString:&tmpString]; + [cellIpDesc setCellComment:tmpString]; + //[tmpString release]; + + [cellElement addIpToCell:cellIpDesc]; + // release the object becasuse NSMutableArray make a retain on object + [cellIpDesc release]; + } +} + + +// ------------------------------------------------------------------------------- +// scanIpForCell: +// ------------------------------------------------------------------------------- +-(NSArray*) readTheseCell:(NSString*) configFile { + + NSFileHandle *fileH = [NSFileHandle fileHandleForReadingAtPath:configFile]; + NSData *dbCellData = [fileH readDataToEndOfFile]; + NSString *strData = [[NSString alloc] initWithData:dbCellData + encoding:NSASCIIStringEncoding]; + + return [strData componentsSeparatedByString:@"\n"]; +} + +// ------------------------------------------------------------------------------- +// -(void) getTokenList +// ------------------------------------------------------------------------------- +-(NSArray*) getTokenList +{ + int line = 0; + NSString *tokenLine = nil; + //NSString *tmpValue = nil; + NSMutableArray *tokenList = [[NSMutableArray alloc] init]; + NSString *tokensOutput = [TaskUtil executeTaskSearchingPath:@"tokens" args:[NSArray arrayWithObjects:nil]]; + + // scann the tokens + NSScanner *tokenScan = [NSScanner scannerWithString:tokensOutput]; + NSCharacterSet *returnCS = [NSCharacterSet characterSetWithCharactersInString:@"\n"]; + + while([tokenScan isAtEnd] == NO){ + line++; + // get the next line + [tokenScan scanUpToCharactersFromSet:returnCS + intoString:&tokenLine]; + + // check for tokens end + if([tokenLine rangeOfString:@"--End of list--"].location != NSNotFound) break; + + + if(line >= 2){ + NSLog(@"Token found %s", [tokenLine UTF8String]); + // add enteir row to result + [tokenList addObject:tokenLine]; + // create the line scanner for all the row that contains token info + } + } + // + return tokenList; +} + +// ------------------------------------------------------------------------------- +// +(void) klog:(NSString*)uName uPwd:(NSString*)uPwd +// ------------------------------------------------------------------------------- +-(void) klog:(NSString*)uName uPwd:(NSString*)uPwd cell:(NSString*)theCell +{ + if(uName == @"" || uPwd == @"") return; + + [TaskUtil executeTaskSearchingPath:@"klog" + args:(theCell==nil?[NSArray arrayWithObjects:@"-principal", uName, @"-password", uPwd, nil]:[NSArray arrayWithObjects:@"-principal", uName, @"-password", uPwd, @"-c", theCell, nil])]; + + +} + + +// ------------------------------------------------------------------------------- +// +(void) aklog +// ------------------------------------------------------------------------------- +-(void) aklog:(NSString*)theCell noKerberosCall:(BOOL)krb5CallEnable { + KLPrincipal princ = nil; + KLStatus kstatus = noErr; + char *princName = malloc(255); + @try { + // trying to ket kerberos ticket + if(krb5CallEnable) { + kstatus = KLAcquireInitialTickets (0L, 0L, &princ, &princName); + if(kstatus != noErr && kstatus != klUserCanceledErr) @throw [NSException exceptionWithName:@"aklog" + reason:kPathNotEmpty + userInfo:nil]; + } else kstatus = klNoErr; + + //ok to launch aklog + if(kstatus == klNoErr) [TaskUtil executeTaskSearchingPath:@"aklog" + args:(theCell==nil?[NSArray arrayWithObjects:nil]:[NSArray arrayWithObjects:@"-c", theCell, nil])]; + + } + @catch (NSException * e) { + @throw e; + } + @finally { + // destory the kerberos va + if(princName && princ != nil) + KLDisposeString(princName); + else if(princName) free(princName); + } + +} + + +// ------------------------------------------------------------------------------- +// getTokens: +// ------------------------------------------------------------------------------- +- (void) getTokens:(BOOL)klogAklogFlag usr:(NSString*)usr pwd:(NSString*)pwd { + + NSString *celStrName = nil; + NSArray *tmpDefaultArray = [self getDefaultForTokenCellsName]; + if(tmpDefaultArray && [tmpDefaultArray count] > 1) { + //there are other cell to autenticate + for(int idx=0; idx < [tmpDefaultArray count]; idx++){ + celStrName = [tmpDefaultArray objectAtIndex:idx]; + if(klogAklogFlag) + [self klog:usr + uPwd:pwd + cell:celStrName]; + else + [self aklog:celStrName noKerberosCall:YES]; + } + + } else { + //there is only default cell to autenticate + if(klogAklogFlag) + [self klog:usr + uPwd:pwd + cell:nil]; + else + [self aklog:nil noKerberosCall:YES]; + } + +} + +// ------------------------------------------------------------------------------- +// +(void) unlog +// ------------------------------------------------------------------------------- +-(void) unlog:(NSString*)cell +{ + [TaskUtil executeTaskSearchingPath:@"unlog" + args:(cell?[NSArray arrayWithObjects:@"-c",cell,nil]:[NSArray arrayWithObjects:nil])]; +} + +// ------------------------------------------------------------------------------- +// -(void) shutdown +// ------------------------------------------------------------------------------- +-(void) shutdown +{ + NSMutableString *filePath = [[NSMutableString alloc] initWithCapacity:256]; + @try { + if([[AuthUtil shared] autorize] != noErr) + return; + + /*const char *args0[] = {"stop", 0L}; + [[AuthUtil shared] execUnixCommand:"/Library/StartupItems/OpenAFS/OpenAFS_stop" + args:args0 + output:0L];*/ + + // unmount afs + const char *args1[] = {"-f", "/afs", 0L}; + [[AuthUtil shared] execUnixCommand:"/sbin/umount" + args:args1 + output:0L]; + + const char *args2[] = {"-shutdown", 0L}; + [[AuthUtil shared] execUnixCommand:"/usr/sbin/afsd" + args:args2 + output:0L]; + + const char *args3[] = {[filePath UTF8String], 0L}; + [[AuthUtil shared] execUnixCommand:"/sbin/kextunload" + args:args3 + output:0L]; + + } + @catch (NSException * e) { + @throw e; + } + @finally { + + } + + +} + +// ------------------------------------------------------------------------------- +// -(void) saveConfigurationFiles +// ------------------------------------------------------------------------------- +-(void) saveConfigurationFiles:(BOOL) makeBackup +{ + NSError *err; + NSMutableString *filePath = [[NSMutableString alloc] initWithCapacity:256]; + NSMutableString *cellServDBString = [[NSMutableString alloc] initWithCapacity:256]; + NSMutableString *theseCellString = [[NSMutableString alloc] initWithCapacity:256]; + DBCellElement *cellElement = nil; + + // save the configuration file + @try{ + [self exceptionOnInvalidPath]; + + // ThisCell + [filePath setString: @"/tmp/ThisCell"]; + [cellName writeToFile: [filePath stringByExpandingTildeInPath] + atomically:YES + encoding: NSASCIIStringEncoding + error:nil]; + // CellServDB + + for(int idx = 0; idx < [cellList count]; idx++){ + cellElement = [cellList objectAtIndex:idx]; + [cellServDBString appendString:[cellElement description]]; + if([cellElement userDefaultForToken]) { + [theseCellString appendString:[cellElement getCellName]]; + [theseCellString appendString:@"\n"]; + } + } + + + [filePath setString: @"/tmp/CellServDB"]; + [cellServDBString writeToFile: [filePath stringByExpandingTildeInPath] + atomically:YES + encoding: NSUTF8StringEncoding + error:&err]; + + [filePath setString: @"/tmp/TheseCells"]; + [theseCellString writeToFile: [filePath stringByExpandingTildeInPath] + atomically:YES + encoding: NSUTF8StringEncoding + error:&err]; + + // backup original file + if([futil startAutorization] != noErr){ + @throw [NSException exceptionWithName:@"saveConfigurationFiles:startAutorization" + reason:kUserNotAuth + userInfo:nil]; + } + + if(makeBackup) [self backupConfigurationFiles]; + + // install ThisCell + [filePath setString: installationPath]; + [filePath appendString: @"/etc/ThisCell"]; + [self installConfigurationFile:@"/tmp/ThisCell" + destPath:filePath]; + + // install CellServDB + [filePath setString: installationPath]; + [filePath appendString: @"/etc/CellServDB"]; + [self installConfigurationFile:@"/tmp/CellServDB" + destPath:filePath]; + + // install CellServDB + [filePath setString: installationPath]; + [filePath appendString: @"/etc/TheseCells"]; + [self installConfigurationFile:@"/tmp/TheseCells" + destPath:filePath]; + + } @catch (NSException *e) { + @throw e; + }@finally { + // dispose all variable used + if(filePath) [filePath release]; + if(cellServDBString) [cellServDBString release]; + } + +} + +// ------------------------------------------------------------------------------- +// -(void) saveCacheConfigurationFiles +// ------------------------------------------------------------------------------- +-(void) saveCacheConfigurationFiles:(BOOL)makeBackup +{ + NSMutableString *filePath = [[NSMutableString alloc] initWithCapacity:256]; + // save the configuration file + @try{ + [self exceptionOnInvalidPath]; + + // cacheinfo file creation + [self writeCacheInfo:@"/tmp/cacheinfo"]; + + //afsd.option or afs.conf file creation + [self writeAfsdOption:useAfsdConfVersion?AFSD_TMP_NEW_PREFERENCE_FILE:AFSD_TMP_OLD_PREFERENCE_FILE]; + + // backup original file + if([futil startAutorization] != noErr){ + @throw [NSException exceptionWithName:@"AFSPropertyManager:saveCacheConfigurationFiles:startAutorization" + reason:kUserNotAuth + userInfo:nil]; + } + + if(makeBackup) { + //cacheinfo + [self backupFile:@"/etc/cacheinfo"]; + + //afsd.options + [self backupFile:useAfsdConfVersion?AFSD_NEW_PREFERENCE_FILE:AFSD_OLD_PREFERENCE_FILE]; + } + + // install cacheinfo + [filePath setString:installationPath]; + [filePath appendString: @"/etc/cacheinfo"]; + [self installConfigurationFile:@"/tmp/cacheinfo" + destPath:filePath]; + + // install afsd.conf or afs.conf configuration file + [filePath setString: installationPath]; + [filePath appendString: useAfsdConfVersion?AFSD_NEW_PREFERENCE_FILE:AFSD_OLD_PREFERENCE_FILE]; + [self installConfigurationFile:useAfsdConfVersion?AFSD_TMP_NEW_PREFERENCE_FILE:AFSD_TMP_OLD_PREFERENCE_FILE + destPath:filePath]; + + } @catch (NSException *e) { + @throw e; + }@finally { + if(filePath) [filePath release]; + } + + +} + +// ------------------------------------------------------------------------------- +// -(void) installConfigurationFile +// ------------------------------------------------------------------------------- +-(void) installConfigurationFile:(NSString*)srcConfFile + destPath:(NSString*)destPath +{ + // delete the file original file + + if([futil autorizedDelete:destPath] != noErr){ + @throw [NSException exceptionWithName:@"installConfigurationFile:autorizedDelete" + reason:destPath + userInfo:nil]; + } + + // move the file + if([futil autorizedMoveFile:srcConfFile + toPath:destPath] != noErr) { + @throw [NSException exceptionWithName:@"saveConfigurationFiles:autorizedMoveFile" + reason:srcConfFile + userInfo:nil]; + } + + + if([futil autorizedChown:destPath + owner:@"root" + group:@"wheel"]!= noErr) { + @throw [NSException exceptionWithName:@"saveConfigurationFiles:autorizedChown" + reason:destPath + userInfo:nil]; + } +} + +// ------------------------------------------------------------------------------- +// -(void) backupConfigurationFiles +// ------------------------------------------------------------------------------- +-(void) backupConfigurationFiles +{ + + @try{ + if([futil startAutorization] != noErr){ + @throw [NSException exceptionWithName:@"backupConfigurationFiles:startAutorization" + reason:kUserNotAuth + userInfo:nil]; + } + //This cell + [self backupFile:@"/etc/ThisCell"]; + + //CellServDB + [self backupFile:@"/etc/CellServDB"]; + + //TheseCell + [self backupFile:@"/etc/TheseCells"]; + + //[futil endAutorization]; + } @catch (NSException *e) { + @throw e; + } @finally { + } +} + +// ------------------------------------------------------------------------------- +// -(void) backupFile:(NSString*)localAfsFilePath +// ------------------------------------------------------------------------------- +-(void) backupFile:(NSString*)localAfsFilePath +{ + NSString *srcString = nil; + NSMutableString *filePath = [[NSMutableString alloc] initWithCapacity:256]; + OSStatus err = noErr; + @try{ + [filePath setString: installationPath]; + [filePath appendString: localAfsFilePath]; + + //Check if the file at path exist + NSFileManager *fileManager = [NSFileManager defaultManager]; + + //check if th efile exist + if(![fileManager fileExistsAtPath:[filePath stringByExpandingTildeInPath]]) return; + + // store the source path + srcString = [filePath stringByExpandingTildeInPath]; + [filePath appendString: @".afscommander_bk"]; + + // check for presence of bk file + if(![[NSFileManager defaultManager] fileExistsAtPath:[filePath stringByExpandingTildeInPath]]){ + // backup the file + err = [futil autorizedCopy:srcString + toPath:[filePath stringByExpandingTildeInPath]]; + } + } @catch (NSException *e) { + @throw e; + } @finally { + if(filePath) [filePath release]; + } +} +// ------------------------------------------------------------------------------- +// checkAfsStatus:[NSArray arrayWithObjects:@"checkserver", nil]; +// ------------------------------------------------------------------------------- +-(BOOL) checkAfsStatus +{ + BOOL result = NO; + NSString *fsResult = [TaskUtil executeTaskSearchingPath:@"fs" args:[NSArray arrayWithObjects:@"checkserver", nil]]; + result = (fsResult?([fsResult rangeOfString:@"All servers are running."].location != NSNotFound):NO); + return result; +} + +// ------------------------------------------------------------------------------- +// makeChaceParamString +// ------------------------------------------------------------------------------- +-(NSString*) makeChaceParamString +{ + NSNumber *tmpNum = nil; + NSMutableString *afsdOption = [[NSMutableString alloc] init]; + if(!afsdOption) return @""; + //write the data for afsd config file '-afsdb -stat x -dcache x -daemons x -volumes x -dynroot -fakestat-all' + //afsdb + //dynRoot + if([self afsDB]) { + [afsdOption appendString:@AFSD_OPTION_AFSDB_KEY];[afsdOption appendString:@" "]; + } + + //Verbose + if([self verbose]) { + [afsdOption appendString:@AFSD_OPTION_VERBOSE_KEY];[afsdOption appendString:@" "]; + } + + //stat entry + tmpNum = [NSNumber numberWithInt:[self statCacheEntry]]; + if([tmpNum intValue]) {[afsdOption appendString:@AFSD_OPTION_STAT_KEY];[afsdOption appendString:@" "];[afsdOption appendString:[tmpNum stringValue]];[afsdOption appendString:@" "];} + + //dcace + tmpNum = [NSNumber numberWithInt:[self dCacheDim]]; + if([tmpNum intValue]) {[afsdOption appendString:@AFSD_OPTION_DCACHE_KEY];[afsdOption appendString:@" "];[afsdOption appendString:[tmpNum stringValue]];[afsdOption appendString:@" "];} + + //daemons + tmpNum = [NSNumber numberWithInt:[self daemonNumber]]; + if([tmpNum intValue]) {[afsdOption appendString:@AFSD_OPTION_DAEMONS_KEY];[afsdOption appendString:@" "];[afsdOption appendString:[tmpNum stringValue]];[afsdOption appendString:@" "];} + + //volumes + tmpNum = [NSNumber numberWithInt:[self nVolEntry]]; + if([tmpNum intValue]) {[afsdOption appendString:@AFSD_OPTION_VOLUMES_KEY];[afsdOption appendString:@" "];[afsdOption appendString:[tmpNum stringValue]];[afsdOption appendString:@" "];} + + //dynRoot + if([self dynRoot]) { + [afsdOption appendString:@AFSD_OPTION_DYNROOT_KEY];[afsdOption appendString:@" "]; + } + + //fakestat-all + [afsdOption appendString:@AFSD_OPTION_FKESTAT_ALL];[afsdOption appendString:@" "]; + + return [afsdOption autorelease]; +} + +@end + diff --git a/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/classes.nib b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/classes.nib new file mode 100644 index 000000000..0f736c17a --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/classes.nib @@ -0,0 +1,62 @@ + + + + + IBClasses + + + CLASS + FirstResponder + LANGUAGE + ObjC + SUPERCLASS + NSObject + + + CLASS + AFSMenuCredentialContoller + LANGUAGE + ObjC + OUTLETS + + credWinController + CredentialWindowController + credentialController + id + credentialView + id + + SUPERCLASS + NSObject + + + ACTIONS + + closePanel + id + getToken + id + + CLASS + CredentialWindowController + LANGUAGE + ObjC + OUTLETS + + afsMenuController + id + credentialView + id + textEditPassword + id + textEditUserName + id + + SUPERCLASS + NSObject + + + IBVersion + 1 + + diff --git a/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/info.nib b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/info.nib new file mode 100644 index 000000000..f32b98574 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/info.nib @@ -0,0 +1,20 @@ + + + + + IBFramework Version + 644 + IBLastKnownRelativeProjectPath + ../AFSCommander.xcodeproj + IBOldestOS + 5 + IBOpenObjects + + 248 + + IBSystem Version + 9C31 + targetFramework + IBCocoaFramework + + diff --git a/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/keyedobjects.nib b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/CredentialWindow.nib/keyedobjects.nib new file mode 100644 index 0000000000000000000000000000000000000000..b74c68de7eb0063ab0d1a2029c63df6293820857 GIT binary patch literal 5498 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 YTXvpZvJTM#O@hWp=wp2+{`I>535?EM&;S4c literal 0 HcmV?d00001 diff --git a/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/Info.plist b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/Info.plist new file mode 100644 index 000000000..01c9deabc --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AfsMenuExtraResource/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + AFSMenuExtra + CFBundleIdentifier + it.infn.lnf.network.AFSMenuExtra + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BNDL + CFBundleSignature + INFN + CFBundleVersion + 0.2a + NSPrincipalClass + AFSMenuExtra + + diff --git a/src/platform/DARWIN/AFSPreference/AuthUtil.h b/src/platform/DARWIN/AFSPreference/AuthUtil.h new file mode 100644 index 000000000..f92156a64 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AuthUtil.h @@ -0,0 +1,29 @@ +// +// AuthUtil.h +// AFSCommander +// +// Created by Claudio Bisegni on 21/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#include +#include + +@interface AuthUtil : NSObject { + AuthorizationRef authorizationRef; +} +-(id) init; +-(OSStatus) autorize; +-(BOOL) deautorize; +-(AuthorizationRef) authorization; +-(NSData*) extFormAuth; +-(OSStatus) execUnixCommand:(const char*) commandPath args:(const char*[])args output:(NSMutableString*)output; ++(AuthUtil*) shared; ++ (id)allocWithZone:(NSZone *)zone; +- (id)copyWithZone:(NSZone *)zone; +- (id)retain; +- (unsigned)retainCount; +- (void)release; +- (id)autorelease; +@end diff --git a/src/platform/DARWIN/AFSPreference/AuthUtil.m b/src/platform/DARWIN/AFSPreference/AuthUtil.m new file mode 100644 index 000000000..fa3d16e3f --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/AuthUtil.m @@ -0,0 +1,186 @@ +// +// AuthUtil.m +// AFSCommander +// +// Created by Claudio Bisegni on 21/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "AuthUtil.h" +//#include +#include +#include +#include +static AuthUtil *sharedAuthUtil = nil; + +@implementation AuthUtil + ++(AuthUtil*) shared +{ + @synchronized(self) { + if (sharedAuthUtil == nil) { + [[self alloc] init]; // assignment not done here + } + } + return sharedAuthUtil; +} + ++ (id)allocWithZone:(NSZone *)zone +{ + @synchronized(self) { + if (sharedAuthUtil == nil) { + sharedAuthUtil = [super allocWithZone:zone]; + return sharedAuthUtil; // assignment and return on first allocation + } + } + return nil; //on subsequent allocation attempts return nil +} + +- (id)copyWithZone:(NSZone *)zone +{ + return self; +} + +// ------------------------------------------------------------------------------- +// init: +// ------------------------------------------------------------------------------- +-(id) init { + [super init]; + authorizationRef = nil; + return self; +} + +// ------------------------------------------------------------------------------- +// autorize: +// ------------------------------------------------------------------------------- +-(OSStatus) autorize +{ + OSStatus status = noErr; + AuthorizationFlags flags; + AuthorizationItem myItems = {kAuthorizationRightExecute, 0, NULL, 0}; + AuthorizationRights myRights = {1, &myItems}; + flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; + + /*if(authorizationRef) { + [self deautorize]; + }*/ + + // chek if autorization is valid for and old password request + status = AuthorizationCopyRights (authorizationRef, &myRights, NULL, flags, NULL ); + + if (status != errAuthorizationSuccess) { + // + flags = kAuthorizationFlagDefaults; + if(!authorizationRef){ + status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, flags, &authorizationRef); + if (status != errAuthorizationSuccess) { + return status; + } + } + + flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights; + status = AuthorizationCopyRights (authorizationRef, &myRights, NULL, flags, NULL ); + + if (status != errAuthorizationSuccess) { + AuthorizationFree (authorizationRef, kAuthorizationFlagDefaults); + return status; + } + } + + return status; +} + + +// ------------------------------------------------------------------------------- +// deatorize: +// ------------------------------------------------------------------------------- +-(BOOL) deautorize +{ + OSStatus status = 0L; + if(authorizationRef){ + status = AuthorizationFree (authorizationRef, kAuthorizationFlagDefaults); + authorizationRef = 0L; + } + return status == noErr; +} + + +// ------------------------------------------------------------------------------- +// authorization: +// ------------------------------------------------------------------------------- +-(AuthorizationRef) authorization +{ + return authorizationRef; +} + +// ------------------------------------------------------------------------------- +// authorization: +// ------------------------------------------------------------------------------- +-(NSData*) extFormAuth { + AuthorizationExternalForm extAuth; // external authorization + NSData *authorizationData = nil; + if(AuthorizationMakeExternalForm([self authorization], &extAuth)) + { + NSLog(@"Could not create external authorization form."); + return nil; + } + authorizationData = [NSData dataWithBytes:&extAuth length:sizeof(AuthorizationExternalForm)]; + return authorizationData; +} + +// ------------------------------------------------------------------------------- +// execUnixCommand: +// ------------------------------------------------------------------------------- +-(OSStatus) execUnixCommand:(const char*) commandPath args:(const char*[])args output:(NSMutableString*)output +{ + OSStatus status = noErr; + FILE *commandOutIn = NULL; + char buff[1024]; + int pid, pidStatus; + + status = AuthorizationExecuteWithPrivileges (authorizationRef, commandPath, kAuthorizationFlagDefaults , (char *const *)args, &commandOutIn); + if (status == errAuthorizationSuccess && commandOutIn){ + for(;;) + { + int bytesRead = read(fileno (commandOutIn), buff, sizeof (buff)); + if (bytesRead < 1) break; + //write (fileno (stdout), buff, bytesRead); + if(output) { + [output appendString:[NSString stringWithCString:buff length:bytesRead]]; + } + } + } + if(commandOutIn){ + fflush(commandOutIn); + fclose(commandOutIn); + } + // whait for comand finish + pid = wait( &pidStatus ); + if (pid == -1 || !WIFEXITED( pidStatus )) + { + NSLog( @"Error: problem with wait pid status: %d", pidStatus ); + return 1; + } + return status; +} + +- (id)retain +{ + return self; +} + +- (unsigned)retainCount +{ + return UINT_MAX; //denotes an object that cannot be released +} + +- (void)release +{ + //do nothing +} + +- (id)autorelease +{ + return self; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/CellIp.h b/src/platform/DARWIN/AFSPreference/CellIp.h new file mode 100644 index 000000000..dbd48124b --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/CellIp.h @@ -0,0 +1,23 @@ +// +// CellIp.h +// AFSCommander +// +// Created by Claudio Bisegni on 14/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import + + +@interface CellIp : NSObject { + NSString *ip; + NSString *ipComment; +} +-(id)init; +-(void)dealloc; +-(void)setCellIp:(NSString*)newip; +-(NSString*) getCellIp; +-(void)setCellComment:(NSString*)newcomment; +-(NSString*) getCellComment; +-(NSString*) description; +@end diff --git a/src/platform/DARWIN/AFSPreference/CellIp.m b/src/platform/DARWIN/AFSPreference/CellIp.m new file mode 100644 index 000000000..6fe80bc15 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/CellIp.m @@ -0,0 +1,76 @@ +// +// CellIp.m +// AFSCommander +// +// Created by Claudio Bisegni on 14/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "CellIp.h" + + +@implementation CellIp +// ------------------------------------------------------------------------------- +// init: +// ------------------------------------------------------------------------------- +-(id)init { + [super init]; + ip = @"0.0.0.0"; + ipComment = @"-----"; + return self; +} + +// ------------------------------------------------------------------------------- +// dealloc: +// ------------------------------------------------------------------------------- +-(void)dealloc{ + if(ip) [ip release]; + if(ipComment) [ipComment release]; + [super dealloc]; +} + +// ------------------------------------------------------------------------------- +// setCellIp: +// ------------------------------------------------------------------------------- +-(void)setCellIp:(NSString*)newip{ + if(ip){ + [ip release]; + } + ip = [newip retain]; +} + +// ------------------------------------------------------------------------------- +// getCellIp: +// ------------------------------------------------------------------------------- +-(NSString*) getCellIp{ + return ip; +} + +// ------------------------------------------------------------------------------- +// setCellComment:(NSString*)newcomment +// ------------------------------------------------------------------------------- +-(void)setCellComment:(NSString*)newcomment{ + if(ipComment){ + [ipComment release]; + } + ipComment = [newcomment retain]; +} + +// ------------------------------------------------------------------------------- +// getCellComment: +// ------------------------------------------------------------------------------- +-(NSString*) getCellComment{ + return ipComment; +} + +// ------------------------------------------------------------------------------- +// description: +// ------------------------------------------------------------------------------- +-(NSString*) description{ + NSMutableString *desc = [[NSMutableString alloc] init]; + [desc autorelease]; + [desc appendString:ip];[desc appendString:@" "];[desc appendString:@"#"];[desc appendString:ipComment];[desc appendString:@"\n"]; + return desc; +} + +@end diff --git a/src/platform/DARWIN/AFSPreference/CredentialWindowController.h b/src/platform/DARWIN/AFSPreference/CredentialWindowController.h new file mode 100644 index 000000000..5a67d07e6 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/CredentialWindowController.h @@ -0,0 +1,30 @@ +// +// CredentialWindowController.h +// AFSCommander +// +// Created by Claudio on 14/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "AFSMenuCredentialContoller.h" +#import "global.h" + +@interface CredentialWindowController : NSObject { + id credentialView; + id afsMenuController; + id textEditUserName; + id textEditPassword; + + BOOL taken; + NSString *uName; + NSString *uPwd; + +} + +- (IBAction) getToken:(id) sender; +- (IBAction) closePanel:(id) sender; +- (BOOL) takenToken; +- (NSString*) uName; +- (NSString*) uPwd; +@end diff --git a/src/platform/DARWIN/AFSPreference/CredentialWindowController.m b/src/platform/DARWIN/AFSPreference/CredentialWindowController.m new file mode 100644 index 000000000..131bcb744 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/CredentialWindowController.m @@ -0,0 +1,71 @@ +// +// CredentialWindowController.m +// AFSCommander +// +// Created by Claudio on 14/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "CredentialWindowController.h" +#import "AFSPropertyManager.h" + +@implementation CredentialWindowController +// ------------------------------------------------------------------------------- +// awakeFromNib: +// ------------------------------------------------------------------------------- +- (void)awakeFromNib +{ + NSLog(@"awakeFromNib"); +} + +// ------------------------------------------------------------------------------- +// getToken: +// ------------------------------------------------------------------------------- +- (IBAction) getToken:(id) sender +{ + uName = [((NSTextField*) textEditUserName) stringValue]; + uPwd = [((NSTextField*) textEditPassword) stringValue]; + if(uName == @"" || uPwd == @"") return; + taken = YES; + + + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kLogWindowClosed]; +} + + +// ------------------------------------------------------------------------------- +// closePanel: +// ------------------------------------------------------------------------------- +- (IBAction) closePanel:(id) sender +{ + taken = NO; + NSLog(@"closePanel"); + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kLogWindowClosed]; +} + + +// ------------------------------------------------------------------------------- +// takenToken: +// ------------------------------------------------------------------------------- +- (BOOL) takenToken +{ + return taken; +} + +// ------------------------------------------------------------------------------- +// takenToken: +// ------------------------------------------------------------------------------- +- (NSString*) uName +{ + return uName; +} + +// ------------------------------------------------------------------------------- +// takenToken: +// ------------------------------------------------------------------------------- +- (NSString*) uPwd +{ + return uPwd; +} + +@end diff --git a/src/platform/DARWIN/AFSPreference/DBCellElement.h b/src/platform/DARWIN/AFSPreference/DBCellElement.h new file mode 100644 index 000000000..8ebc2aba2 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/DBCellElement.h @@ -0,0 +1,134 @@ +// +// DBCellElement.h +// AFSCommander +// +// Created by Claudio Bisegni on 14/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// +// Is the identification of a cell in he afs cell database + +#import +#import "CellIp.h" + +@interface DBCellElement : NSObject { + BOOL userDefaultForToken; + BOOL userDefaultCell; + NSString *cellName; + NSString *cellComment; + NSMutableArray *ipCellList; +} + +/*! + @method init + @abstract + @discussion + */ +-(id) init; + +/*! + @method dealloc + @abstract + @discussion + */ +-(void) dealloc; + +/*! + @method setCellName + @abstract Set the cel name + @discussion Release the old cell name andretain the new one + @param name - Name of the cell + */ +-(void) setCellName:(NSString *)name; + +/*! + @method getCellName + @abstract Return the cell name + @discussion Return the cell name + @result Name of the cell + */ +-(NSString*) getCellName; + +/*! + @method setCellComment + @abstract Set the comment of the cell + @discussion Release the old cell comment and retain the new one + @param comment - Comment of the cell + */ +-(void) setCellComment:(NSString *)comment; + +/*! + @method getCellComment + @abstract Get the comment of the cell + @discussion Get the comment of the cell + @result comment of the cell + + */ +-(NSString*) getCellComment; + +/*! + @method setUserDefaultForToken + @abstract Set the userde fault for tokens for the cell + @discussion If this cell is a cell used by user this flag will be true, + for multi cell authentication will be more cell with this flag on true. + @param isDefault - true if the this cell is default which the user want to ge token for + + */ +-(void) setUserDefaultForToken:(BOOL)isDefault; + +/*! + @method userDefault + @abstract Return the user request for token flag + @discussion + @result if true this cell is used to get the tokens + */ +-(BOOL) userDefaultForToken; +/*! + @method setUserDefaultCell + @abstract set the user default cell state + @discussion + @result set this cell as default user cell + */ +-(void) setUserDefaultCell:(BOOL)isDefault; +/*! + @method userDefaultForCell + @abstract Return the user default cell state + @discussion + @result is true if this cell is the default cell + */ +-(BOOL) userDefaultForCell; +/*! + @method addIpToCell + @abstract Add an ipcell description to this cell + @discussion Add a new IpCell class to this cell to specify the server ip + @param ip - CellIP class representing the ip of one server of the cell + */ +-(void) addIpToCell:(CellIp*)ip; + +/*! + @method getIp + @abstract Return the array containing all ip for thi cell + @discussion + @result The array containing all the cell ip decription class + */ +-(NSMutableArray*) getIp; + +/*! + @method description + @abstract Return the description of this cell + @discussion The description is the same stile used in CellServDB file(for a single cell) + so calling thi method for all cell will be reconstructed the entire afs configuration file for CellSerDB + @result The string description of the cell with all the ip + */ +-(NSString*) description; + +/*! + @method isEqual + @abstract Compare this object with anoter of the same type + @discussion Compare this object with the ine passed to the function + @param anObject - An object to compare with this. + @result true if the two object are the same. + */ +- (BOOL)isEqual:(id)anObject; + +- (BOOL)isEqualToString:(NSString *)aString; +@end diff --git a/src/platform/DARWIN/AFSPreference/DBCellElement.m b/src/platform/DARWIN/AFSPreference/DBCellElement.m new file mode 100644 index 000000000..ac43f0057 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/DBCellElement.m @@ -0,0 +1,143 @@ +// +// DBCellElement.m +// AFSCommander +// +// Created by Claudio Bisegni on 14/06/07. +// Copyright 2007 INFN. All rights reserved. +// + +#import "DBCellElement.h" + + +@implementation DBCellElement + +// ------------------------------------------------------------------------------- +// init: +// ------------------------------------------------------------------------------- +-(id) init{ + [super init]; + userDefaultForToken = false; + userDefaultCell = false; + ipCellList = [[NSMutableArray alloc] init]; + return self; +} + +// ------------------------------------------------------------------------------- +// dealloc: +// ------------------------------------------------------------------------------- +-(void) dealloc{ + if(ipCellList) [ipCellList release]; + if(cellName) [cellName release]; + if(cellComment) [cellComment release]; + [super dealloc]; +} + +// ------------------------------------------------------------------------------- +// setCellName: +// ------------------------------------------------------------------------------- +-(void) setCellName:(NSString *)name +{ + if(cellName){ + [cellName release]; + } + cellName = [name retain]; +} + +// ------------------------------------------------------------------------------- +// getCellName: +// ------------------------------------------------------------------------------- +-(NSString*) getCellName{ + return cellName; +} + +// ------------------------------------------------------------------------------- +// setCellComment: +// ------------------------------------------------------------------------------- +-(void) setCellComment:(NSString *)comment{ + if(cellComment){ + [cellComment release]; + } + cellComment = [comment retain]; +} + +// ------------------------------------------------------------------------------- +// getCellComment: +// ------------------------------------------------------------------------------- +-(NSString*) getCellComment{ + return cellComment; +} + +// ------------------------------------------------------------------------------- +// setCellComment: +// ------------------------------------------------------------------------------- +-(void) setUserDefaultForToken:(BOOL)isDefault { + userDefaultForToken = isDefault; +} + +// ------------------------------------------------------------------------------- +// getCellComment: +// ------------------------------------------------------------------------------- +-(BOOL) userDefaultForToken { + return userDefaultForToken; +} + +// ------------------------------------------------------------------------------- +// setCellComment: +// ------------------------------------------------------------------------------- +-(void) setUserDefaultCell:(BOOL)isDefault { + userDefaultCell = isDefault; +} + +// ------------------------------------------------------------------------------- +// getCellComment: +// ------------------------------------------------------------------------------- +-(BOOL) userDefaultForCell { + return userDefaultCell; +} + +// ------------------------------------------------------------------------------- +// addIpToCell: +// ------------------------------------------------------------------------------- +-(void) addIpToCell:(CellIp*)ip{ + [ipCellList addObject:ip]; +} + +// ------------------------------------------------------------------------------- +// getIp: +// ------------------------------------------------------------------------------- +-(NSMutableArray*) getIp{ + return ipCellList; +} + +// ------------------------------------------------------------------------------- +// description: +// ------------------------------------------------------------------------------- +-(NSString*) description{ + NSMutableString *desc = [[NSMutableString alloc] init]; + // write the description according to CellServDB semantic + // write cell name + [desc appendString:@">"];[desc appendString:cellName];[desc appendString:@" "];[desc appendString:@"#"];[desc appendString:cellComment];[desc appendString:@"\n"]; + + // write all ip + for(int idx = 0, count = [ipCellList count]; idx < count; idx++){ + CellIp *cellIP = (CellIp*)[ipCellList objectAtIndex:idx]; + [desc appendString:[cellIP description]]; + } + + return desc; +} + +// ------------------------------------------------------------------------------- +// description: +// ------------------------------------------------------------------------------- +- (BOOL)isEqual:(id)anObject +{ + if(!anObject) return NO; + else return [cellName isEqual:[anObject getCellName]] && [cellComment isEqual:[anObject getCellComment]]; +} + +- (BOOL)isEqualToString:(NSString *)aString { + if(!aString) return NO; + else return [aString isEqualToString:[self getCellName]]; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/DialogUtility.h b/src/platform/DARWIN/AFSPreference/DialogUtility.h new file mode 100644 index 000000000..992ab3736 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/DialogUtility.h @@ -0,0 +1,16 @@ +// +// DialogUtility.h +// OpenAFS +// +// Created by Claudio Bisegni on 01/05/08. +// Copyright 2008 Infn. All rights reserved. +// + +#import + + +@interface DialogUtility : NSObject { + +} ++ (BOOL) showMessageYesNo:(NSString*) message delegator:(id)delegator functionSelecter:(SEL)fSelector window:(NSWindow*)window; +@end diff --git a/src/platform/DARWIN/AFSPreference/DialogUtility.m b/src/platform/DARWIN/AFSPreference/DialogUtility.m new file mode 100644 index 000000000..77feb2c79 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/DialogUtility.m @@ -0,0 +1,26 @@ +// +// DialogUtility.m +// OpenAFS +// +// Created by Claudio Bisegni on 01/05/08. +// Copyright 2008 Infn. All rights reserved. +// + +#import "DialogUtility.h" + + +@implementation DialogUtility +// ------------------------------------------------------------------------------- +// showMessage: +// ------------------------------------------------------------------------------- ++ (BOOL) showMessageYesNo:(NSString*) message delegator:(id)delegator functionSelecter:(SEL)fSelector window:(NSWindow*)window { + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + [alert setMessageText:message]; + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + [alert beginSheetModalForWindow:window + modalDelegate:delegator + didEndSelector:fSelector + contextInfo:nil]; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/English.lproj/CredentialPanel.xib b/src/platform/DARWIN/AFSPreference/English.lproj/CredentialPanel.xib new file mode 100644 index 000000000..c3f419eef --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/English.lproj/CredentialPanel.xib @@ -0,0 +1,710 @@ + + + + 1050 + 9C31 + 648 + 949.26 + 352.00 + + YES + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + AFSCommanderPref + + + FirstResponder + + + NSApplication + + + 3 + 2 + {{594, 606}, {360, 116}} + 1886912512 + Panel + + NSPanel + + + View + + {213, 107} + + + 256 + + YES + + + 256 + {{19, 75}, {63, 14}} + + YES + + 67239424 + 272629760 + Username: + + LucidaGrande + 1.100000e+01 + 3100 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 256 + {{21, 47}, {61, 14}} + + YES + + 67239424 + 272629760 + Password: + + + + + + + + + 256 + {{87, 73}, {253, 19}} + + YES + + -1804468671 + 272761856 + + + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + + + + + + 256 + {{87, 45}, {253, 19}} + + YES + + -1804468671 + 272761856 + + + + YES + + + + + + + 256 + {{242, 13}, {103, 28}} + + YES + + 67239424 + 134348800 + Get Token + + + -2038284033 + 1 + + LucidaGrande + 1.100000e+01 + 16 + + + DQ + 200 + 25 + + + + + 256 + {{160, 13}, {80, 28}} + + YES + + 67239424 + 134348800 + Cancel + + + -2038284033 + 1 + + + Gw + 200 + 25 + + + + {{1, 1}, {360, 116}} + + {{0, 0}, {1920, 1178}} + {213, 129} + {3.40282e+38, 3.40282e+38} + + + TokenCredentialController + + + + + YES + + + afsCommanderPref + + + + 8 + + + + credentialCommander + + + + 9 + + + + credentialSheet + + + + 10 + + + + credentialPanel + + + + 11 + + + + textEditUserName + + + + 18 + + + + textEditPassword + + + + 19 + + + + getToken: + + + + 20 + + + + closePanel: + + + + 21 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + 5 + + + YES + + + + Panel + + + 6 + + + YES + + + + + + + + + + + 12 + + + YES + + + + + + 13 + + + YES + + + + + + 14 + + + YES + + + + + + 15 + + + YES + + + + + + 16 + + + YES + + + + + + 17 + + + YES + + + + + + 7 + + + TokenCredentialController + + + 23 + + + + + 24 + + + + + 25 + + + + + 26 + + + + + 27 + + + + + 28 + + + + + -3 + + + Application + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + 12.IBPluginDependency + 12.ImportedFromIB2 + 13.IBPluginDependency + 13.ImportedFromIB2 + 14.IBPluginDependency + 14.ImportedFromIB2 + 15.CustomClassName + 15.IBPluginDependency + 15.ImportedFromIB2 + 16.IBPluginDependency + 16.ImportedFromIB2 + 17.IBPluginDependency + 17.ImportedFromIB2 + 5.IBPluginDependency + 5.ImportedFromIB2 + 5.windowTemplate.hasMinSize + 5.windowTemplate.minSize + 6.IBPluginDependency + 6.ImportedFromIB2 + 7.IBPluginDependency + 7.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + NSSecureTextField + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + {213, 107} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 28 + + + + YES + + AFSCommanderPref + NSPreferencePane + + YES + + YES + addRemoveCell: + afsMenuActivationEvent: + aklogSwitchEvent: + getNewToken: + info: + refreshConfiguration: + saveCacheManagerParam: + saveConfiguration: + searchCellTextEvent: + showCellIP: + startStopAfs: + tableDoubleAction: + unlog: + + + YES + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + YES + + YES + addCellButton + afsCommanderView + afsDB + afsDefaultCellLabel + afsMenucheckBox + afsRootMountPoint + afsVersionLabel + cacheDimension + cellIpButton + cellList + credentialCommander + credentialSheet + dCacheDim + daemonNumber + dynRoot + groupsBox + infoController + infoSheet + installationPathTextField + ipConfControllerCommander + ipConfigurationSheet + labelSaveResult + nVolEntry + refreshConfigurationButton + removeCellButton + saveConfigurationButton + startStopButton + statCacheEntry + textSearchField + tokensButton + tokensTable + unlogButton + useAklogCheck + verbose + + + YES + id + NSView + NSButton + NSTextField + id + NSTextField + NSTextField + NSTextField + id + id + id + id + NSTextField + NSTextField + NSButton + NSBox + id + id + id + id + id + id + NSTextField + id + id + id + id + NSTextField + NSSearchField + NSButton + id + NSButton + NSButton + NSButton + + + + IBProjectSource + AFSCommanderPref.h + + + + AFSCommanderPref + NSPreferencePane + + cellNameTextEdit + id + + + IBUserSource + + + + + FirstResponder + + IBUserSource + + + + + NSPreferencePane + NSObject + + YES + + YES + _firstKeyView + _initialKeyView + _lastKeyView + _window + + + YES + NSView + NSView + NSView + NSWindow + + + + IBUserSource + + + + + TokenCredentialController + NSObject + + YES + + YES + closePanel: + getToken: + + + YES + id + id + + + + YES + + YES + afsCommanderPref + credentialPanel + textEditPassword + textEditUserName + + + YES + id + id + id + id + + + + IBProjectSource + TokenCredentialController.h + + + + TokenCredentialController + NSObject + + IBUserSource + + + + + + 0 + + 3 + + diff --git a/src/platform/DARWIN/AFSPreference/English.lproj/InfoPlist.strings b/src/platform/DARWIN/AFSPreference/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..1352c22e51c462c9b49a9dce6b7fb7339a2d12e4 GIT binary patch literal 204 zcmZvW!4APd6h+UvU(r}0Qeq_$D~XUu7koj{B50cy2_KJ>S<6f2&AfZ>nfLiJq)*J6 ziai-u&b-MvID6U~S|=5yJ+>E~D_@28ggW?J?oKbdU%}Ov8CfY?mOQx0E!n7Nax-?O la^@0h6OH^Mr@)xW>HJl?Zr4*CGqNTO!X7CLe@V + + + 1050 + 9C31 + 648 + 949.26 + 352.00 + + YES + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + AFSCommanderPref + + + FirstResponder + + + NSApplication + + + 11 + 2 + {{622, 526}, {525, 370}} + 813170688 + Panel + + NSPanel + + + View + + {525, 345} + + + 256 + + YES + + + 289 + {{430, 13}, {80, 28}} + + YES + + 67239424 + 134348800 + Ok + + LucidaGrande + 1.100000e+01 + 3100 + + + -2038284033 + 1 + + LucidaGrande + 1.100000e+01 + 16 + + + + + + 200 + 25 + + + + + 289 + {{348, 13}, {80, 28}} + + YES + + 67239424 + 134348800 + Cancel + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 268 + {{51, 344}, {54, 16}} + + YES + + 67239424 + 272760832 + QWZzIENlbGw6Cg + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 274 + + YES + + + 256 + + YES + + + 274 + + YES + + + 2304 + + YES + + + 256 + {453, 190} + + YES + + + 256 + {453, 17} + + + + + + -2147483392 + {{-22, 0}, {12, 17}} + + + + YES + + 1 + 2.080000e+02 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + IP + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + + + + 337772096 + 133120 + Text Cell + + + + 6 + System + controlBackgroundColor + + + + + 3 + YES + YES + + + + 2 + 2.389761e+02 + 5.997607e+01 + 1.000000e+03 + + 75628032 + 0 + Comment + + + + + + 337772096 + 133120 + Text Cell + + + + + + 3 + YES + YES + + + + 3.000000e+00 + 2.000000e+00 + + 3 + MQA + + + 6 + System + gridColor + + 3 + MC41AA + + + 1.700000e+01 + -692060160 + 4 + 15 + 0 + YES + + + {{1, 17}, {453, 190}} + + + + + 4 + + + + -2147483392 + {{-22, 17}, {11, 189}} + + 256 + + _doScroller: + 9.947369e-01 + + + + -2147483392 + {{1, -22}, {442, 11}} + + 257 + + _doScroller: + 9.757174e-01 + + + + 2304 + + YES + + + {{1, 0}, {453, 17}} + + + + + 4 + + + + {{16, 30}, {455, 208}} + + + 562 + + + + + QSAAAEEgAABBmAAAQZgAAA + + + {{2, 2}, {487, 249}} + + + + {{17, 41}, {491, 266}} + + {0, 0} + + 67239424 + 0 + Authentication server ip + + + 6 + System + textBackgroundColor + + + + 3 + MCAwLjgwMDAwMDAxAA + + + + 3 + 0 + 2 + NO + + + + 289 + {{331, 52}, {75, 16}} + + YES + + 604110336 + 134479872 + Delete + + LucidaGrande + 9.000000e+00 + 3614 + + + -2038284033 + 1 + + LucidaGrande + 9.000000e+00 + 16 + + + + + + 200 + 25 + + + + + 289 + {{412, 52}, {75, 16}} + + YES + + 67239424 + 134479872 + Add + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 268 + {{44, 314}, {61, 16}} + + YES + + 67239424 + 272760832 + Q29tbWVudDoKA + + + + + + + + + 266 + {{110, 344}, {389, 19}} + + YES + + -1804468671 + 272761856 + + + cell name + + YES + + + 6 + System + textColor + + + + + + + 266 + {{110, 315}, {389, 19}} + + YES + + -1804468671 + 272761856 + + + Comment + + YES + + + + + + {525, 370} + + {{0, 0}, {1920, 1178}} + {525, 367} + {3.40282e+38, 3.40282e+38} + + + IpConfiguratorCommander + + + AFSCommanderPref + + + + + YES + + + ipConfigurationSheet + + + + 15 + + + + cancel: + + + + 17 + + + + save: + + + + 18 + + + + confPanel + + + + 19 + + + + afsCommanderPref + + + + 20 + + + + ipConfControllerCommander + + + + 22 + + + + tableViewCellIP + + + + 40 + + + + deleteButton + + + + 41 + + + + createButton + + + + 43 + + + + cancelIP: + + + + 48 + + + + createNewIP: + + + + 50 + + + + delegate + + + + 52 + + + + textFieldCellName + + + + 57 + + + + textFieldComment + + + + 58 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 5 + + + YES + + + + IpConfigurator + + + 6 + + + YES + + + + + + + + + + + + + + 7 + + + YES + + + + + + 8 + + + YES + + + + + + 14 + + + YES + + + + + + 25 + + + YES + + + + + + 38 + + + YES + + + + + + 39 + + + YES + + + + + + 53 + + + YES + + + + + + 55 + + + YES + + + + + + 56 + + + YES + + + + + + 16 + + + IpConfiguratorCommander1 + + + 21 + + + AFSCommanderPref + + + 62 + + + + + 63 + + + + + 64 + + + + + 65 + + + + + 66 + + + + + 67 + + + + + 68 + + + + + 69 + + + + + 27 + + + YES + + + + + + + + + 74 + + + + + 73 + + + + + 72 + + + + + 28 + + + YES + + + + + + + 30 + + + YES + + + + + + 29 + + + YES + + + + + + 70 + + + + + 71 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + -3.ImportedFromIB2 + 14.IBPluginDependency + 14.ImportedFromIB2 + 16.IBPluginDependency + 16.ImportedFromIB2 + 21.IBPluginDependency + 21.ImportedFromIB2 + 25.IBPluginDependency + 25.ImportedFromIB2 + 27.IBPluginDependency + 27.ImportedFromIB2 + 28.IBPluginDependency + 28.ImportedFromIB2 + 29.IBPluginDependency + 29.ImportedFromIB2 + 30.IBPluginDependency + 30.ImportedFromIB2 + 38.IBPluginDependency + 38.ImportedFromIB2 + 39.IBPluginDependency + 39.ImportedFromIB2 + 5.IBPluginDependency + 5.ImportedFromIB2 + 5.windowTemplate.hasMinSize + 5.windowTemplate.minSize + 53.IBPluginDependency + 53.ImportedFromIB2 + 55.IBPluginDependency + 55.ImportedFromIB2 + 56.IBPluginDependency + 56.ImportedFromIB2 + 6.IBPluginDependency + 6.ImportedFromIB2 + 7.IBPluginDependency + 7.ImportedFromIB2 + 70.IBShouldRemoveOnLegacySave + 71.IBShouldRemoveOnLegacySave + 72.IBShouldRemoveOnLegacySave + 73.IBShouldRemoveOnLegacySave + 74.IBShouldRemoveOnLegacySave + 8.IBPluginDependency + 8.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + {525, 345} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 74 + + + + YES + + AFSCommanderPref + NSPreferencePane + + YES + + YES + addRemoveCell: + afsMenuActivationEvent: + aklogSwitchEvent: + getNewToken: + info: + refreshConfiguration: + saveCacheManagerParam: + saveConfiguration: + searchCellTextEvent: + showCellIP: + startStopAfs: + tableDoubleAction: + unlog: + + + YES + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + YES + + YES + addCellButton + afsCommanderView + afsDB + afsDefaultCellLabel + afsMenucheckBox + afsRootMountPoint + afsVersionLabel + cacheDimension + cellIpButton + cellList + credentialCommander + credentialSheet + dCacheDim + daemonNumber + dynRoot + groupsBox + infoController + infoSheet + installationPathTextField + ipConfControllerCommander + ipConfigurationSheet + labelSaveResult + nVolEntry + refreshConfigurationButton + removeCellButton + saveConfigurationButton + startStopButton + statCacheEntry + textSearchField + tokensButton + tokensTable + unlogButton + useAklogCheck + verbose + + + YES + id + NSView + NSButton + NSTextField + id + NSTextField + NSTextField + NSTextField + id + id + id + id + NSTextField + NSTextField + NSButton + NSBox + id + id + id + id + id + id + NSTextField + id + id + id + id + NSTextField + NSSearchField + NSButton + id + NSButton + NSButton + NSButton + + + + IBProjectSource + AFSCommanderPref.h + + + + AFSCommanderPref + NSPreferencePane + + addMoifyCell: + id + + + cellNameTextEdit + id + + + IBUserSource + + + + + FirstResponder + + IBUserSource + + + + + IpConfiguratorCommander + NSObject + + YES + + YES + cancel: + cancelIP: + createNewIP: + save: + + + YES + id + id + id + id + + + + YES + + YES + afsCommanderPref + confPanel + createButton + deleteButton + modifyButton + tableViewCellIP + textFieldCellName + textFieldComment + + + YES + id + id + id + id + id + id + id + id + + + + IBProjectSource + IpConfiguratorCommander.h + + + + IpConfiguratorCommander + NSObject + + IBUserSource + + + + + NSPreferencePane + NSObject + + YES + + YES + _firstKeyView + _initialKeyView + _lastKeyView + _window + + + YES + NSView + NSView + NSView + NSWindow + + + + IBUserSource + + + + + + 0 + ../../AFSCommander.xcodeproj + 3 + + diff --git a/src/platform/DARWIN/AFSPreference/English.lproj/Localizable.strings b/src/platform/DARWIN/AFSPreference/English.lproj/Localizable.strings new file mode 100644 index 000000000..76f8b4e1a --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/English.lproj/Localizable.strings @@ -0,0 +1,50 @@ + + + + + AfsButtonShutdown + Shutdown + AfsButtonStartup + Startup + AfsOff + Afs is off + AfsOn + Afs is on + ConfFileNotExits + Configuration files not found + ConfigurationSaved + Configuration file has been saved + DevelopInfo + Developed by Claudio Bisegni + NewCellComment + Cell comment + NewCellName + Cell name + PathDontContainAfsInstallation + Installation path doesn't contain an afs installation + PathNotEmpty + Path can't be empty + ThisCellFOError + ThisCell file open error + UserNotAuth + User not autenticated + MenuLogin + Get token + MenuUnlog + Release token + SavedCacheConfiguration + Cache Configuration File Saved + BadAfsRootMountPoint + Error in afs volume mount point + KerberosAuthError + Error in Kerberos Authetincation + BadAfsPath + Bad AFS mount point + DoYouWantCreateTheDirectory + Do you want create the directory + DirectoryCreated + Directory and launchd configuration file created + ErrorCreatingDirectory + Error creating directory + + diff --git a/src/platform/DARWIN/AFSPreference/English.lproj/OpenAFSPreference.xib b/src/platform/DARWIN/AFSPreference/English.lproj/OpenAFSPreference.xib new file mode 100644 index 000000000..4518e4761 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/English.lproj/OpenAFSPreference.xib @@ -0,0 +1,4335 @@ + + + + 1050 + 9D34 + 670 + 949.33 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + AFSCommanderPref + + + FirstResponder + + + NSApplication + + + 15 + 2 + {{423, 652}, {595, 486}} + 1081606144 + PDwgZG8gbm90IGxvY2FsaXplID4+A + NSWindow + + View + + {3.40282e+38, 3.40282e+38} + + + 274 + + YES + + + 256 + {{17, 0}, {488, 17}} + + YES + + 67239424 + 272629760 + + + LucidaGrande + 9.000000e+00 + 3614 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 266 + + YES + + + 256 + + YES + + + 268 + {{13, 9}, {109, 28}} + + YES + + 67239424 + 134348800 + On + + LucidaGrande + 1.100000e+01 + 3100 + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 265 + {{526, 12}, {21, 23}} + + YES + + -2080244224 + 134217728 + + + LucidaGrande + 1.300000e+01 + 1044 + + + -2038284033 + 33 + + + + + + 200 + 25 + + + + + 268 + {{273, 15}, {170, 18}} + + YES + + 67239424 + 0 + Get Krb5 credential at login + + LucidaGrande + 1.100000e+01 + 16 + + + 1211912703 + 130 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + + + + 268 + {{138, 15}, {117, 18}} + + YES + + 67239424 + 131072 + Start AFS at boot + + + 1211912703 + 130 + + + + + 200 + 25 + + + + {{1, 1}, {562, 49}} + + + + {{17, 417}, {564, 51}} + + {0, 0} + + 67239424 + 0 + Box + + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 3 + MCAwLjgwMDAwMDAxAA + + + + 1 + 0 + 0 + NO + + 1 + MCAwIDAgMC40MQA + + + + + 274 + {{13, 15}, {572, 401}} + + + YES + + + 1 + + + + 256 + + YES + + + 266 + + YES + + + 2304 + + YES + + + 256 + {516, 140} + + 1 + YES + + + 256 + {516, 17} + + + + + + -2147483392 + {{-22, 0}, {12, 17}} + + + + YES + + 5.130000e+02 + 4.109668e+01 + 1.000000e+03 + + 75628032 + 0 + Token + + + 3 + MC4zMzMzMzI5OQA + + + 6 + System + headerTextColor + + + + + 337772096 + 264192 + Text Cell + + + + 6 + System + controlBackgroundColor + + + + + 3 + YES + + + + 3.000000e+00 + 2.000000e+00 + + + 6 + System + gridColor + + 3 + MC41AA + + + 1.200000e+01 + -692060160 + 2 + 5 + 15 + 0 + YES + + + {{1, 17}, {516, 140}} + + + + + 4 + + + + -2147483392 + {{494, 17}, {11, 80}} + + 256 + + _doScroller: + 8.791209e-01 + + + + -2147483392 + {{1, 97}, {505, 11}} + + 257 + + _doScroller: + 9.980198e-01 + + + + 2304 + + YES + + + {{1, 0}, {516, 17}} + + + + + 4 + + + + {{17, 199}, {518, 158}} + + + 562 + + + + + + QSAAAEEgAABBYAAAQWAAAA + + + + 265 + {{322, 167}, {80, 28}} + + YES + + 67239424 + 134348800 + Unlog + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 265 + {{407, 167}, {133, 28}} + + YES + + 67239424 + 134348800 + Get new Token + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 268 + {{14, 163}, {86, 18}} + + YES + + 67239424 + 131072 + AFS Menu + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 12 + + YES + + + 256 + + YES + + + 268 + {{5, 31}, {75, 18}} + + YES + + 67239424 + 131072 + Use aklog + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 268 + {{5, 11}, {167, 18}} + + YES + + 67239424 + 131072 + get credential at login time + + + 1211912703 + 130 + + + + + 200 + 25 + + + + {{1, 1}, {195, 57}} + + + + {{103, 130}, {197, 73}} + + {0, 0} + + 67239424 + 0 + + + + + 3 + MCAwLjgwMDAwMDAxAA + + + + 1 + 0 + 2 + NO + + + {{10, 25}, {552, 363}} + + + Tokens + + + + + 2 + + + 256 + + YES + + + 265 + {{337, 335}, {198, 19}} + + YES + + 343014976 + 134349824 + + + CellServDB Search + + YES + 1 + + + + 130560 + 0 + search + _searchFieldSearch: + + + 138690815 + 0 + + 400 + 75 + + + 130560 + 0 + clear + + YES + + YES + + YES + AXDescription + NSAccessibilityEncodedAttributesValueType + + + YES + cancel + + + + + _searchFieldCancel: + + 138428671 + 0 + + 400 + 75 + + cell_searc + 255 + CAAAAA + + + + + 268 + {{17, 335}, {76, 17}} + + YES + + 67239424 + 272629760 + Default Cell: + + + + + + + + + 292 + {{17, 7}, {30, 25}} + + 1 + YES + + 67239424 + 134348800 + + + + 1 + + -2038021889 + 35 + + + + 400 + 75 + + + + + 292 + {{50, 7}, {30, 25}} + + 2 + YES + + 604110336 + 134348800 + - + + 2 + + -2038021889 + 35 + + + + 400 + 75 + + + + + 292 + {{82, 7}, {72, 25}} + + YES + + 604110336 + 134348800 + Modify + + + -2038021889 + 35 + + + + 400 + 75 + + + + + 289 + {{387, 4}, {151, 28}} + + YES + + 67239424 + 134348800 + Save Cell Configuration + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + + 274 + + YES + + + 2304 + + YES + + + 256 + {516, 271} + + 2 + YES + + + 256 + {516, 17} + + + + + + -2147483392 + {{-22, 0}, {12, 17}} + + + + YES + + 0 + 4.700000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + Default + + + 6 + System + headerColor + + + + + + 67239424 + 134348800 + + + + 1215582719 + 130 + + + + + 200 + 25 + + 3 + YES + YES + + + + 1 + 4.700000e+01 + 1.000000e+01 + 3.402823e+38 + + 75628032 + 0 + Tokens + + + + + + 67239424 + 134348800 + Check + + + 1212436991 + 130 + + + + + 200 + 25 + + 2 + YES + YES + + + + 2 + 1.670000e+02 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + Name + + + 3 + MC4zMzMzMzI5OQA + + + + + 337772096 + 133120 + Text Cell + + + + + + 3 + YES + + + + 3 + 2.430000e+02 + 6.509082e+01 + 1.000000e+03 + + 67239424 + 0 + Description + + + + + + 337772096 + 133120 + Text Cell + + + + + + 3 + YES + + + + 3.000000e+00 + 2.000000e+00 + + + 1.500000e+01 + 1522532352 + 1 + 4 + 15 + 0 + YES + + + {{1, 17}, {516, 271}} + + + + + 4 + + + + -2147483392 + {{506, 17}, {11, 198}} + + 256 + + _doScroller: + 9.473684e-01 + + + + -2147483392 + {{1, 215}, {516, 11}} + + 257 + + _doScroller: + 1.000000e+00 + 9.942197e-01 + + + + 2304 + + YES + + + {{1, 0}, {516, 17}} + + + + + 4 + + + + {{15, 41}, {518, 289}} + + + 562 + + + + + + QSAAAEEgAABBiAAAQYgAAA + + + + 268 + {{95, 338}, {237, 14}} + + YES + + 68288064 + 272630784 + Default Cell + + + + + 1 + MCAwLjEwOTg1MTg0IDEAA + + + + + {{10, 25}, {552, 363}} + + CellServDB Editor + + + + + 3 + + + 256 + + YES + + + 266 + + YES + + + 256 + + YES + + + 268 + {{18, 112}, {114, 14}} + + YES + + 67239488 + 272630784 + TsKwIHN0YXQgY2hhY2hlIGVudHJ5A + + + + + + + + + 268 + {{140, 107}, {55, 19}} + + YES + + -1804468671 + 272761856 + + + + + YES + + YES + allowsFloats + formatterBehavior + minimum + minimumIntegerDigits + numberStyle + positiveFormat + + + YES + + + + + + # + + + # + #0000 + + + + + + + + + + NaN + + YES + + YES + + + YES + + + + + + 0 + 0 + YES + NO + 1 + AAAAAAAAAAAAAAAAAAAAAA + + + 3 + YES + YES + YES + + , + . + NO + YES + YES + + + YES + + + 6 + System + textColor + + + + + + + 268 + {{140, 81}, {55, 19}} + + YES + + -1804468671 + -1874721792 + 0 + + + + YES + + YES + allowsFloats + formatterBehavior + minimum + minimumIntegerDigits + positiveFormat + + + YES + + + + + # + + + # + #000 + + + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + , + . + NO + YES + YES + + + YES + + + + + + + 268 + {{83, 83}, {49, 14}} + + YES + + 67239488 + 272630784 + DCache + + + + + + + + + 268 + {{140, 52}, {25, 19}} + + YES + + -1804468671 + 272761856 + + + + + YES + + YES + allowsFloats + formatterBehavior + maximumIntegerDigits + minimum + minimumIntegerDigits + positiveFormat + + + YES + + + + + + # + + + # + #0 + + + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + , + . + NO + YES + YES + + + YES + + + + + + + 268 + {{47, 54}, {85, 14}} + + YES + + 67239488 + 272630784 + TsKwIG9mIGRhZW1vbnM + + + + + + + + + 297 + {{413, 109}, {93, 18}} + + YES + + 604110336 + 131072 + Encryption + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 301 + {{209, 112}, {103, 14}} + + YES + + 67239488 + 272630784 + TsKwIFZvbHVtZSBlbnRyaWVzA + + + + + + + + + 301 + {{313, 109}, {37, 19}} + + YES + + 343014977 + 272630784 + + + + + YES + + YES + allowsFloats + formatWidth + formatterBehavior + generatesDecimalNumbers + groupingSize + maximumFractionDigits + maximumIntegerDigits + minimum + minimumIntegerDigits + numberStyle + positiveFormat + + + YES + + + + + + + + + + + # + + + # + #00 + + + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + , + . + NO + YES + NO + + + YES + + + + + + + 268 + {{46, 23}, {86, 14}} + + YES + + 67239488 + 272630784 + Afs Root Mount + + + + + + + + + 268 + {{140, 21}, {55, 19}} + + YES + + -1804468671 + 272630784 + / + + + YES + + + + + + + 301 + {{215, 81}, {97, 14}} + + YES + + 67239488 + 272630784 + Cache Dimension + + + + + + + + + 301 + {{313, 79}, {52, 19}} + + YES + + -1804468671 + 272630784 + + + + + YES + + YES + allowsFloats + formatterBehavior + minimum + minimumIntegerDigits + numberStyle + positiveFormat + + + YES + + + + + + # + + + # + #00000 + + + + + + + + + + NaN + + + + + + 3 + YES + YES + YES + + , + . + NO + YES + YES + + + YES + + + + + + + 297 + {{400, 15}, {104, 17}} + + YES + + -2080244224 + 134348800 + Save Param + + + -2038152961 + 164 + + + 400 + 75 + + + + + 297 + {{388, 4}, {126, 13}} + + YES + + 67239488 + 272630784 + afs needs to be restarted + + LucidaGrande + 1.000000e+01 + 16 + + + + + 1 + MSAwLjAyNDA1ODExNSAwLjAxMjI2ODU0MwA + + + + + + 297 + {{413, 89}, {76, 18}} + + YES + + -2080244224 + 131072 + DynRoot + + + 1211912703 + 2 + + + + + 200 + 25 + + + + + 297 + {{413, 49}, {66, 18}} + + YES + + -2080244224 + 131072 + Verbose + + + 1211912703 + 130 + + + + + 200 + 25 + + + + + 297 + {{413, 69}, {63, 18}} + + YES + + -2080244224 + 131072 + AfsDB + + + 1211912703 + 130 + + + + + 200 + 25 + + + + {{1, 1}, {522, 139}} + + + + {{14, 202}, {524, 155}} + + {0, 0} + + 67239424 + 0 + Cache Manager + + + + 3 + MCAwLjgwMDAwMDAxAA + + + + 1 + 0 + 2 + NO + + + {{10, 25}, {552, 363}} + + Parameter + + + + + 4 + + + 256 + + YES + + + 274 + + YES + + + 2304 + + YES + + + 256 + {501, 283} + + YES + + + 256 + {501, 17} + + + + + + 256 + {{502, 0}, {16, 17}} + + + + YES + + 8.400000e+01 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + Mount Name + + + 3 + MC4zMzMzMzI5OQA + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 4.110000e+02 + 4.000000e+01 + 1.000000e+03 + + 75628032 + 0 + Mount Path + + + + + + 337772096 + 2048 + Text Cell + + + + + + 3 + YES + YES + + + + 3.000000e+00 + 2.000000e+00 + + + 1.700000e+01 + -557842432 + 2 + 4 + 15 + 0 + YES + + + {{1, 17}, {501, 283}} + + + + + 4 + + + + 256 + {{502, 17}, {15, 283}} + + + _doScroller: + 3.700000e+01 + 1.947368e-01 + + + + 256 + {{1, 300}, {501, 15}} + + 1 + + _doScroller: + 5.714286e-01 + + + + 2304 + + YES + + + {{1, 0}, {501, 17}} + + + + + 4 + + + + {{17, 41}, {518, 316}} + + + 50 + + + + + + QSAAAEEgAABBmAAAQZgAAA + + + + 292 + {{17, 16}, {81, 18}} + + YES + + -2080244224 + 134348800 + Add New Path + + + -2033434369 + 160 + + + 400 + 75 + + + + + 292 + {{106, 16}, {78, 18}} + + YES + + -1543373312 + 134348800 + Remove Path + + + -2033434369 + 160 + + + 400 + 75 + + + + + 289 + {{400, 17}, {137, 18}} + + YES + + 67239424 + 131072 + Enable Symbolic Link + + + 1211912703 + 130 + + + + + 200 + 25 + + + + {{10, 25}, {552, 363}} + + Mounts + + + + + + + 134217728 + YES + YES + + YES + + + + + + 289 + {{229, 6}, {349, 11}} + + YES + + 68288064 + 71435264 + afs version + + LucidaGrande + 9.000000e+00 + 16 + + + + + + + + {595, 486} + + + {{0, 0}, {1920, 1178}} + {0, 22} + {3.40282e+38, 3.40282e+38} + + + 9 + 2 + {{1006, 707}, {715, 485}} + 1886912512 + Panel + + NSPanel + + + View + + {3.40282e+38, 3.40282e+38} + + + 256 + + YES + + + 274 + + YES + + + 2304 + + YES + + + 2322 + {662, 14} + + + + + + + + + + + YES + + + 6 + + + + 6.620000e+02 + 1 + + + 2913 + + + + YES + + YES + NSBackgroundColor + NSColor + + + YES + + 6 + System + selectedTextBackgroundColor + + + + 6 + System + selectedTextColor + + + + + + + YES + + YES + NSColor + NSUnderline + + + YES + + 1 + MCAwIDEAA + + + + + + + 6 + {1337, 1e+07} + {114, 0} + + + + {{1, 1}, {662, 423}} + + + + + + {4, -5} + 1 + + 4 + + + + 256 + {{663, 1}, {11, 423}} + + 256 + + _doScroller: + 1.000000e+00 + + + + 256 + {{-100, -100}, {87, 18}} + + 257 + + _doScroller: + 1.000000e+00 + 9.456522e-01 + + + {{20, 40}, {675, 425}} + + + 18 + + + + + + + 293 + {{318, 8}, {80, 28}} + + YES + + 67239424 + 134348800 + Close + + + -2038284033 + 1 + + + + + + 200 + 25 + + + + {715, 485} + + {{0, 0}, {1920, 1178}} + {0, 22} + {3.40282e+38, 3.40282e+38} + + + InfoController + + + + + YES + + + _window + + + + 100 + + + + cellList + + + + 187 + + + + cellIpButton + + + + 188 + + + + removeCellButton + + + + 189 + + + + addCellButton + + + + 190 + + + + addRemoveCell: + + + + 191 + + + + addRemoveCell: + + + + 192 + + + + showCellIP: + + + + 193 + + + + saveConfiguration: + + + + 202 + + + + infoSheet + + + + 217 + + + + infoController + + + + 225 + + + + infoPanel + + + + 226 + + + + texEditInfo + + + + 227 + + + + closePanel: + + + + 228 + + + + afsCommanderView + + + + 303 + + + + statCacheEntry + + + + 418 + + + + dCacheDim + + + + 419 + + + + daemonNumber + + + + 420 + + + + afsRootMountPoint + + + + 421 + + + + nVolEntry + + + + 422 + + + + cacheDimension + + + + 423 + + + + dynRoot + + + + 424 + + + + saveCacheManagerParam: + + + + 474 + + + + delegate + + + + 669 + + + + textSearchField + + + + 812 + + + + searchCellTextEvent: + + + + 817 + + + + delegate + + + + 886 + + + + startStopAfs: + + + + 1105 + + + + startStopButton + + + + 1106 + + + + afsMenuActivationEvent: + + + + 1109 + + + + afsMenucheckBox + + + + 1110 + + + + info: + + + + 1113 + + + + tokensTable + + + + 1206 + + + + unlog: + + + + 1211 + + + + getNewToken: + + + + 1212 + + + + useAklogCheck + + + + 1282 + + + + aklogSwitchEvent: + + + + 1353 + + + + unlogButton + + + + 1644 + + + + tokensButton + + + + 1645 + + + + afsVersionLabel + + + + 1717 + + + + afsDefaultCellLabel + + + + 1847 + + + + afsDB + + + + 1904 + + + + verbose + + + + 1962 + + + + aklogCredentialAtLoginTime + + + + 2014 + + + + credentialAtLoginTimeEvent: + + + + 2015 + + + + installKRB5AuthAtLoginButton + + + + 2020 + + + + krb5KredentialAtLoginTimeEvent: + + + + 2021 + + + + checkEnableLink + + + + 2042 + + + + buttonRemoveLink + + + + 2044 + + + + buttonAddLink + + + + 2045 + + + + addLink: + + + + 2046 + + + + removeLink: + + + + 2047 + + + + enableLink: + + + + 2048 + + + + checkButtonAfsAtBootTime + + + + 2051 + + + + afsStartupSwitchEvent: + + + + 2052 + + + + textFieldDevInfoLabel + + + + 2053 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 12 + + + YES + + + + PrefPane + + + 6 + + + YES + + + + + + + + + 101 + + + YES + + + + + + + + + 104 + + + YES + + + + + + 105 + + + YES + + + + + + + + + + 1107 + + + YES + + + + + + 1199 + + + YES + + + + + + + + + 1203 + + + YES + + + + + + 1204 + + + YES + + + + + + 1207 + + + YES + + + + + + 1209 + + + YES + + + + + + 177 + + + YES + + + + + + 178 + + + YES + + + + + + + + + + + + + 179 + + + YES + + + + + + + + + 180 + + + YES + + + + + + + + + 181 + + + YES + + + + + + 182 + + + YES + + + + + + 1422 + + + YES + + + + + + 1426 + + + + + 1787 + + + YES + + + + + + 1789 + + + + + 183 + + + YES + + + + + + 184 + + + YES + + + + + + 185 + + + YES + + + + + + 186 + + + YES + + + + + + 200 + + + YES + + + + + + 265 + + + YES + + + + + + 1845 + + + YES + + + + + + 337 + + + YES + + + + + + 338 + + + YES + + + + + + 339 + + + YES + + + + + + + + + + + + + + + + + + + + + + + 207 + + + YES + + + + + + 1122 + + + YES + + + + + + + + + 1715 + + + YES + + + + + + 208 + + + YES + + + + Info + + + 209 + + + YES + + + + + + + 214 + + + YES + + + + + + + + 215 + + + + + 216 + + + YES + + + + + + 224 + + + InfoController + + + 1964 + + + + + 1965 + + + + + 1966 + + + + + 1968 + + + + + 1969 + + + + + 1970 + + + + + 1971 + + + + + 1972 + + + + + 1973 + + + + + 1974 + + + + + 1993 + + + + + 1998 + + + + + 1999 + + + + + 2000 + + + + + 2001 + + + + + 2002 + + + + + 2003 + + + + + 2004 + + + + + 2005 + + + + + 2006 + + + + + 2007 + + + + + 2008 + + + + + 2009 + + + + + 2010 + + + + + 340 + + + YES + + + + + + 1975 + + + + + 342 + + + YES + + + + + + 1976 + + + YES + + + + + + 741 + + + + + 344 + + + YES + + + + + + 1977 + + + YES + + + + + + 742 + + + + + 345 + + + YES + + + + + + 1978 + + + + + 348 + + + YES + + + + + + 1979 + + + YES + + + + + + 417 + + + + + 349 + + + YES + + + + + + 1980 + + + + + 352 + + + YES + + + + + + 1981 + + + + + 402 + + + YES + + + + + + 1983 + + + + + 404 + + + YES + + + + + + 1984 + + + YES + + + + + + 411 + + + + + 406 + + + YES + + + + + + 1985 + + + + + 408 + + + YES + + + + + + 1986 + + + + + 413 + + + YES + + + + + + 1987 + + + + + 415 + + + YES + + + + + + 1988 + + + YES + + + + + + 740 + + + + + 425 + + + YES + + + + + + 1989 + + + + + 475 + + + YES + + + + + + 1990 + + + + + 400 + + + YES + + + + + + 1982 + + + + + 1902 + + + YES + + + + + + 1991 + + + + + 1960 + + + YES + + + + + + 1992 + + + + + 1103 + + + YES + + + + + + 1994 + + + + + 1111 + + + YES + + + + + + 1995 + + + + + 2013 + + + YES + + + + + + + 1280 + + + YES + + + + + + 1967 + + + + + 2011 + + + YES + + + + + + 2012 + + + + + 2018 + + + YES + + + + + + 2019 + + + + + 2022 + + + YES + + + + + + 2023 + + + YES + + + + + + + + + 2024 + + + YES + + + + + + + + + 2025 + + + + + 2026 + + + + + 2027 + + + YES + + + + + + + 2028 + + + + + 2029 + + + YES + + + + + + 2030 + + + YES + + + + + + 2031 + + + + + 2032 + + + + + 2033 + + + YES + + + + + + 2034 + + + + + 2035 + + + YES + + + + + + 2036 + + + + + 2037 + + + YES + + + + + + 2038 + + + + + 2049 + + + YES + + + + + + 2050 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + -3.ImportedFromIB2 + 101.IBPluginDependency + 101.ImportedFromIB2 + 104.IBPluginDependency + 104.ImportedFromIB2 + 105.IBPluginDependency + 105.ImportedFromIB2 + 1103.IBPluginDependency + 1103.ImportedFromIB2 + 1107.IBPluginDependency + 1107.ImportedFromIB2 + 1111.IBPluginDependency + 1111.ImportedFromIB2 + 1122.IBPluginDependency + 1122.ImportedFromIB2 + 1199.IBPluginDependency + 1199.ImportedFromIB2 + 12.IBEditorWindowLastContentRect + 12.IBPluginDependency + 12.IBWindowTemplateEditedContentRect + 12.ImportedFromIB2 + 12.windowTemplate.hasMinSize + 12.windowTemplate.maxSize + 12.windowTemplate.minSize + 1203.IBPluginDependency + 1203.ImportedFromIB2 + 1204.IBPluginDependency + 1204.ImportedFromIB2 + 1207.IBPluginDependency + 1207.ImportedFromIB2 + 1209.IBPluginDependency + 1209.ImportedFromIB2 + 1280.IBPluginDependency + 1280.ImportedFromIB2 + 1422.IBPluginDependency + 1422.ImportedFromIB2 + 1426.IBPluginDependency + 1426.ImportedFromIB2 + 1715.IBPluginDependency + 1715.ImportedFromIB2 + 177.IBPluginDependency + 177.ImportedFromIB2 + 178.IBPluginDependency + 178.ImportedFromIB2 + 1787.IBPluginDependency + 1787.ImportedFromIB2 + 1789.IBPluginDependency + 1789.ImportedFromIB2 + 179.IBPluginDependency + 179.ImportedFromIB2 + 180.IBPluginDependency + 180.ImportedFromIB2 + 181.IBPluginDependency + 181.ImportedFromIB2 + 182.IBPluginDependency + 182.ImportedFromIB2 + 183.IBPluginDependency + 183.ImportedFromIB2 + 184.IBPluginDependency + 184.ImportedFromIB2 + 1845.IBPluginDependency + 1845.ImportedFromIB2 + 185.IBPluginDependency + 185.ImportedFromIB2 + 186.IBPluginDependency + 186.ImportedFromIB2 + 1902.IBPluginDependency + 1902.ImportedFromIB2 + 1960.IBAttributePlaceholdersKey + 1960.IBPluginDependency + 1960.ImportedFromIB2 + 1992.IBAttributePlaceholdersKey + 200.IBPluginDependency + 200.ImportedFromIB2 + 2000.IBShouldRemoveOnLegacySave + 2001.IBShouldRemoveOnLegacySave + 2002.IBShouldRemoveOnLegacySave + 2003.IBShouldRemoveOnLegacySave + 2004.IBShouldRemoveOnLegacySave + 2005.IBShouldRemoveOnLegacySave + 2006.IBShouldRemoveOnLegacySave + 2007.IBShouldRemoveOnLegacySave + 2008.IBShouldRemoveOnLegacySave + 2009.IBShouldRemoveOnLegacySave + 2010.IBShouldRemoveOnLegacySave + 2011.IBPluginDependency + 2012.IBPluginDependency + 2013.IBPluginDependency + 2018.IBPluginDependency + 2019.IBPluginDependency + 2024.IBPluginDependency + 2025.IBPluginDependency + 2026.IBPluginDependency + 2027.IBPluginDependency + 2028.IBPluginDependency + 2029.IBPluginDependency + 2030.IBPluginDependency + 2031.IBPluginDependency + 2032.IBPluginDependency + 2033.IBPluginDependency + 2034.IBPluginDependency + 2035.IBPluginDependency + 2036.IBPluginDependency + 2037.IBPluginDependency + 2038.IBPluginDependency + 2049.IBPluginDependency + 2050.IBPluginDependency + 207.IBPluginDependency + 207.ImportedFromIB2 + 208.IBEditorWindowLastContentRect + 208.IBPluginDependency + 208.IBWindowTemplateEditedContentRect + 208.ImportedFromIB2 + 208.windowTemplate.hasMinSize + 208.windowTemplate.maxSize + 208.windowTemplate.minSize + 209.IBPluginDependency + 209.ImportedFromIB2 + 214.IBPluginDependency + 214.ImportedFromIB2 + 215.IBPluginDependency + 215.ImportedFromIB2 + 216.IBPluginDependency + 216.ImportedFromIB2 + 224.IBPluginDependency + 224.ImportedFromIB2 + 265.IBPluginDependency + 265.ImportedFromIB2 + 337.IBPluginDependency + 337.ImportedFromIB2 + 338.IBPluginDependency + 338.ImportedFromIB2 + 339.IBPluginDependency + 339.ImportedFromIB2 + 340.IBPluginDependency + 340.ImportedFromIB2 + 342.IBPluginDependency + 342.ImportedFromIB2 + 344.IBAttributePlaceholdersKey + 344.IBPluginDependency + 344.ImportedFromIB2 + 345.IBPluginDependency + 345.ImportedFromIB2 + 348.IBAttributePlaceholdersKey + 348.IBPluginDependency + 348.ImportedFromIB2 + 349.IBPluginDependency + 349.ImportedFromIB2 + 352.IBPluginDependency + 352.ImportedFromIB2 + 400.IBPluginDependency + 400.ImportedFromIB2 + 402.IBPluginDependency + 402.ImportedFromIB2 + 404.IBAttributePlaceholdersKey + 404.IBPluginDependency + 404.ImportedFromIB2 + 406.IBPluginDependency + 406.ImportedFromIB2 + 408.IBAttributePlaceholdersKey + 408.IBPluginDependency + 408.ImportedFromIB2 + 411.IBPluginDependency + 411.ImportedFromIB2 + 413.IBPluginDependency + 413.ImportedFromIB2 + 415.IBAttributePlaceholdersKey + 415.IBPluginDependency + 415.ImportedFromIB2 + 417.IBPluginDependency + 417.ImportedFromIB2 + 425.IBPluginDependency + 425.ImportedFromIB2 + 475.IBPluginDependency + 475.ImportedFromIB2 + 6.IBPluginDependency + 6.ImportedFromIB2 + 740.IBPluginDependency + 740.ImportedFromIB2 + 741.IBPluginDependency + 741.ImportedFromIB2 + 742.IBPluginDependency + 742.ImportedFromIB2 + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + {{192, 153}, {595, 486}} + com.apple.InterfaceBuilder.CocoaPlugin + {{192, 153}, {595, 486}} + + + {3.40282e+38, 3.40282e+38} + {0, 0} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + Enable the verbose mode or afsd + + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + RW5hYmxlIGxvdCBvZiBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24gZnJvbSBhZnNkLiAgT25seSB1c2VmdWwg +Zm9yIGRlYnVnZ2luZyBhcyBpdCBwcmludHMgYSBMT1Qgb2YgaW5mb3JtYXRpb24uCg + + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + {{0, 510}, {715, 485}} + com.apple.InterfaceBuilder.CocoaPlugin + {{0, 510}, {715, 485}} + + + {3.40282e+38, 3.40282e+38} + {0, 0} + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + DCache entry used for store information about cache chunk + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + Number of daemons to use + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + Specifies the number of memory structures to allocate for storing volume location information + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + The directory on which the AFS is to be mounted. + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + ToolTip + + ToolTip + + Specifies the number of memory structures to allocate for storing volume location information + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 2053 + + + + YES + + AFSCommanderPref + NSPreferencePane + + YES + + YES + addLink: + addRemoveCell: + afsMenuActivationEvent: + afsStartupSwitchEvent: + aklogSwitchEvent: + credentialAtLoginTimeEvent: + enableLink: + getNewToken: + info: + krb5KredentialAtLoginTimeEvent: + refreshConfiguration: + removeLink: + saveCacheManagerParam: + saveConfiguration: + searchCellTextEvent: + showCellIP: + startStopAfs: + tableDoubleAction: + unlog: + + + YES + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + YES + + YES + addCellButton + afsCommanderView + afsDB + afsDefaultCellLabel + afsMenucheckBox + afsRootMountPoint + afsVersionLabel + aklogCredentialAtLoginTime + buttonAddLink + buttonRemoveLink + cacheDimension + cellIpButton + cellList + checkButtonAfsAtBootTime + checkEnableLink + credentialCommander + credentialSheet + dCacheDim + daemonNumber + dynRoot + groupsBox + infoController + infoSheet + installKRB5AuthAtLoginButton + ipConfControllerCommander + ipConfigurationSheet + labelSaveResult + lyncCreationSheet + lynkCreationController + nVolEntry + removeCellButton + saveConfigurationButton + startStopButton + statCacheEntry + textFieldDevInfoLabel + textSearchField + tokensButton + tokensTable + unlogButton + useAklogCheck + verbose + + + YES + id + NSView + NSButton + NSTextField + id + NSTextField + NSTextField + NSButton + NSButton + NSButton + NSTextField + id + id + NSButton + NSButton + id + id + NSTextField + NSTextField + NSButton + NSBox + id + id + NSButton + id + id + id + id + LynkCreationController + NSTextField + id + id + id + NSTextField + NSTextField + NSSearchField + NSButton + id + NSButton + NSButton + NSButton + + + + IBProjectSource + AFSCommanderPref.h + + + + AFSCommanderPref + NSPreferencePane + + YES + + YES + cellPopupButton + getTokenButton + + + YES + NSPopUpButton + NSPopUpButton + + + + IBUserSource + + + + + FirstResponder + NSObject + + IBUserSource + + + + + InfoController + NSObject + + closePanel: + id + + + YES + + YES + infoPanel + texEditInfo + + + YES + id + id + + + + IBProjectSource + InfoController.h + + + + InfoController + NSObject + + IBUserSource + + + + + LynkCreationController + NSObject + + YES + + YES + cancell: + save: + selectLinkDest: + + + YES + id + id + id + + + + YES + + YES + lynkCreationSheet + textFieldLinkDestPath + textfieldLinkName + + + YES + NSPanel + NSTextField + NSTextField + + + + IBProjectSource + LynkCreationController.h + + + + NSPreferencePane + NSObject + + YES + + YES + _firstKeyView + _initialKeyView + _lastKeyView + _window + + + YES + id + id + id + id + + + + IBUserSource + + + + + + 0 + ../OpenAFS.xcodeproj + 3 + + diff --git a/src/platform/DARWIN/AFSPreference/English.lproj/SymLinkEdit.xib b/src/platform/DARWIN/AFSPreference/English.lproj/SymLinkEdit.xib new file mode 100644 index 000000000..50eca3361 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/English.lproj/SymLinkEdit.xib @@ -0,0 +1,728 @@ + + + + 1050 + 9D34 + 667 + 949.33 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + AFSCommanderPref + + + FirstResponder + + + NSApplication + + + LynkCreationController + + + 11 + 2 + {{196, 372}, {502, 138}} + 1946157056 + Window + NSPanel + + {800, 138} + {502, 138} + + + 266 + + YES + + + 268 + {{46, 116}, {67, 14}} + + YES + + 68288064 + 272761856 + Lynk Name: + + LucidaGrande + 1.100000e+01 + 3100 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2OQA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 266 + {{118, 114}, {364, 19}} + + YES + + -1804468671 + 272761856 + + + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + textColor + + + + + + + 268 + {{17, 89}, {96, 14}} + + YES + + 68288064 + 272761856 + Destination Path: + + + + + + + + + 266 + {{118, 87}, {364, 19}} + + YES + + -1804468671 + 272761856 + + + + YES + + + + + + + 265 + {{391, 55}, {96, 28}} + + YES + + 67239424 + 134348800 + Select Path + + + -2038284033 + 268435585 + + p + 200 + 25 + + + + + 289 + {{391, 28}, {96, 28}} + + YES + + -2080244224 + 134348800 + Save + + + -2038284033 + 129 + + DQ + 200 + 25 + + + + + 289 + {{297, 28}, {96, 28}} + + YES + + 67239424 + 134348800 + Cancel + + + -2038284033 + 129 + + Gw + 200 + 25 + + + + {502, 138} + + + {{0, 0}, {1920, 1178}} + {502, 160} + {800, 160} + + + + + YES + + + save: + + + + 23 + + + + cancell: + + + + 24 + + + + lynkCreationSheet + + + + 25 + + + + lyncCreationSheet + + + + 26 + + + + selectLinkDest: + + + + 27 + + + + textFieldLinkDestPath + + + + 28 + + + + textfieldLinkName + + + + 29 + + + + + YES + + 0 + + YES + + + + + + -2 + + + RmlsZSdzIE93bmVyA + + + -1 + + + First Responder + + + -3 + + + Application + + + 6 + + + YES + + + + LynkCreation + + + 7 + + + YES + + + + + + + + + + + + 8 + + + YES + + + + + + 9 + + + + + 10 + + + YES + + + + + + 11 + + + + + 12 + + + YES + + + + + + 13 + + + YES + + + + + + 14 + + + + + 15 + + + + + 16 + + + YES + + + + + + 17 + + + + + 18 + + + YES + + + + + + 19 + + + + + 20 + + + YES + + + + + + 21 + + + + + 22 + + + + + + + YES + + YES + -1.IBPluginDependency + -2.IBPluginDependency + -3.IBPluginDependency + 10.IBAttributePlaceholdersKey + 10.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBAttributePlaceholdersKey + 13.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 16.IBPluginDependency + 17.IBPluginDependency + 18.IBPluginDependency + 19.IBPluginDependency + 20.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 6.IBEditorWindowLastContentRect + 6.IBPluginDependency + 6.IBWindowTemplateEditedContentRect + 6.NSWindowTemplate.visibleAtLaunch + 6.windowTemplate.hasMaxSize + 6.windowTemplate.hasMinSize + 6.windowTemplate.maxSize + 6.windowTemplate.minSize + 7.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilderKit + com.apple.InterfaceBuilderKit + + ToolTip + + ToolTip + + Alias that describe the link. It will be used as mount name. + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + ToolTip + + ToolTip + + AFS path for the link destination + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{86, 409}, {502, 138}} + com.apple.InterfaceBuilder.CocoaPlugin + {{86, 409}, {502, 138}} + + + + {800, 138} + {502, 138} + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 29 + + + + YES + + AFSCommanderPref + NSPreferencePane + + YES + + YES + addLink: + addRemoveCell: + afsMenuActivationEvent: + aklogSwitchEvent: + credentialAtLoginTimeEvent: + enableLink: + getNewToken: + info: + krb5KredentialAtLoginTimeEvent: + refreshConfiguration: + removeLink: + saveCacheManagerParam: + saveConfiguration: + searchCellTextEvent: + showCellIP: + startStopAfs: + tableDoubleAction: + unlog: + + + YES + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + id + + + + YES + + YES + addCellButton + afsCommanderView + afsDB + afsDefaultCellLabel + afsMenucheckBox + afsRootMountPoint + afsVersionLabel + aklogCredentialAtLoginTime + buttonAddLink + buttonRemoveLink + cacheDimension + cellIpButton + cellList + checkEnableLink + credentialCommander + credentialSheet + dCacheDim + daemonNumber + dynRoot + groupsBox + infoController + infoSheet + installKRB5AuthAtLoginButton + installationPathTextField + ipConfControllerCommander + ipConfigurationSheet + labelSaveResult + lyncCreationSheet + lynkCreationController + nVolEntry + refreshConfigurationButton + removeCellButton + saveConfigurationButton + startStopButton + statCacheEntry + textSearchField + tokensButton + tokensTable + unlogButton + useAklogCheck + verbose + + + YES + id + NSView + NSButton + NSTextField + id + NSTextField + NSTextField + NSButton + NSButton + NSButton + NSTextField + id + id + NSButton + id + id + NSTextField + NSTextField + NSButton + NSBox + id + id + NSButton + id + id + id + id + id + LynkCreationController + NSTextField + id + id + id + id + NSTextField + NSSearchField + NSButton + id + NSButton + NSButton + NSButton + + + + IBProjectSource + AFSCommanderPref.h + + + + LynkCreationController + NSObject + + YES + + YES + cancell: + save: + selectLinkDest: + + + YES + id + id + id + + + + YES + + YES + lynkCreationSheet + textFieldLinkDestPath + textfieldLinkName + + + YES + NSPanel + NSTextField + NSTextField + + + + IBProjectSource + LynkCreationController.h + + + + + 0 + ../OpenAFS.xcodeproj + 3 + + diff --git a/src/platform/DARWIN/AFSPreference/FileUtil.h b/src/platform/DARWIN/AFSPreference/FileUtil.h new file mode 100644 index 000000000..42257ca3c --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/FileUtil.h @@ -0,0 +1,24 @@ +// +// FileUtil.h +// AFSCommander +// +// Created by Claudio Bisegni on 21/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#include "AuthUtil.h" + +@interface FileUtil : NSObject { + AuthUtil *autorization; +} + +-(id) init; +-(void) dealloc; +-(OSStatus) startAutorization; +-(OSStatus) autorizedMoveFile:(NSString*)srcPath toPath:(NSString*)dstPath; +-(OSStatus) autorizedChown:(NSString*)filePath owner:(NSString*)owner group:(NSString*)group; +-(OSStatus) autorizedCopy:(NSString*)srcPath toPath:(NSString*)dstPath; +-(OSStatus) autorizedDelete:(NSString*)destFilePath; +-(void) endAutorization; +@end diff --git a/src/platform/DARWIN/AFSPreference/FileUtil.m b/src/platform/DARWIN/AFSPreference/FileUtil.m new file mode 100644 index 000000000..6b2b5fccf --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/FileUtil.m @@ -0,0 +1,91 @@ +// +// FileUtil.m +// AFSCommander +// +// Created by Claudio Bisegni on 21/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "FileUtil.h" + +@implementation FileUtil + +-(id) init; +{ + [super init]; + return self; +} + +-(void) dealloc +{ + [super dealloc]; +} + +// ------------------------------------------------------------------------------- +// startAutorization: +// ------------------------------------------------------------------------------- +-(OSStatus) startAutorization +{ + OSStatus err = noErr; + err = [[AuthUtil shared] autorize]; + return err; +} + +// ------------------------------------------------------------------------------- +// autorizedMoveFile: +// ------------------------------------------------------------------------------- +-(OSStatus) autorizedMoveFile:(NSString*)srcPath toPath:(NSString*)dstPath +{ + OSStatus status = noErr; + const char *arguments[] = {[srcPath UTF8String], [dstPath UTF8String], 0L}; + status = [[AuthUtil shared] execUnixCommand:"/bin/mv" args:arguments output:nil]; + return status; +} + +// ------------------------------------------------------------------------------- +// autorizedMoveFile: +// ------------------------------------------------------------------------------- +-(OSStatus) autorizedCopy:(NSString*)srcPath toPath:(NSString*)dstPath +{ + OSStatus status = noErr; + const char *arguments[] = {[srcPath UTF8String], [dstPath UTF8String], 0L}; + status = [[AuthUtil shared] execUnixCommand:"/bin/cp" args:arguments output:nil]; + return status; +} + +// ------------------------------------------------------------------------------- +// autorizedChown: +// ------------------------------------------------------------------------------- +-(OSStatus) autorizedChown:(NSString*)filePath owner:(NSString*)owner group:(NSString*)group; +{ + OSStatus status = noErr; + NSMutableString *chownParam = [[NSMutableString alloc] init]; + [chownParam appendString:owner]; + [chownParam appendString:@":"]; + [chownParam appendString:group]; + + const char *arguments[] = {[chownParam UTF8String], [filePath UTF8String], 0L}; + status = [[AuthUtil shared] execUnixCommand:"/usr/sbin/chown" args:arguments output:nil]; + [chownParam release]; + return status; +} + +// ------------------------------------------------------------------------------- +// autorizedDelete: +// ------------------------------------------------------------------------------- +-(OSStatus) autorizedDelete:(NSString*)destFilePath{ + OSStatus status = noErr; + const char *arguments[] = {[destFilePath UTF8String], 0L}; + status = [[AuthUtil shared] execUnixCommand:"/bin/rm" args:arguments output:nil]; + return status; +} + +// ------------------------------------------------------------------------------- +// endAutorization: +// ------------------------------------------------------------------------------- +-(void) endAutorization +{ + [[AuthUtil shared] deautorize]; +} + +@end \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/Info.plist b/src/platform/DARWIN/AFSPreference/Info.plist new file mode 100644 index 000000000..80459b933 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/Info.plist @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + OpenAFS + CFBundleIdentifier + it.infn.lnf.network.openafs + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0b + CFBundleSignature + INFN + CFBundleVersion + 1.0b + NSMainNibFile + OpenAFSPreference + NSPrefPaneIconFile + AFSCommanderIcon + NSPrefPaneIconLabel + OpenAFS + NSPrincipalClass + AFSCommanderPref + + diff --git a/src/platform/DARWIN/AFSPreference/InfoController.h b/src/platform/DARWIN/AFSPreference/InfoController.h new file mode 100644 index 000000000..23d1d1e71 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/InfoController.h @@ -0,0 +1,21 @@ +// +// InfoCommander.h +// AFSCommander +// +// Created by Claudio Bisegni on 06/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import + + +@interface InfoController : NSObject { + id infoPanel; + id texEditInfo; + + NSAttributedString *htmlLicence; +} +- (IBAction) closePanel:(id) sender; +- (void)showHtmlResource :(NSString*)resourcePath; + +@end diff --git a/src/platform/DARWIN/AFSPreference/InfoController.m b/src/platform/DARWIN/AFSPreference/InfoController.m new file mode 100644 index 000000000..f10f03e8c --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/InfoController.m @@ -0,0 +1,42 @@ +// +// InfoCommander.m +// AFSCommander +// +// Created by Claudio Bisegni on 06/07/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "InfoController.h" + + +@implementation InfoController +// ------------------------------------------------------------------------------- +// awakeFromNib: +// ------------------------------------------------------------------------------- +- (void)awakeFromNib +{ + NSLog(@"awakeFromNib"); + htmlLicence = nil; +} + +// ------------------------------------------------------------------------------- +// awakeFromNib: +// ------------------------------------------------------------------------------- +- (void)showHtmlResource :(NSString*)resourcePath +{ + NSData *rtfData = [NSData dataWithContentsOfFile:resourcePath]; + htmlLicence = [[NSAttributedString alloc] initWithRTF:rtfData + documentAttributes:nil]; + [[((NSTextView*) texEditInfo ) textStorage] setAttributedString:htmlLicence]; +} + + +// ------------------------------------------------------------------------------- +// awakeFromNib: +// ------------------------------------------------------------------------------- +- (IBAction) closePanel:(id) sender +{ + if(htmlLicence) [htmlLicence release]; + [NSApp endSheet:infoPanel]; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.h b/src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.h new file mode 100644 index 000000000..b0e7dfa8f --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.h @@ -0,0 +1,42 @@ +// +// IpConfiguratorCommander.h +// AFSCommander +// +// Created by Claudio Bisegni on 18/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#import "DBCellElement.h" +#import "AFSCommanderPref.h" +@interface IpConfiguratorCommander : NSObject { + id confPanel; + id afsCommanderPref; + id textFieldCellName; + id textFieldComment; + id tableViewCellIP; + + id modifyButton; + id createButton; + id deleteButton; + + BOOL hasSaved; + DBCellElement *cellElement; + NSMutableArray *bkIPArray; + NSMutableArray *workIPArray; + CellIp *currentSelectedIP; +} + +- (void) setWorkCell:(DBCellElement*)cell; +- (IBAction) save:(id) sender; +- (IBAction) cancel:(id) sender; +- (IBAction) createNewIP:(id) sender; +- (IBAction) cancelIP:(id) sender; +- (BOOL) saved; + +- (id) getPanel; +- (void) commitModify; +- (void) rollbackModify; +- (void) loadValueFromCellIPClass; +- (void) manageTableSelection:(int)row; +@end diff --git a/src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.m b/src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.m new file mode 100644 index 000000000..668f7eb0e --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/IpConfiguratorCommander.m @@ -0,0 +1,238 @@ +// +// IpConfiguratorCommander.m +// AFSCommander +// +// Created by Claudio Bisegni on 18/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "IpConfiguratorCommander.h" +#import "AFSCommanderPref.h" + +@implementation IpConfiguratorCommander + +// ------------------------------------------------------------------------------- +// awakeFromNib: +// ------------------------------------------------------------------------------- +- (void)awakeFromNib +{ + NSLog(@"awakeFromNib"); + [((NSTableView*)tableViewCellIP) setDelegate:self]; + [((NSTableView*)tableViewCellIP) setDataSource:self]; +} + +// ------------------------------------------------------------------------------- +// initWhitCell: +// ------------------------------------------------------------------------------- +- (void) setWorkCell:(DBCellElement*)cell { + cellElement = cell; + currentSelectedIP = nil; +} + +// ------------------------------------------------------------------------------- +// save: +// ------------------------------------------------------------------------------- +- (IBAction) save:(id) sender +{ + hasSaved = YES; + [self commitModify]; + [NSApp endSheet:confPanel]; +} + +// ------------------------------------------------------------------------------- +// commitModify: +// ------------------------------------------------------------------------------- +- (void) commitModify +{ + //store the cell name + [cellElement setCellName:[((NSControl*) textFieldCellName) stringValue]]; + [cellElement setCellComment:[((NSControl*) textFieldComment) stringValue]]; + + NSLog(@"Deleting:\n%s",[[bkIPArray description] cString]); + [bkIPArray removeAllObjects]; + NSLog(@"deleted:\n"); + NSLog(@"Coping:\n%s",[[workIPArray description] cString]); + [bkIPArray setArray:workIPArray]; + NSLog(@"Copied:\n%s",[[workIPArray description] cString]); + NSLog(@"Releasing:\n%s",[[workIPArray description] cString]); + [workIPArray release]; + NSLog(@"Released:\n%s",[[workIPArray description] cString]); +} + +// ------------------------------------------------------------------------------- +// cancel: +// ------------------------------------------------------------------------------- +- (IBAction) cancel:(id) sender +{ + hasSaved = NO; + [self rollbackModify]; + [NSApp endSheet:confPanel]; +} + + +// ------------------------------------------------------------------------------- +// rollbackModify: +// ------------------------------------------------------------------------------- +- (void) rollbackModify +{ + // take bkarray + [workIPArray release]; + workIPArray = nil; +} + +// ------------------------------------------------------------------------------- +// createNewIP: +// ------------------------------------------------------------------------------- +- (IBAction) createNewIP:(id) sender +{ + CellIp *ip = [[CellIp alloc] init]; + [workIPArray addObject:ip]; + [ip release]; + currentSelectedIP = ip; + [((NSTableView*)tableViewCellIP) reloadData]; + [((NSTableView *) tableViewCellIP) scrollRowToVisible:[[cellElement getIp] count]-1]; +} + +// ------------------------------------------------------------------------------- +// cancelIP: +// ------------------------------------------------------------------------------- +- (IBAction) cancelIP:(id) sender +{ + [workIPArray removeObjectAtIndex:[((NSTableView*)tableViewCellIP) selectedRow]]; + [((NSTableView*)tableViewCellIP) deselectAll:nil]; + [self manageTableSelection:-1]; + [((NSTableView*)tableViewCellIP) reloadData]; + +} + +// ------------------------------------------------------------------------------- +// hasSaved: +// ------------------------------------------------------------------------------- +- (BOOL)saved +{ + return hasSaved; +} + +// ------------------------------------------------------------------------------- +// loadValueFromCellIPClass: +// ------------------------------------------------------------------------------- +- (void) loadValueFromCellIPClass +{ + [((NSTextField*)textFieldCellName) setStringValue:[cellElement getCellName]]; + [((NSTextField*)textFieldComment) setStringValue:[cellElement getCellComment]]; + [((NSTableView*)tableViewCellIP) reloadData]; +} + +// ------------------------------------------------------------------------------- +// manageTableSelection: +// ------------------------------------------------------------------------------- +- (void) manageTableSelection:(int)row +{ + //[((NSControl*) modifyButton) setEnabled:row>=0]; + [((NSControl*) deleteButton) setEnabled:row>=0]; +} + +- (id) getPanel +{ + return confPanel; +} +@end + +//Windows Delegator +@implementation IpConfiguratorCommander(PanelDelegator) +// ------------------------------------------------------------------------------- +// windowDidBecomeKey: +// ------------------------------------------------------------------------------- +- (void)windowDidBecomeKey:(NSNotification *)aNotification +{ + if(!cellElement){ + [NSApp endSheet:confPanel]; + return; + } + + bkIPArray = [cellElement getIp]; + workIPArray = [[NSMutableArray alloc] initWithArray:bkIPArray]; + [self loadValueFromCellIPClass]; +} + +// ------------------------------------------------------------------------------- +// windowWillClose: +// ------------------------------------------------------------------------------- +- (void)windowWillClose:(NSNotification *)aNotification +{ +} +@end + +//Table datasource +@implementation IpConfiguratorCommander (NSTableDataSource) +// ------------------------------------------------------------------------------- +// tableView: +// ------------------------------------------------------------------------------- +- (id) tableView:(NSTableView *) aTableView + objectValueForTableColumn:(NSTableColumn *) aTableColumn + row:(int) rowIndex +{ + + NSString *result = nil; + //NSMutableArray *cellArray = [cellElement getIp]; + CellIp *ipElement = (CellIp*)[workIPArray objectAtIndex:rowIndex]; + NSString *identifier = (NSString*)[aTableColumn identifier]; + switch([identifier intValue]){ + case 1: + result = [ipElement getCellIp]; + break; + + case 2: + result = [ipElement getCellComment]; + break; + + } + return result; +} + +// ------------------------------------------------------------------------------- +// numberOfRowsInTableView: +// ------------------------------------------------------------------------------- +- (int)numberOfRowsInTableView:(NSTableView *)aTableView +{ + return [workIPArray count]; +} + +- (void)tableView:(NSTableView *)aTable setObjectValue:(id)aData + forTableColumn:(NSTableColumn *)aCol row:(int)aRow +{ + NSLog([aData description]); + CellIp *ipElement = (CellIp*)[workIPArray objectAtIndex:aRow]; + switch([((NSNumber*)[aCol identifier]) intValue]) + { + case 1: + [ipElement setCellIp:[aData description]]; + break; + + case 2: + [ipElement setCellComment:[aData description]]; + break; + } +} +@end + +// Table delegator +@implementation IpConfiguratorCommander (TableDelegate) +// ------------------------------------------------------------------------------- +// selectionShouldChangeInTableView: +// ------------------------------------------------------------------------------- +- (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTable +{ + [self manageTableSelection:[aTable selectedRow]]; + return YES; +} + +// ------------------------------------------------------------------------------- +// tableView: +// ------------------------------------------------------------------------------- +- (BOOL)tableView:(NSTableView *)aTable shouldSelectRow:(int)aRow +{ + [self manageTableSelection:aRow]; + return YES; +} +@end diff --git a/src/platform/DARWIN/AFSPreference/LynkCreationController.h b/src/platform/DARWIN/AFSPreference/LynkCreationController.h new file mode 100644 index 000000000..8a38ef46e --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/LynkCreationController.h @@ -0,0 +1,23 @@ +// +// LynkCreationController.h +// OpenAFS +// +// Created by MacDeveloper on 03/06/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface LynkCreationController : NSObject { + IBOutlet NSPanel *lynkCreationSheet; + IBOutlet NSTextField *textFieldLinkDestPath; + IBOutlet NSTextField *textfieldLinkName; + int choiceResult; +} + +-(NSPanel*)getView; +- (IBAction) save:(id) sender; +- (IBAction) cancell:(id) sender; +- (IBAction) selectLinkDest:(id) sender; +@end diff --git a/src/platform/DARWIN/AFSPreference/LynkCreationController.m b/src/platform/DARWIN/AFSPreference/LynkCreationController.m new file mode 100644 index 000000000..308f61c90 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/LynkCreationController.m @@ -0,0 +1,44 @@ +// +// LynkCreationController.m +// OpenAFS +// +// Created by MacDeveloper on 03/06/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "LynkCreationController.h" + + +@implementation LynkCreationController + +-(NSPanel*)getView { + return lynkCreationSheet; +} + +- (IBAction) save:(id) sender { + [NSApp endSheet:lynkCreationSheet]; +} + +- (IBAction) cancell:(id) sender{ + [NSApp endSheet:lynkCreationSheet]; +} + +- (IBAction) selectLinkDest:(id) sender { + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + [openPanel setCanChooseFiles:NO]; + [openPanel setCanChooseDirectories:YES]; + [openPanel setAllowsMultipleSelection:NO]; + choiceResult = [openPanel runModalForTypes:nil]; + switch(choiceResult){ + case NSOKButton: + if([[openPanel filenames] count] == 1) { + [textFieldLinkDestPath setStringValue:[[openPanel filenames] objectAtIndex:0]]; + } + break; + + case NSCancelButton: + [textFieldLinkDestPath setStringValue:@""]; + break; + } +} +@end diff --git a/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Info.plist b/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Info.plist new file mode 100644 index 000000000..efe0c9edb --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleExecutable + MenuCracker + CFBundleGetInfoString + MenuCracker 1.4 ©2001-2006, james_007_bond@users.sourceforge.net + CFBundleIdentifier + net.sourceforge.menucracker2 + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + MenuCracker + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.4 + CFBundleSignature + ???? + CFBundleVersion + 6 + NSMenuExtraWidth + 0 + NSPrincipalClass + CPUExtra + + diff --git a/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/MacOS/MenuCracker b/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/MacOS/MenuCracker new file mode 100755 index 0000000000000000000000000000000000000000..c85b89cd7338b037442ba1d8e64629c4c72efb20 GIT binary patch literal 47328 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 QDS`i89l?-pU}=f}0(HH7%>V!Z literal 0 HcmV?d00001 diff --git a/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Resources/ReadMe.rtf b/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Resources/ReadMe.rtf new file mode 100644 index 000000000..d635393dd --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/MenuCracker.menu/Contents/Resources/ReadMe.rtf @@ -0,0 +1,51 @@ +{\rtf1\mac\ansicpg10000\cocoartf102 +{\fonttbl\f0\fswiss\fcharset77 Helvetica;\f1\fswiss\fcharset77 Helvetica-Bold;\f2\fnil\fcharset77 Monaco; +} +{\colortbl;\red255\green255\blue255;\red118\green15\blue80;\red0\green0\blue255;\red35\green110\blue37; +} +\margl1440\margr1440\vieww17140\viewh9140\viewkind0 +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\f0\fs24 \cf0 Welcome to +\f1\b MenuCracker +\f0\b0 .\ +\ +Menu cracker is a little tool to reenable the menu extra that Apple closed in Mac OS X 10.2 (code named Jaguar). Using MenuCracker you can use all your 10.1 Menu Extras unmodified.\ +\ +If you are an end user and you just want to make sure everything works as it was before 10.2:\ +\ +- first copy MenuCracker.menu anywhere in your home directory (Applications and Library/Bundles are relatively good choices)\ +\ +- Then double click on the installed version or drag it to the menubar.\ +\ +That's it.\ +\ +From then on all your third party menu extra will work.\ +\ +If you are a developer and your menu extra is controlled by an application there is some work for you to do. First add the MenuCracker binary to the resource folder of your application or preference pane. Then before calling +\f2\fs20 \CocoaLigature0 CoreMenuExtraAddMenuExtra() +\f0\fs24 \CocoaLigature1 for your menu extra execute the following code:\ +\ +\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\li1440\fi-1440\ql\qnatural + +\f2\fs20 \cf0 \CocoaLigature0 NSString *menuExtraPath = [[[\cf2 self\cf0 bundle] resourcePath] stringByAppendingPathComponent:@"MenuCracker.menu"];\ + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)menuExtraPath, kCFURLPOSIXPathStyle, \cf2 NO\cf0 );\ +\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\li960\fi-960\ql\qnatural +\cf0 \cf2 unsigned\cf0 \cf2 int\cf0 outExtra;\ +\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\li1440\fi-1440\ql\qnatural +\cf0 \ + CoreMenuExtraAddMenuExtra(url, 0, \cf3 0\cf0 , \cf2 nil\cf0 , \cf3 0\cf0 , &outExtra);\ +\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\li1920\fi-1920\ql\qnatural +\cf0 +\f0\fs24 \cf4 // Do not check the return value as it is always going to return an error +\f2\fs20 \cf0 \ +\pard\tx480\tx960\tx1440\tx1920\tx2400\tx2880\tx3360\tx3840\tx4320\tx4800\tx5280\tx5760\tx6240\tx6720\tx7200\tx7680\tx8160\tx8640\tx9120\tx9600\tx10080\tx10560\tx11040\tx11520\tx12000\tx12480\tx12960\tx13440\tx13920\tx14400\tx14880\tx15360\tx15840\tx16320\tx16800\tx17280\tx17760\tx18240\tx18720\tx19200\tx19680\tx20160\tx20640\tx21120\tx21600\tx22080\tx22560\tx23040\tx23520\tx24000\tx24480\tx24960\tx25440\tx25920\tx26400\tx26880\tx27360\tx27840\tx28320\tx28800\tx29280\tx29760\tx30240\tx30720\tx31200\tx31680\tx32160\tx32640\tx33120\tx33600\tx34080\tx34560\tx35040\tx35520\tx36000\tx36480\tx36960\tx37440\tx37920\tx38400\tx38880\tx39360\tx39840\tx40320\tx40800\tx41280\tx41760\tx42240\tx42720\tx43200\tx43680\tx44160\tx44640\tx45120\tx45600\tx46080\tx46560\tx47040\tx47520\tx48000\li1440\fi-1440\ql\qnatural +\cf0 CFRelease(url);\ +\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural + +\f0\fs24 \cf0 \CocoaLigature1 \ +That's it.\ +\ +You can find the latest version of MenuCracker at http://sourceforge.net/projects/menucracker.\ +\ +-- james_007_bond @ users.sourceforge.net} \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/NSString+search.h b/src/platform/DARWIN/AFSPreference/NSString+search.h new file mode 100644 index 000000000..4065eed14 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/NSString+search.h @@ -0,0 +1,28 @@ +// +// NSString+search.h +// AFSCommander +// +// Created by MacDeveloper on 18/03/08. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import + + + +/*! + @category NSString (search) + @abstract Implements some function for searching something into string + @discussion <#(comprehensive description)#> +*/ +@interface NSString (search) +/*! + @function estractTokenByDelimiter + @abstract Extract a string enclosed by two token + @discussion <#(description)#> + @param startToken - start token where the string to get begin + @param endTk - end token where the string to get begin + @result the found string + */ +-(NSString*) estractTokenByDelimiter:(NSString*)startToken endToken:(NSString*)endTk; +@end diff --git a/src/platform/DARWIN/AFSPreference/NSString+search.m b/src/platform/DARWIN/AFSPreference/NSString+search.m new file mode 100644 index 000000000..631a4bff4 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/NSString+search.m @@ -0,0 +1,26 @@ +// +// NSString+search.m +// AFSCommander +// +// Created by MacDeveloper on 18/03/08. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "NSString+search.h" + + +@implementation NSString(search) + +-(NSString*) estractTokenByDelimiter:(NSString*)startToken endToken:(NSString*)endTk { + NSString *result = nil; + NSScanner *strScan = [NSScanner scannerWithString:self]; + if(!endTk) return nil; + //make the CharacterSet for scanner + + if(startToken) [strScan scanUpToString:startToken intoString:&result]; + [strScan scanUpToString:endTk intoString:&result]; + if(startToken) result = [result substringFromIndex:[startToken length]]; + return result; +} + +@end diff --git a/src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/bisegni.mode1 b/src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/bisegni.mode1 new file mode 100644 index 000000000..1ab5b1a87 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/bisegni.mode1 @@ -0,0 +1,1439 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXRunSessionModule + Name + Run Log + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1 + FavBarConfig + + PBXProjectModuleGUID + 3213E8430BF3E63C0010360B + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1 + MajorVersion + 31 + MinorVersion + 1 + Name + Default + Notifications + + OpenEditors + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-target-popup + active-buildstyle-popup + action + NSToolbarFlexibleSpaceItem + buildOrClean + build-and-runOrDebug + com.apple.ide.PBXToolbarStopButton + get-info + toggle-editor + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 22 + 22 + 309 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + SCMStatusColumn + TargetStatusColumn + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 089C166AFE841209C02AAC07 + 08FB77AFFE84173DC02AAC07 + 3212AA7F0C27AC2800A0689C + 3219259A0C339C1F00B55E86 + 494BD47A0C43EDD400DB0A3A + 4941F62F0C49377000B29A73 + 325313A10C4515A700FAF2F3 + 32DBCFA10370C40200C91783 + 089C167CFE841241C02AAC07 + 32B0AFB40C016E6900272348 + 19C28FB8FE9D52D311CA2CBB + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 48 + 47 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 41}, {353, 1064}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {370, 1082}} + GroupTreeTableConfiguration + + SCMStatusColumn + 22 + TargetStatusColumn + 22 + MainColumn + 309 + + RubberWindowFrame + 53 55 1264 1123 0 0 1920 1178 + + Module + PBXSmartGroupTreeModule + Proportion + 370pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + Localizable.strings + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + Localizable.strings + _historyCapacity + 0 + bookmark + 322F65490C9AF64400B937CC + history + + 323DFED60C0B2C9C000350E8 + 32C4A9190C268A03009280A0 + 32C4AB110C26D6D6009280A0 + 3259409D0C26F85400040E5A + 3212AB240C27C12800A0689C + 322381E80C3273AE00380547 + 3223832D0C32A51B00380547 + 322383FA0C32AF4200380547 + 321926E20C33EC0700B55E86 + 322884390C3E477C00E778CC + 3228845D0C3E48AA00E778CC + 322884E40C3E6F4400E778CC + 325311BA0C44F3B500FAF2F3 + 325311BB0C44F3B500FAF2F3 + 325311BC0C44F3B500FAF2F3 + 325311BD0C44F3B500FAF2F3 + 325311BE0C44F3B500FAF2F3 + 325312CE0C45140300FAF2F3 + 325312CF0C45140300FAF2F3 + 325313890C45154E00FAF2F3 + 3279B9450C4519AA008FE3FA + 3279B9BE0C4524D3008FE3FA + 3279BA480C452A61008FE3FA + 3279BA9C0C452DFB008FE3FA + 3279BAA00C4530C5008FE3FA + 32D45E420C4F4FE500A1012D + 32D45E450C4F4FE500A1012D + 32922CD00C4F882800A95641 + 32922CD10C4F882800A95641 + 32922CD20C4F882800A95641 + 32922D4D0C4F8EA400A95641 + 32922D6D0C4FA65A00A95641 + 32922D840C4FA75900A95641 + 32922D970C4FB32500A95641 + 32F2DD100C54870900655773 + 32F2DD110C54870900655773 + 3241DEDF0C97E0E1000AEF82 + 322F653F0C9AF5BC00B937CC + 322F65400C9AF5BC00B937CC + 322384170C32C2CC00380547 + + prevStack + + 3213E83B0BF3E63C0010360B + 3213E83C0BF3E63C0010360B + 3213E83D0BF3E63C0010360B + 323DFEA80C0B1CB3000350E8 + 32C4A8770C268649009280A0 + 32C4A88B0C268717009280A0 + 32C4A88C0C268717009280A0 + 32C4A8FE0C2689B2009280A0 + 32C4A8FF0C2689B2009280A0 + 32C4A9010C2689B2009280A0 + 32C4A9750C268F07009280A0 + 32C4A9780C268F07009280A0 + 325940A70C26F85400040E5A + 3212AA740C27AB8700A0689C + 3212AB2B0C27C12800A0689C + 322381EC0C3273AE00380547 + 322381ED0C3273AE00380547 + 322381EE0C3273AE00380547 + 322382250C3296C600380547 + 322383320C32A51B00380547 + 322383FD0C32AF4200380547 + 3223841E0C32C2CC00380547 + 321925C90C33A85700B55E86 + 321925CB0C33A85700B55E86 + 3228840D0C3E45E700E778CC + 3228842F0C3E469000E778CC + 325311CC0C44F3B500FAF2F3 + 325311DD0C44F56A00FAF2F3 + 325312050C44F76800FAF2F3 + 325312D50C45140300FAF2F3 + 325312D60C45140300FAF2F3 + 325312D70C45140300FAF2F3 + 3279B9260C45194F008FE3FA + 3279B9490C4519AA008FE3FA + 3279BA9E0C452DFB008FE3FA + 32D45E4C0C4F4FE500A1012D + 32D45E4D0C4F4FE500A1012D + 32D45E4E0C4F4FE500A1012D + 32D45E530C4F4FE500A1012D + 32F2DD140C54870900655773 + 322F65410C9AF5BC00B937CC + 322F65420C9AF5BC00B937CC + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {889, 872}} + RubberWindowFrame + 53 55 1264 1123 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 872pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 877}, {889, 205}} + RubberWindowFrame + 53 55 1264 1123 0 0 1920 1178 + + Module + XCDetailModule + Proportion + 205pt + + + Proportion + 889pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 322F65380C9AF59500B937CC + 1CE0B1FE06471DED0097A5F4 + 322F65390C9AF59500B937CC + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.short + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 323DFE5E0C0B173F000350E8 + /Users/bisegni/svnrepo/AFSCommander/AFSCommander.xcodeproj + + WindowString + 53 55 1264 1123 0 0 1920 1178 + WindowTools + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1307, 396}} + RubberWindowFrame + 342 266 1307 912 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 396pt + + + ContentConfiguration + + PBXBuildLogShowsTranscriptDefaultKey + {{0, 5}, {1307, 465}} + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 401}, {1307, 470}} + RubberWindowFrame + 342 266 1307 912 0 0 1920 1178 + + Module + PBXBuildResultsModule + Proportion + 470pt + + + Proportion + 871pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 323DFE5E0C0B173F000350E8 + 322F65440C9AF5BC00B937CC + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.build + WindowString + 342 266 1307 912 0 0 1920 1178 + WindowToolGUID + 323DFE5E0C0B173F000350E8 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {150, 432}} + {{150, 0}, {921, 432}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1071, 432}} + {{0, 432}, {1071, 459}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {1071, 891}} + RubberWindowFrame + 519 246 1071 932 0 0 1920 1178 + + Module + PBXDebugSessionModule + Proportion + 891pt + + + Proportion + 891pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 322884AF0C3E4B1600E778CC + 1C162984064C10D400B95A72 + 322884B00C3E4B1600E778CC + 322884B10C3E4B1600E778CC + 322884B20C3E4B1600E778CC + 322884B30C3E4B1600E778CC + 322884B40C3E4B1600E778CC + 322884B50C3E4B1600E778CC + + ToolbarConfiguration + xcode.toolbar.config.debug + WindowString + 519 246 1071 932 0 0 1920 1178 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {781, 212}} + RubberWindowFrame + 62 685 781 470 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 212pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 217}, {781, 212}} + RubberWindowFrame + 62 685 781 470 0 0 1920 1178 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 429pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 321926770C33DF7E00B55E86 + 321926780C33DF7E00B55E86 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 62 685 781 470 0 0 1920 1178 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {578, 500}} + RubberWindowFrame + 1342 637 578 541 0 0 1920 1178 + + Module + PBXDebugCLIModule + Proportion + 500pt + + + Proportion + 500pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 325A0B160C291AFC007B198B + 321926950C33E0EE00B55E86 + 1C78EAAC065D492600B07095 + + WindowString + 1342 637 578 541 0 0 1920 1178 + WindowToolGUID + 325A0B160C291AFC007B198B + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.run + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + LauncherConfigVersion + 3 + PBXProjectModuleGUID + 1CD0528B0623707200166675 + PBXProjectModuleLabel + Run + Runner + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {493, 167}} + {{0, 176}, {493, 267}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {405, 443}} + {{414, 0}, {514, 443}} + + + + + GeometryConfiguration + + Frame + {{0, 0}, {530, 159}} + RubberWindowFrame + 1389 978 530 200 0 0 1920 1178 + + Module + PBXRunSessionModule + Proportion + 159pt + + + Proportion + 159pt + + + Name + Run Log + ServiceClasses + + PBXRunSessionModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2B3069F1EA900FABCE6 + 32B3AF7C0C2A4C9100CB8686 + 1CD0528B0623707200166675 + 32B3AF7D0C2A4C9100CB8686 + + ToolbarConfiguration + xcode.toolbar.config.run + WindowString + 1389 978 530 200 0 0 1920 1178 + WindowToolGUID + 1C0AD2B3069F1EA900FABCE6 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.scm + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {998, 0}} + RubberWindowFrame + 87 268 998 887 0 0 1920 1178 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM Results + + GeometryConfiguration + + Frame + {{0, 5}, {998, 841}} + RubberWindowFrame + 87 268 998 887 0 0 1920 1178 + + Module + PBXCVSModule + Proportion + 841pt + + + Proportion + 846pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + + TableOfContents + + 3259408D0C26F72A00040E5A + 327E2EEC0C280DA1007E8712 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 87 268 998 887 0 0 1920 1178 + WindowToolGUID + 3259408D0C26F72A00040E5A + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.breakpoints + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 226 582 744 409 0 0 1920 1178 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 226 582 744 409 0 0 1920 1178 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 2 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + + TableOfContents + + 32E9C9760C2BF29A0028F051 + 32E9C9770C2BF29A0028F051 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpoints + WindowString + 226 582 744 409 0 0 1920 1178 + WindowToolGUID + 32E9C9760C2BF29A0028F051 + WindowToolIsVisible + + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimator + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.classBrowser + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + OptionsSetName + Hierarchy, project classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {378, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 332}} + MembersFrame + {{0, 101}, {378, 231}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 101 + PBXMemberBookColumnIdentifier + 22 + + RubberWindowFrame + 547 674 630 352 0 0 1920 1178 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 325940910C26F7D700040E5A + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 547 674 630 352 0 0 1920 1178 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + + + + + diff --git a/src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/project.pbxproj b/src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/project.pbxproj new file mode 100644 index 000000000..dc0e301ed --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/OpenAFS.xcodeproj/project.pbxproj @@ -0,0 +1,1254 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + 3213E9410C2ABFD200D3D2F6 /* AuthUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 3213E93F0C2ABFD200D3D2F6 /* AuthUtil.h */; }; + 3213E9420C2ABFD200D3D2F6 /* AuthUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */; }; + 3219259D0C339DAE00B55E86 /* TokenCredentialController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3219259C0C339DAE00B55E86 /* TokenCredentialController.m */; }; + 3223836C0C32A96F00380547 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3223836A0C32A96F00380547 /* Localizable.strings */; }; + 322884030C3E45C800E778CC /* InfoController.h in Headers */ = {isa = PBXBuildFile; fileRef = 322884010C3E45C800E778CC /* InfoController.h */; }; + 322884040C3E45C800E778CC /* InfoController.m in Sources */ = {isa = PBXBuildFile; fileRef = 322884020C3E45C800E778CC /* InfoController.m */; }; + 322884050C3E45C800E778CC /* InfoController.m in Sources */ = {isa = PBXBuildFile; fileRef = 322884020C3E45C800E778CC /* InfoController.m */; }; + 322B90450C2F0A2D0068F99A /* start_afs.sh in Resources */ = {isa = PBXBuildFile; fileRef = 322B90430C2F0A2D0068F99A /* start_afs.sh */; }; + 322B90460C2F0A2D0068F99A /* stop_afs.sh in Resources */ = {isa = PBXBuildFile; fileRef = 322B90440C2F0A2D0068F99A /* stop_afs.sh */; }; + 322CEF600C211D220060D66D /* DBCellElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF5F0C211D220060D66D /* DBCellElement.m */; }; + 322CEF6E0C211DCC0060D66D /* CellIp.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF6D0C211DCC0060D66D /* CellIp.m */; }; + 324D67FD0DA13194007E1561 /* OpenAFSPreference.xib in Resources */ = {isa = PBXBuildFile; fileRef = 324D67FB0DA13194007E1561 /* OpenAFSPreference.xib */; }; + 324D683D0DA133A3007E1561 /* IpPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 324D683B0DA133A3007E1561 /* IpPanel.xib */; }; + 324D684A0DA133CF007E1561 /* CredentialPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 324D68480DA133CF007E1561 /* CredentialPanel.xib */; }; + 325311AB0C44F38200FAF2F3 /* AFSPropertyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */; }; + 325311AF0C44F38D00FAF2F3 /* CellIp.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF6D0C211DCC0060D66D /* CellIp.m */; }; + 325311B00C44F38D00FAF2F3 /* DBCellElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF5F0C211D220060D66D /* DBCellElement.m */; }; + 325311B10C44F39200FAF2F3 /* TaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 327756260C3053A100C15D11 /* TaskUtil.m */; }; + 325311B20C44F39300FAF2F3 /* AuthUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */; }; + 325311B30C44F39400FAF2F3 /* FileUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3273088C0C2A9B05008C322B /* FileUtil.m */; }; + 325311D00C44F4B100FAF2F3 /* licenza.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 325311CF0C44F4B100FAF2F3 /* licenza.rtf */; }; + 325312190C44F7BD00FAF2F3 /* AFSMenuExtraView.m in Sources */ = {isa = PBXBuildFile; fileRef = 325312180C44F7BD00FAF2F3 /* AFSMenuExtraView.m */; }; + 325313520C45153400FAF2F3 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327308D20C2AA364008C322B /* SecurityFoundation.framework */; }; + 325313550C45153500FAF2F3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327309620C2AB433008C322B /* Security.framework */; }; + 3253138D0C45157A00FAF2F3 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 325313B10C4516A900FAF2F3 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 325313B00C4516A900FAF2F3 /* Info.plist */; }; + 3273088D0C2A9B05008C322B /* FileUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 3273088B0C2A9B05008C322B /* FileUtil.h */; }; + 3273088E0C2A9B05008C322B /* FileUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3273088C0C2A9B05008C322B /* FileUtil.m */; }; + 327308C30C2AA2E1008C322B /* FileUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3273088C0C2A9B05008C322B /* FileUtil.m */; }; + 327308D70C2AA364008C322B /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327308D20C2AA364008C322B /* SecurityFoundation.framework */; }; + 327308D80C2AA369008C322B /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327308D20C2AA364008C322B /* SecurityFoundation.framework */; }; + 327309970C2AB433008C322B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327309620C2AB433008C322B /* Security.framework */; }; + 327309980C2AB434008C322B /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327309620C2AB433008C322B /* Security.framework */; }; + 327756270C3053A100C15D11 /* TaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 327756260C3053A100C15D11 /* TaskUtil.m */; }; + 327756280C3053A100C15D11 /* TaskUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 327756250C3053A100C15D11 /* TaskUtil.h */; }; + 327756290C3053A100C15D11 /* TaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 327756260C3053A100C15D11 /* TaskUtil.m */; }; + 32B0AFDF0C01729400272348 /* AFSPropertyManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 32B0AFDD0C01729400272348 /* AFSPropertyManager.h */; }; + 32B0AFE00C01729400272348 /* AFSPropertyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */; }; + 32B565740D8FAF62005255F2 /* NSString+search.h in Headers */ = {isa = PBXBuildFile; fileRef = 32B565720D8FAF62005255F2 /* NSString+search.h */; }; + 32B565750D8FAF62005255F2 /* NSString+search.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B565730D8FAF62005255F2 /* NSString+search.m */; }; + 32B565760D8FAF62005255F2 /* NSString+search.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B565730D8FAF62005255F2 /* NSString+search.m */; }; + 32C4A9580C268D9B009280A0 /* IpConfiguratorCommander.m in Sources */ = {isa = PBXBuildFile; fileRef = 32C4A9570C268D9B009280A0 /* IpConfiguratorCommander.m */; }; + 32C4A9B80C26A0FA009280A0 /* IpConfiguratorCommander.m in Sources */ = {isa = PBXBuildFile; fileRef = 32C4A9570C268D9B009280A0 /* IpConfiguratorCommander.m */; }; + 32C4A9B90C26A0FB009280A0 /* IpConfiguratorCommander.h in Headers */ = {isa = PBXBuildFile; fileRef = 32C4A9560C268D9B009280A0 /* IpConfiguratorCommander.h */; }; + 32CF013F0C203C5600A8DC58 /* TestLib.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CFFEFD0C20316B00A8DC58 /* TestLib.m */; }; + 32CF01460C203CA800A8DC58 /* AFSPropertyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */; }; + 32CF014C0C203CBD00A8DC58 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 32D45E070C4B4D9C00A1012D /* afshlp in Resources */ = {isa = PBXBuildFile; fileRef = 49683EE40C3446380093C7C8 /* afshlp */; }; + 32DE818C0DF573200069A05C /* LynkCreationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 32DE818A0DF573200069A05C /* LynkCreationController.h */; }; + 32DE818D0DF573200069A05C /* LynkCreationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DE818B0DF573200069A05C /* LynkCreationController.m */; }; + 32DE81BD0DF57BDA0069A05C /* SymLinkEdit.xib in Resources */ = {isa = PBXBuildFile; fileRef = 32DE81BC0DF57BDA0069A05C /* SymLinkEdit.xib */; }; + 492AFA860C51301D00AEDC93 /* TokenCredentialController.h in Headers */ = {isa = PBXBuildFile; fileRef = 3219259B0C339DAE00B55E86 /* TokenCredentialController.h */; }; + 492AFA870C51301E00AEDC93 /* TokenCredentialController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3219259C0C339DAE00B55E86 /* TokenCredentialController.m */; }; + 492AFB280C51483600AEDC93 /* CredentialWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 492AFB270C51483600AEDC93 /* CredentialWindow.nib */; }; + 4934D4170DC38958000511D2 /* PListManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 498DCB420DC2240B00D143C8 /* PListManager.m */; }; + 493564E80CE711F300699A24 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 493564E70CE711F300699A24 /* Carbon.framework */; }; + 4940075B0CE62EB500F40D0A /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4940075A0CE62EB500F40D0A /* CoreServices.framework */; }; + 4941F4C00C491D2D00B29A73 /* TokenCredentialController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3219259C0C339DAE00B55E86 /* TokenCredentialController.m */; }; + 4941F5100C4929C000B29A73 /* AFSMenuCredentialContoller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4941F50F0C4929C000B29A73 /* AFSMenuCredentialContoller.m */; }; + 4941F6320C49379000B29A73 /* CredentialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4941F6310C49379000B29A73 /* CredentialWindowController.m */; }; + 494435170DC35D4C00C7A333 /* LoginTimeDaemon in Resources */ = {isa = PBXBuildFile; fileRef = 4998A6860DC33BEC00146652 /* LoginTimeDaemon */; }; + 494BD4880C43EEA400DB0A3A /* SystemUIPlugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 494BD4870C43EEA400DB0A3A /* SystemUIPlugin.framework */; }; + 494BD48C0C43EEC300DB0A3A /* AFSMenuExtra.m in Sources */ = {isa = PBXBuildFile; fileRef = 494BD48B0C43EEC300DB0A3A /* AFSMenuExtra.m */; }; + 494C75110C4605C000D3A2D2 /* AFSMenuExtra.menu in Resources */ = {isa = PBXBuildFile; fileRef = 494C74DE0C46052800D3A2D2 /* AFSMenuExtra.menu */; }; + 49575BB50C53CBDB00B3BC32 /* hasToken.png in Resources */ = {isa = PBXBuildFile; fileRef = 49575BB30C53CBDB00B3BC32 /* hasToken.png */; }; + 49575BB60C53CBDB00B3BC32 /* noToken.png in Resources */ = {isa = PBXBuildFile; fileRef = 49575BB40C53CBDB00B3BC32 /* noToken.png */; }; + 495B04400D219A2900F1E328 /* ViewUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 495B043E0D219A2900F1E328 /* ViewUtility.h */; }; + 495B04410D219A2900F1E328 /* ViewUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 495B043F0D219A2900F1E328 /* ViewUtility.m */; }; + 495B04420D219A2900F1E328 /* ViewUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 495B043F0D219A2900F1E328 /* ViewUtility.m */; }; + 495C39470D81EA3C003426FC /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 495C39460D81EA3C003426FC /* Kerberos.framework */; }; + 495C39480D81EA3C003426FC /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 495C39460D81EA3C003426FC /* Kerberos.framework */; }; + 495C39490D81EA3C003426FC /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 495C39460D81EA3C003426FC /* Kerberos.framework */; }; + 495C39CC0D81F742003426FC /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 495C39460D81EA3C003426FC /* Kerberos.framework */; }; + 49683EEC0C3446600093C7C8 /* afshlp.m in Sources */ = {isa = PBXBuildFile; fileRef = 49683EEB0C3446600093C7C8 /* afshlp.m */; }; + 49683F3D0C344CD40093C7C8 /* AFSPropertyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */; }; + 49683F3E0C344CD50093C7C8 /* DBCellElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF5F0C211D220060D66D /* DBCellElement.m */; }; + 49683F3F0C344CD70093C7C8 /* CellIp.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF6D0C211DCC0060D66D /* CellIp.m */; }; + 49683F400C344CD80093C7C8 /* IpConfiguratorCommander.m in Sources */ = {isa = PBXBuildFile; fileRef = 32C4A9570C268D9B009280A0 /* IpConfiguratorCommander.m */; }; + 49683F410C344CD90093C7C8 /* FileUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3273088C0C2A9B05008C322B /* FileUtil.m */; }; + 49683F420C344CDA0093C7C8 /* AuthUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */; }; + 49683F430C344CDB0093C7C8 /* TaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 327756260C3053A100C15D11 /* TaskUtil.m */; }; + 49683F440C344CE20093C7C8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327308D20C2AA364008C322B /* SecurityFoundation.framework */; }; + 49683F470C344CE40093C7C8 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327309620C2AB433008C322B /* Security.framework */; }; + 49683F990C3452870093C7C8 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 4968CBEB0C51EA01001F5CC7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 089C1672FE841209C02AAC07 /* Foundation.framework */; }; + 498DCB430DC2240B00D143C8 /* PListManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 498DCB410DC2240B00D143C8 /* PListManager.h */; }; + 498DCB440DC2240B00D143C8 /* PListManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 498DCB420DC2240B00D143C8 /* PListManager.m */; }; + 499716930C23E36E001339E3 /* CellIp.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF6D0C211DCC0060D66D /* CellIp.m */; }; + 499716940C23E36F001339E3 /* CellIp.h in Headers */ = {isa = PBXBuildFile; fileRef = 322CEF6C0C211DCC0060D66D /* CellIp.h */; }; + 499716950C23E370001339E3 /* DBCellElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF5F0C211D220060D66D /* DBCellElement.m */; }; + 499716960C23E370001339E3 /* DBCellElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 322CEF5E0C211D220060D66D /* DBCellElement.h */; }; + 4998A6A40DC33C9300146652 /* afsltd.m in Sources */ = {isa = PBXBuildFile; fileRef = 4998A6A30DC33C9300146652 /* afsltd.m */; }; + 4998A6A50DC33CD800146652 /* AFSPropertyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */; }; + 4998A6A60DC33CDB00146652 /* DBCellElement.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF5F0C211D220060D66D /* DBCellElement.m */; }; + 4998A6A70DC33CDB00146652 /* CellIp.m in Sources */ = {isa = PBXBuildFile; fileRef = 322CEF6D0C211DCC0060D66D /* CellIp.m */; }; + 4998A6A80DC33CE600146652 /* FileUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3273088C0C2A9B05008C322B /* FileUtil.m */; }; + 4998A6A90DC33CE700146652 /* AuthUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */; }; + 4998A6AA0DC33CE800146652 /* TaskUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 327756260C3053A100C15D11 /* TaskUtil.m */; }; + 4998A6AB0DC33CE900146652 /* ViewUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 495B043F0D219A2900F1E328 /* ViewUtility.m */; }; + 4998A6AC0DC33CEA00146652 /* NSString+search.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B565730D8FAF62005255F2 /* NSString+search.m */; }; + 4998A6AD0DC33CEB00146652 /* PListManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 498DCB420DC2240B00D143C8 /* PListManager.m */; }; + 4998A6F00DC3415600146652 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327308D20C2AA364008C322B /* SecurityFoundation.framework */; }; + 4998A6F10DC3415700146652 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 327309620C2AB433008C322B /* Security.framework */; }; + 4998A6F20DC3415800146652 /* Kerberos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 495C39460D81EA3C003426FC /* Kerberos.framework */; }; + 4998A6F30DC3415900146652 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 493564E70CE711F300699A24 /* Carbon.framework */; }; + 4998A6F40DC3415900146652 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4940075A0CE62EB500F40D0A /* CoreServices.framework */; }; + 4998A6F50DC3415A00146652 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 49AF1F480C25B52A006A046E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 49AF1F470C25B52A006A046E /* InfoPlist.strings */; }; + 49B766450DCA47A50014A80F /* DialogUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 49B766430DCA47A50014A80F /* DialogUtility.h */; }; + 49B766460DCA47A50014A80F /* DialogUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 49B766440DCA47A50014A80F /* DialogUtility.m */; }; + 49E05CAD0C2674DA002AAEF2 /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8D202CF70486D31800D8A456 /* Info.plist */; }; + 49E43BA60C47D53F00084436 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3223836A0C32A96F00380547 /* Localizable.strings */; }; + 49E43BE70C47D9EE00084436 /* global.h in Headers */ = {isa = PBXBuildFile; fileRef = 49E43BE60C47D9EE00084436 /* global.h */; }; + 49E43C730C47E0EA00084436 /* start_afs.sh in Resources */ = {isa = PBXBuildFile; fileRef = 322B90430C2F0A2D0068F99A /* start_afs.sh */; }; + 49E43C740C47E0EC00084436 /* stop_afs.sh in Resources */ = {isa = PBXBuildFile; fileRef = 322B90440C2F0A2D0068F99A /* stop_afs.sh */; }; + 49E43D2E0C480B8200084436 /* afshlp in Resources */ = {isa = PBXBuildFile; fileRef = 49683EE40C3446380093C7C8 /* afshlp */; }; + 49FFE7D20C2AED7200DF83CF /* AuthUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */; }; + 8D202CEA0486D31800D8A456 /* AFSCommander_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 32DBCFA20370C41700C91783 /* AFSCommander_Prefix.pch */; }; + 8D202CEB0486D31800D8A456 /* AFSCommanderPref.h in Headers */ = {isa = PBXBuildFile; fileRef = F506C03C013D9D7901CA16C8 /* AFSCommanderPref.h */; }; + 8D202CF10486D31800D8A456 /* AFSCommanderPref.m in Sources */ = {isa = PBXBuildFile; fileRef = F506C03D013D9D7901CA16C8 /* AFSCommanderPref.m */; }; + 8D202CF30486D31800D8A456 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; + 8D202CF40486D31800D8A456 /* PreferencePanes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F506C035013D953901CA16C8 /* PreferencePanes.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3279B9800C451A63008FE3FA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 089C1669FE841209C02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 494BD4680C43ED0C00DB0A3A; + remoteInfo = AFSMenuExtra; + }; + 494435680DC35D6F00C7A333 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 089C1669FE841209C02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4998A6850DC33BEC00146652; + remoteInfo = LoginTimeDaemon; + }; + 49575C270C53CD9A00B3BC32 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 089C1669FE841209C02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 49683EE30C3446380093C7C8; + remoteInfo = afshlp; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 494D72C90C350BC400B1FD21 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = MenuCracker.menu; + dstSubfolderSpec = 7; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; + 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 3213E93F0C2ABFD200D3D2F6 /* AuthUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuthUtil.h; sourceTree = ""; }; + 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AuthUtil.m; sourceTree = ""; }; + 3219259B0C339DAE00B55E86 /* TokenCredentialController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TokenCredentialController.h; sourceTree = ""; }; + 3219259C0C339DAE00B55E86 /* TokenCredentialController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TokenCredentialController.m; sourceTree = ""; }; + 3223836B0C32A96F00380547 /* English */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = English; path = English.lproj/Localizable.strings; sourceTree = ""; }; + 322884010C3E45C800E778CC /* InfoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoController.h; sourceTree = ""; }; + 322884020C3E45C800E778CC /* InfoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InfoController.m; sourceTree = ""; }; + 322B90430C2F0A2D0068F99A /* start_afs.sh */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = start_afs.sh; sourceTree = ""; }; + 322B90440C2F0A2D0068F99A /* stop_afs.sh */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.script.sh; path = stop_afs.sh; sourceTree = ""; }; + 322CEF5E0C211D220060D66D /* DBCellElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBCellElement.h; sourceTree = ""; }; + 322CEF5F0C211D220060D66D /* DBCellElement.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DBCellElement.m; sourceTree = ""; }; + 322CEF6C0C211DCC0060D66D /* CellIp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CellIp.h; sourceTree = ""; }; + 322CEF6D0C211DCC0060D66D /* CellIp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CellIp.m; sourceTree = ""; }; + 324D67FC0DA13194007E1561 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/OpenAFSPreference.xib; sourceTree = ""; }; + 324D683C0DA133A3007E1561 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/IpPanel.xib; sourceTree = ""; }; + 324D68490DA133CF007E1561 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/CredentialPanel.xib; sourceTree = ""; }; + 325311CF0C44F4B100FAF2F3 /* licenza.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = licenza.rtf; sourceTree = ""; }; + 325312170C44F7BD00FAF2F3 /* AFSMenuExtraView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSMenuExtraView.h; sourceTree = ""; }; + 325312180C44F7BD00FAF2F3 /* AFSMenuExtraView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSMenuExtraView.m; sourceTree = ""; }; + 325313B00C4516A900FAF2F3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; name = Info.plist; path = AfsMenuExtraResource/Info.plist; sourceTree = ""; }; + 3273088B0C2A9B05008C322B /* FileUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileUtil.h; sourceTree = ""; }; + 3273088C0C2A9B05008C322B /* FileUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileUtil.m; sourceTree = ""; }; + 327308D20C2AA364008C322B /* SecurityFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityFoundation.framework; path = /System/Library/Frameworks/SecurityFoundation.framework; sourceTree = ""; }; + 327309620C2AB433008C322B /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; + 327756250C3053A100C15D11 /* TaskUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskUtil.h; sourceTree = ""; }; + 327756260C3053A100C15D11 /* TaskUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskUtil.m; sourceTree = ""; }; + 32B0AFDD0C01729400272348 /* AFSPropertyManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSPropertyManager.h; sourceTree = ""; }; + 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSPropertyManager.m; sourceTree = ""; }; + 32B565720D8FAF62005255F2 /* NSString+search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+search.h"; sourceTree = ""; }; + 32B565730D8FAF62005255F2 /* NSString+search.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+search.m"; sourceTree = ""; }; + 32C4A9560C268D9B009280A0 /* IpConfiguratorCommander.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IpConfiguratorCommander.h; sourceTree = ""; }; + 32C4A9570C268D9B009280A0 /* IpConfiguratorCommander.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IpConfiguratorCommander.m; sourceTree = ""; }; + 32CF01390C203C1800A8DC58 /* Test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Test; sourceTree = BUILT_PRODUCTS_DIR; }; + 32CFFEFD0C20316B00A8DC58 /* TestLib.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestLib.m; sourceTree = ""; }; + 32DBCFA20370C41700C91783 /* AFSCommander_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSCommander_Prefix.pch; sourceTree = ""; }; + 32DE817D0DF571630069A05C /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/SymLinkEdit.xib; sourceTree = ""; }; + 32DE818A0DF573200069A05C /* LynkCreationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LynkCreationController.h; sourceTree = ""; }; + 32DE818B0DF573200069A05C /* LynkCreationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LynkCreationController.m; sourceTree = ""; }; + 492AFB270C51483600AEDC93 /* CredentialWindow.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = CredentialWindow.nib; path = AfsMenuExtraResource/CredentialWindow.nib; sourceTree = ""; }; + 493564E70CE711F300699A24 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 4940075A0CE62EB500F40D0A /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; + 4941F50E0C4929C000B29A73 /* AFSMenuCredentialContoller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSMenuCredentialContoller.h; sourceTree = ""; }; + 4941F50F0C4929C000B29A73 /* AFSMenuCredentialContoller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSMenuCredentialContoller.m; sourceTree = ""; }; + 4941F6300C49379000B29A73 /* CredentialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CredentialWindowController.h; sourceTree = ""; }; + 4941F6310C49379000B29A73 /* CredentialWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CredentialWindowController.m; sourceTree = ""; }; + 494BD47B0C43EDF900DB0A3A /* SystemUIPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SystemUIPlugin.h; sourceTree = ""; }; + 494BD4870C43EEA400DB0A3A /* SystemUIPlugin.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemUIPlugin.framework; path = /System/Library/PrivateFrameworks/SystemUIPlugin.framework; sourceTree = ""; }; + 494BD48A0C43EEC300DB0A3A /* AFSMenuExtra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSMenuExtra.h; sourceTree = ""; }; + 494BD48B0C43EEC300DB0A3A /* AFSMenuExtra.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSMenuExtra.m; sourceTree = ""; }; + 494C74DE0C46052800D3A2D2 /* AFSMenuExtra.menu */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AFSMenuExtra.menu; sourceTree = BUILT_PRODUCTS_DIR; }; + 49575BB30C53CBDB00B3BC32 /* hasToken.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = hasToken.png; sourceTree = ""; }; + 49575BB40C53CBDB00B3BC32 /* noToken.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = noToken.png; sourceTree = ""; }; + 495B043E0D219A2900F1E328 /* ViewUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewUtility.h; sourceTree = ""; }; + 495B043F0D219A2900F1E328 /* ViewUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewUtility.m; sourceTree = ""; }; + 495C39460D81EA3C003426FC /* Kerberos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kerberos.framework; path = /System/Library/Frameworks/Kerberos.framework; sourceTree = ""; }; + 49683EE40C3446380093C7C8 /* afshlp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = afshlp; sourceTree = BUILT_PRODUCTS_DIR; }; + 49683EEB0C3446600093C7C8 /* afshlp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = afshlp.m; sourceTree = ""; }; + 498DCB410DC2240B00D143C8 /* PListManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PListManager.h; sourceTree = ""; }; + 498DCB420DC2240B00D143C8 /* PListManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PListManager.m; sourceTree = ""; }; + 4998A6860DC33BEC00146652 /* LoginTimeDaemon */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = LoginTimeDaemon; sourceTree = BUILT_PRODUCTS_DIR; }; + 4998A6A30DC33C9300146652 /* afsltd.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = afsltd.m; sourceTree = ""; }; + 49B766430DCA47A50014A80F /* DialogUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DialogUtility.h; sourceTree = ""; }; + 49B766440DCA47A50014A80F /* DialogUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DialogUtility.m; sourceTree = ""; }; + 49E43BE60C47D9EE00084436 /* global.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = global.h; sourceTree = ""; }; + 8D202CF70486D31800D8A456 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8D202CF80486D31800D8A456 /* OpenAFS.prefPane */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenAFS.prefPane; sourceTree = BUILT_PRODUCTS_DIR; }; + F506C035013D953901CA16C8 /* PreferencePanes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PreferencePanes.framework; path = /System/Library/Frameworks/PreferencePanes.framework; sourceTree = ""; }; + F506C03C013D9D7901CA16C8 /* AFSCommanderPref.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AFSCommanderPref.h; sourceTree = ""; }; + F506C03D013D9D7901CA16C8 /* AFSCommanderPref.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AFSCommanderPref.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 32CF01370C203C1800A8DC58 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 32CF014C0C203CBD00A8DC58 /* Cocoa.framework in Frameworks */, + 327308D80C2AA369008C322B /* SecurityFoundation.framework in Frameworks */, + 327309980C2AB434008C322B /* Security.framework in Frameworks */, + 495C39490D81EA3C003426FC /* Kerberos.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 494BD4670C43ED0C00DB0A3A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 494BD4880C43EEA400DB0A3A /* SystemUIPlugin.framework in Frameworks */, + 325313520C45153400FAF2F3 /* SecurityFoundation.framework in Frameworks */, + 325313550C45153500FAF2F3 /* Security.framework in Frameworks */, + 3253138D0C45157A00FAF2F3 /* Cocoa.framework in Frameworks */, + 495C39480D81EA3C003426FC /* Kerberos.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 49683EE20C3446380093C7C8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 49683F440C344CE20093C7C8 /* SecurityFoundation.framework in Frameworks */, + 49683F470C344CE40093C7C8 /* Security.framework in Frameworks */, + 49683F990C3452870093C7C8 /* Cocoa.framework in Frameworks */, + 4968CBEB0C51EA01001F5CC7 /* Foundation.framework in Frameworks */, + 495C39CC0D81F742003426FC /* Kerberos.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4998A6840DC33BEC00146652 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4998A6F00DC3415600146652 /* SecurityFoundation.framework in Frameworks */, + 4998A6F10DC3415700146652 /* Security.framework in Frameworks */, + 4998A6F20DC3415800146652 /* Kerberos.framework in Frameworks */, + 4998A6F30DC3415900146652 /* Carbon.framework in Frameworks */, + 4998A6F40DC3415900146652 /* CoreServices.framework in Frameworks */, + 4998A6F50DC3415A00146652 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D202CF20486D31800D8A456 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D202CF30486D31800D8A456 /* Cocoa.framework in Frameworks */, + 8D202CF40486D31800D8A456 /* PreferencePanes.framework in Frameworks */, + 327308D70C2AA364008C322B /* SecurityFoundation.framework in Frameworks */, + 327309970C2AB433008C322B /* Security.framework in Frameworks */, + 4940075B0CE62EB500F40D0A /* CoreServices.framework in Frameworks */, + 493564E80CE711F300699A24 /* Carbon.framework in Frameworks */, + 495C39470D81EA3C003426FC /* Kerberos.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* AFSCommander */ = { + isa = PBXGroup; + children = ( + 32CFFEF90C20314100A8DC58 /* Stand Alone Program */, + 08FB77AFFE84173DC02AAC07 /* Classes */, + 494BD47A0C43EDD400DB0A3A /* AFSMenuExtra */, + 32DBCFA10370C40200C91783 /* Other Sources */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */, + 19C28FB8FE9D52D311CA2CBB /* Products */, + ); + comments = "Progetto per la gestione delle configurazioni afs"; + name = AFSCommander; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */, + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */, + ); + name = "Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 325311CF0C44F4B100FAF2F3 /* licenza.rtf */, + 322B90430C2F0A2D0068F99A /* start_afs.sh */, + 322B90440C2F0A2D0068F99A /* stop_afs.sh */, + 324D67FB0DA13194007E1561 /* OpenAFSPreference.xib */, + 32DE81BC0DF57BDA0069A05C /* SymLinkEdit.xib */, + 324D68480DA133CF007E1561 /* CredentialPanel.xib */, + 324D683B0DA133A3007E1561 /* IpPanel.xib */, + 32B0AFB40C016E6900272348 /* English.lproj */, + 8D202CF70486D31800D8A456 /* Info.plist */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Classes */ = { + isa = PBXGroup; + children = ( + 49E43BE60C47D9EE00084436 /* global.h */, + F506C03C013D9D7901CA16C8 /* AFSCommanderPref.h */, + F506C03D013D9D7901CA16C8 /* AFSCommanderPref.m */, + 3212AA7F0C27AC2800A0689C /* AFS Logic */, + 32C4A9550C268D84009280A0 /* IpConfigurator */, + 3219259A0C339C1F00B55E86 /* TokenCredential */, + 32DE81890DF573030069A05C /* Lynk Creation */, + 322884000C3E45B100E778CC /* Info */, + 327308880C2A99A1008C322B /* Utility */, + ); + name = Classes; + sourceTree = ""; + }; + 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 495C39460D81EA3C003426FC /* Kerberos.framework */, + 493564E70CE711F300699A24 /* Carbon.framework */, + 4940075A0CE62EB500F40D0A /* CoreServices.framework */, + 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, + F506C035013D953901CA16C8 /* PreferencePanes.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + 494BD4870C43EEA400DB0A3A /* SystemUIPlugin.framework */, + 327309620C2AB433008C322B /* Security.framework */, + 327308D20C2AA364008C322B /* SecurityFoundation.framework */, + 089C1672FE841209C02AAC07 /* Foundation.framework */, + 089C167FFE841241C02AAC07 /* AppKit.framework */, + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FB8FE9D52D311CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8D202CF80486D31800D8A456 /* OpenAFS.prefPane */, + 32CF01390C203C1800A8DC58 /* Test */, + 49683EE40C3446380093C7C8 /* afshlp */, + 494C74DE0C46052800D3A2D2 /* AFSMenuExtra.menu */, + 4998A6860DC33BEC00146652 /* LoginTimeDaemon */, + ); + name = Products; + sourceTree = ""; + }; + 3212AA7F0C27AC2800A0689C /* AFS Logic */ = { + isa = PBXGroup; + children = ( + 32B0AFDD0C01729400272348 /* AFSPropertyManager.h */, + 32B0AFDE0C01729400272348 /* AFSPropertyManager.m */, + 322CEF6B0C211DAC0060D66D /* Afs Element */, + ); + name = "AFS Logic"; + sourceTree = ""; + }; + 3219259A0C339C1F00B55E86 /* TokenCredential */ = { + isa = PBXGroup; + children = ( + 3219259B0C339DAE00B55E86 /* TokenCredentialController.h */, + 3219259C0C339DAE00B55E86 /* TokenCredentialController.m */, + ); + name = TokenCredential; + sourceTree = ""; + }; + 322884000C3E45B100E778CC /* Info */ = { + isa = PBXGroup; + children = ( + 322884010C3E45C800E778CC /* InfoController.h */, + 322884020C3E45C800E778CC /* InfoController.m */, + ); + name = Info; + sourceTree = ""; + }; + 322CEF6B0C211DAC0060D66D /* Afs Element */ = { + isa = PBXGroup; + children = ( + 322CEF5E0C211D220060D66D /* DBCellElement.h */, + 322CEF5F0C211D220060D66D /* DBCellElement.m */, + 322CEF6C0C211DCC0060D66D /* CellIp.h */, + 322CEF6D0C211DCC0060D66D /* CellIp.m */, + ); + name = "Afs Element"; + sourceTree = ""; + }; + 325313A10C4515A700FAF2F3 /* Resource */ = { + isa = PBXGroup; + children = ( + 49575BB30C53CBDB00B3BC32 /* hasToken.png */, + 49575BB40C53CBDB00B3BC32 /* noToken.png */, + 325313B00C4516A900FAF2F3 /* Info.plist */, + 492AFB270C51483600AEDC93 /* CredentialWindow.nib */, + ); + name = Resource; + sourceTree = ""; + }; + 327308880C2A99A1008C322B /* Utility */ = { + isa = PBXGroup; + children = ( + 3273088B0C2A9B05008C322B /* FileUtil.h */, + 3273088C0C2A9B05008C322B /* FileUtil.m */, + 3213E93F0C2ABFD200D3D2F6 /* AuthUtil.h */, + 3213E9400C2ABFD200D3D2F6 /* AuthUtil.m */, + 327756250C3053A100C15D11 /* TaskUtil.h */, + 327756260C3053A100C15D11 /* TaskUtil.m */, + 495B043E0D219A2900F1E328 /* ViewUtility.h */, + 495B043F0D219A2900F1E328 /* ViewUtility.m */, + 32B565720D8FAF62005255F2 /* NSString+search.h */, + 32B565730D8FAF62005255F2 /* NSString+search.m */, + 498DCB410DC2240B00D143C8 /* PListManager.h */, + 498DCB420DC2240B00D143C8 /* PListManager.m */, + 49B766430DCA47A50014A80F /* DialogUtility.h */, + 49B766440DCA47A50014A80F /* DialogUtility.m */, + ); + name = Utility; + sourceTree = ""; + }; + 32B0AFB40C016E6900272348 /* English.lproj */ = { + isa = PBXGroup; + children = ( + 3223836A0C32A96F00380547 /* Localizable.strings */, + 49AF1F470C25B52A006A046E /* InfoPlist.strings */, + ); + name = English.lproj; + sourceTree = ""; + }; + 32C4A9550C268D84009280A0 /* IpConfigurator */ = { + isa = PBXGroup; + children = ( + 32C4A9560C268D9B009280A0 /* IpConfiguratorCommander.h */, + 32C4A9570C268D9B009280A0 /* IpConfiguratorCommander.m */, + ); + name = IpConfigurator; + sourceTree = ""; + }; + 32CFFEF90C20314100A8DC58 /* Stand Alone Program */ = { + isa = PBXGroup; + children = ( + 32CFFEFD0C20316B00A8DC58 /* TestLib.m */, + 49683EEB0C3446600093C7C8 /* afshlp.m */, + 4998A6A30DC33C9300146652 /* afsltd.m */, + ); + name = "Stand Alone Program"; + sourceTree = ""; + }; + 32DBCFA10370C40200C91783 /* Other Sources */ = { + isa = PBXGroup; + children = ( + 494BD47B0C43EDF900DB0A3A /* SystemUIPlugin.h */, + 32DBCFA20370C41700C91783 /* AFSCommander_Prefix.pch */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 32DE81890DF573030069A05C /* Lynk Creation */ = { + isa = PBXGroup; + children = ( + 32DE818A0DF573200069A05C /* LynkCreationController.h */, + 32DE818B0DF573200069A05C /* LynkCreationController.m */, + ); + name = "Lynk Creation"; + sourceTree = ""; + }; + 4941F62F0C49377000B29A73 /* CredentialWindow */ = { + isa = PBXGroup; + children = ( + 4941F6300C49379000B29A73 /* CredentialWindowController.h */, + 4941F6310C49379000B29A73 /* CredentialWindowController.m */, + ); + name = CredentialWindow; + sourceTree = ""; + }; + 494BD47A0C43EDD400DB0A3A /* AFSMenuExtra */ = { + isa = PBXGroup; + children = ( + 494BD48A0C43EEC300DB0A3A /* AFSMenuExtra.h */, + 494BD48B0C43EEC300DB0A3A /* AFSMenuExtra.m */, + 325312170C44F7BD00FAF2F3 /* AFSMenuExtraView.h */, + 325312180C44F7BD00FAF2F3 /* AFSMenuExtraView.m */, + 4941F50E0C4929C000B29A73 /* AFSMenuCredentialContoller.h */, + 4941F50F0C4929C000B29A73 /* AFSMenuCredentialContoller.m */, + 4941F62F0C49377000B29A73 /* CredentialWindow */, + 325313A10C4515A700FAF2F3 /* Resource */, + ); + name = AFSMenuExtra; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8D202CE90486D31800D8A456 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D202CEA0486D31800D8A456 /* AFSCommander_Prefix.pch in Headers */, + 8D202CEB0486D31800D8A456 /* AFSCommanderPref.h in Headers */, + 32B0AFDF0C01729400272348 /* AFSPropertyManager.h in Headers */, + 499716940C23E36F001339E3 /* CellIp.h in Headers */, + 499716960C23E370001339E3 /* DBCellElement.h in Headers */, + 32C4A9B90C26A0FB009280A0 /* IpConfiguratorCommander.h in Headers */, + 3273088D0C2A9B05008C322B /* FileUtil.h in Headers */, + 3213E9410C2ABFD200D3D2F6 /* AuthUtil.h in Headers */, + 327756280C3053A100C15D11 /* TaskUtil.h in Headers */, + 322884030C3E45C800E778CC /* InfoController.h in Headers */, + 49E43BE70C47D9EE00084436 /* global.h in Headers */, + 492AFA860C51301D00AEDC93 /* TokenCredentialController.h in Headers */, + 495B04400D219A2900F1E328 /* ViewUtility.h in Headers */, + 32B565740D8FAF62005255F2 /* NSString+search.h in Headers */, + 498DCB430DC2240B00D143C8 /* PListManager.h in Headers */, + 49B766450DCA47A50014A80F /* DialogUtility.h in Headers */, + 32DE818C0DF573200069A05C /* LynkCreationController.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 32CF01380C203C1800A8DC58 /* Test */ = { + isa = PBXNativeTarget; + buildConfigurationList = 32CF013C0C203C4900A8DC58 /* Build configuration list for PBXNativeTarget "Test" */; + buildPhases = ( + 32CF01360C203C1800A8DC58 /* Sources */, + 32CF01370C203C1800A8DC58 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Test; + productName = Test; + productReference = 32CF01390C203C1800A8DC58 /* Test */; + productType = "com.apple.product-type.tool"; + }; + 494BD4680C43ED0C00DB0A3A /* AFSMenuExtra */ = { + isa = PBXNativeTarget; + buildConfigurationList = 494BD46C0C43ED0D00DB0A3A /* Build configuration list for PBXNativeTarget "AFSMenuExtra" */; + buildPhases = ( + 494BD4650C43ED0C00DB0A3A /* Resources */, + 494BD4660C43ED0C00DB0A3A /* Sources */, + 494BD4670C43ED0C00DB0A3A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 49575C280C53CD9A00B3BC32 /* PBXTargetDependency */, + ); + name = AFSMenuExtra; + productName = AFSMenuExtra; + productReference = 494C74DE0C46052800D3A2D2 /* AFSMenuExtra.menu */; + productType = "com.apple.product-type.bundle"; + }; + 49683EE30C3446380093C7C8 /* afshlp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 49683EE70C34465D0093C7C8 /* Build configuration list for PBXNativeTarget "afshlp" */; + buildPhases = ( + 49683EE10C3446380093C7C8 /* Sources */, + 49683EE20C3446380093C7C8 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = afshlp; + productName = afshlp; + productReference = 49683EE40C3446380093C7C8 /* afshlp */; + productType = "com.apple.product-type.tool"; + }; + 4998A6850DC33BEC00146652 /* LoginTimeDaemon */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4998A6A10DC33C2000146652 /* Build configuration list for PBXNativeTarget "LoginTimeDaemon" */; + buildPhases = ( + 4998A6830DC33BEC00146652 /* Sources */, + 4998A6840DC33BEC00146652 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LoginTimeDaemon; + productName = LoginTimeDaemon; + productReference = 4998A6860DC33BEC00146652 /* LoginTimeDaemon */; + productType = "com.apple.product-type.tool"; + }; + 8D202CE80486D31800D8A456 /* OpenAFS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DBD214808BA80EA00186707 /* Build configuration list for PBXNativeTarget "OpenAFS" */; + buildPhases = ( + 8D202CE90486D31800D8A456 /* Headers */, + 8D202CEC0486D31800D8A456 /* Resources */, + 8D202CF00486D31800D8A456 /* Sources */, + 8D202CF20486D31800D8A456 /* Frameworks */, + 8D202CF50486D31800D8A456 /* Rez */, + 494D72C90C350BC400B1FD21 /* CopyFiles */, + 3281A5B00CD7432A00907CF6 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 3279B9810C451A63008FE3FA /* PBXTargetDependency */, + 494435690DC35D6F00C7A333 /* PBXTargetDependency */, + ); + name = OpenAFS; + productInstallPath = "$(HOME)/Library/PreferencePanes"; + productName = AFSCommander; + productReference = 8D202CF80486D31800D8A456 /* OpenAFS.prefPane */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DBD214C08BA80EA00186707 /* Build configuration list for PBXProject "OpenAFS" */; + compatibilityVersion = "Xcode 2.4"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + Italian, + ); + mainGroup = 089C166AFE841209C02AAC07 /* AFSCommander */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D202CE80486D31800D8A456 /* OpenAFS */, + 32CF01380C203C1800A8DC58 /* Test */, + 49683EE30C3446380093C7C8 /* afshlp */, + 494BD4680C43ED0C00DB0A3A /* AFSMenuExtra */, + 4998A6850DC33BEC00146652 /* LoginTimeDaemon */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 494BD4650C43ED0C00DB0A3A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 325313B10C4516A900FAF2F3 /* Info.plist in Resources */, + 49E43BA60C47D53F00084436 /* Localizable.strings in Resources */, + 49E43C730C47E0EA00084436 /* start_afs.sh in Resources */, + 49E43C740C47E0EC00084436 /* stop_afs.sh in Resources */, + 32D45E070C4B4D9C00A1012D /* afshlp in Resources */, + 492AFB280C51483600AEDC93 /* CredentialWindow.nib in Resources */, + 49575BB50C53CBDB00B3BC32 /* hasToken.png in Resources */, + 49575BB60C53CBDB00B3BC32 /* noToken.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D202CEC0486D31800D8A456 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 49AF1F480C25B52A006A046E /* InfoPlist.strings in Resources */, + 49E05CAD0C2674DA002AAEF2 /* Info.plist in Resources */, + 322B90450C2F0A2D0068F99A /* start_afs.sh in Resources */, + 322B90460C2F0A2D0068F99A /* stop_afs.sh in Resources */, + 3223836C0C32A96F00380547 /* Localizable.strings in Resources */, + 325311D00C44F4B100FAF2F3 /* licenza.rtf in Resources */, + 494C75110C4605C000D3A2D2 /* AFSMenuExtra.menu in Resources */, + 49E43D2E0C480B8200084436 /* afshlp in Resources */, + 324D67FD0DA13194007E1561 /* OpenAFSPreference.xib in Resources */, + 324D683D0DA133A3007E1561 /* IpPanel.xib in Resources */, + 324D684A0DA133CF007E1561 /* CredentialPanel.xib in Resources */, + 494435170DC35D4C00C7A333 /* LoginTimeDaemon in Resources */, + 32DE81BD0DF57BDA0069A05C /* SymLinkEdit.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 8D202CF50486D31800D8A456 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3281A5B00CD7432A00907CF6 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + comments = "Copy the menucraker.menu into resources"; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\nif [ \"$ACTION\" = \"build\" ]\nthen\n\techo \"Start coping MenuCraker.menu\"\n\techo $SRCROOT/MenuCracker.menu\n\techo $TARGET_BUILD_DIR/$PRODUCT_NAME.prefPane/Resources/\t\n\tcp -R $SRCROOT/MenuCracker.menu $TARGET_BUILD_DIR/$PRODUCT_NAME.prefPane/Contents/Resources/MenuCracker.menu\nfi\n\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 32CF01360C203C1800A8DC58 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 32CF013F0C203C5600A8DC58 /* TestLib.m in Sources */, + 32CF01460C203CA800A8DC58 /* AFSPropertyManager.m in Sources */, + 322CEF600C211D220060D66D /* DBCellElement.m in Sources */, + 322CEF6E0C211DCC0060D66D /* CellIp.m in Sources */, + 32C4A9580C268D9B009280A0 /* IpConfiguratorCommander.m in Sources */, + 327308C30C2AA2E1008C322B /* FileUtil.m in Sources */, + 49FFE7D20C2AED7200DF83CF /* AuthUtil.m in Sources */, + 327756270C3053A100C15D11 /* TaskUtil.m in Sources */, + 3219259D0C339DAE00B55E86 /* TokenCredentialController.m in Sources */, + 322884050C3E45C800E778CC /* InfoController.m in Sources */, + 495B04420D219A2900F1E328 /* ViewUtility.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 494BD4660C43ED0C00DB0A3A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 494BD48C0C43EEC300DB0A3A /* AFSMenuExtra.m in Sources */, + 325311AB0C44F38200FAF2F3 /* AFSPropertyManager.m in Sources */, + 325311AF0C44F38D00FAF2F3 /* CellIp.m in Sources */, + 325311B00C44F38D00FAF2F3 /* DBCellElement.m in Sources */, + 325311B10C44F39200FAF2F3 /* TaskUtil.m in Sources */, + 325311B20C44F39300FAF2F3 /* AuthUtil.m in Sources */, + 325311B30C44F39400FAF2F3 /* FileUtil.m in Sources */, + 325312190C44F7BD00FAF2F3 /* AFSMenuExtraView.m in Sources */, + 4941F4C00C491D2D00B29A73 /* TokenCredentialController.m in Sources */, + 4941F5100C4929C000B29A73 /* AFSMenuCredentialContoller.m in Sources */, + 4941F6320C49379000B29A73 /* CredentialWindowController.m in Sources */, + 32B565760D8FAF62005255F2 /* NSString+search.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 49683EE10C3446380093C7C8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 49683EEC0C3446600093C7C8 /* afshlp.m in Sources */, + 49683F3D0C344CD40093C7C8 /* AFSPropertyManager.m in Sources */, + 49683F3E0C344CD50093C7C8 /* DBCellElement.m in Sources */, + 49683F3F0C344CD70093C7C8 /* CellIp.m in Sources */, + 49683F400C344CD80093C7C8 /* IpConfiguratorCommander.m in Sources */, + 49683F410C344CD90093C7C8 /* FileUtil.m in Sources */, + 49683F420C344CDA0093C7C8 /* AuthUtil.m in Sources */, + 49683F430C344CDB0093C7C8 /* TaskUtil.m in Sources */, + 4934D4170DC38958000511D2 /* PListManager.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4998A6830DC33BEC00146652 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4998A6A40DC33C9300146652 /* afsltd.m in Sources */, + 4998A6A50DC33CD800146652 /* AFSPropertyManager.m in Sources */, + 4998A6A60DC33CDB00146652 /* DBCellElement.m in Sources */, + 4998A6A70DC33CDB00146652 /* CellIp.m in Sources */, + 4998A6A80DC33CE600146652 /* FileUtil.m in Sources */, + 4998A6A90DC33CE700146652 /* AuthUtil.m in Sources */, + 4998A6AA0DC33CE800146652 /* TaskUtil.m in Sources */, + 4998A6AB0DC33CE900146652 /* ViewUtility.m in Sources */, + 4998A6AC0DC33CEA00146652 /* NSString+search.m in Sources */, + 4998A6AD0DC33CEB00146652 /* PListManager.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8D202CF00486D31800D8A456 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D202CF10486D31800D8A456 /* AFSCommanderPref.m in Sources */, + 32B0AFE00C01729400272348 /* AFSPropertyManager.m in Sources */, + 499716930C23E36E001339E3 /* CellIp.m in Sources */, + 499716950C23E370001339E3 /* DBCellElement.m in Sources */, + 32C4A9B80C26A0FA009280A0 /* IpConfiguratorCommander.m in Sources */, + 3273088E0C2A9B05008C322B /* FileUtil.m in Sources */, + 3213E9420C2ABFD200D3D2F6 /* AuthUtil.m in Sources */, + 327756290C3053A100C15D11 /* TaskUtil.m in Sources */, + 322884040C3E45C800E778CC /* InfoController.m in Sources */, + 492AFA870C51301E00AEDC93 /* TokenCredentialController.m in Sources */, + 495B04410D219A2900F1E328 /* ViewUtility.m in Sources */, + 32B565750D8FAF62005255F2 /* NSString+search.m in Sources */, + 498DCB440DC2240B00D143C8 /* PListManager.m in Sources */, + 49B766460DCA47A50014A80F /* DialogUtility.m in Sources */, + 32DE818D0DF573200069A05C /* LynkCreationController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3279B9810C451A63008FE3FA /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 494BD4680C43ED0C00DB0A3A /* AFSMenuExtra */; + targetProxy = 3279B9800C451A63008FE3FA /* PBXContainerItemProxy */; + }; + 494435690DC35D6F00C7A333 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4998A6850DC33BEC00146652 /* LoginTimeDaemon */; + targetProxy = 494435680DC35D6F00C7A333 /* PBXContainerItemProxy */; + }; + 49575C280C53CD9A00B3BC32 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 49683EE30C3446380093C7C8 /* afshlp */; + targetProxy = 49575C270C53CD9A00B3BC32 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 3223836A0C32A96F00380547 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 3223836B0C32A96F00380547 /* English */, + ); + name = Localizable.strings; + sourceTree = ""; + }; + 324D67FB0DA13194007E1561 /* OpenAFSPreference.xib */ = { + isa = PBXVariantGroup; + children = ( + 324D67FC0DA13194007E1561 /* English */, + ); + name = OpenAFSPreference.xib; + sourceTree = ""; + }; + 324D683B0DA133A3007E1561 /* IpPanel.xib */ = { + isa = PBXVariantGroup; + children = ( + 324D683C0DA133A3007E1561 /* English */, + ); + name = IpPanel.xib; + sourceTree = ""; + }; + 324D68480DA133CF007E1561 /* CredentialPanel.xib */ = { + isa = PBXVariantGroup; + children = ( + 324D68490DA133CF007E1561 /* English */, + ); + name = CredentialPanel.xib; + sourceTree = ""; + }; + 32DE81BC0DF57BDA0069A05C /* SymLinkEdit.xib */ = { + isa = PBXVariantGroup; + children = ( + 32DE817D0DF571630069A05C /* English */, + ); + name = SymLinkEdit.xib; + sourceTree = ""; + }; + 49AF1F470C25B52A006A046E /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C167EFE841241C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DBD214908BA80EA00186707 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AFSCommander_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; + PRODUCT_NAME = OpenAFS; + WRAPPER_EXTENSION = prefPane; + ZERO_LINK = YES; + }; + name = Debug; + }; + 1DBD214A08BA80EA00186707 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = AFSCommander_Prefix.pch; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/PreferencePanes"; + PRODUCT_NAME = OpenAFS; + WRAPPER_EXTENSION = prefPane; + }; + name = Release; + }; + 1DBD214D08BA80EA00186707 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Debug; + }; + 1DBD214E08BA80EA00186707 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = ( + ppc, + i386, + ); + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk; + }; + name = Release; + }; + 32CF013D0C203C4900A8DC58 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INSTALL_PATH = "$(HOME)/bin"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Test; + ZERO_LINK = YES; + }; + name = Debug; + }; + 32CF013E0C203C4900A8DC58 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INSTALL_PATH = "$(HOME)/bin"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = Test; + ZERO_LINK = NO; + }; + name = Release; + }; + 494BD46D0C43ED0D00DB0A3A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INFOPLIST_FILE = "AFSMenuExtra-Info.plist"; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = AFSMenuExtra; + WRAPPER_EXTENSION = menu; + ZERO_LINK = YES; + }; + name = Debug; + }; + 494BD46E0C43ED0D00DB0A3A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)", + ); + FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\""; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INFOPLIST_FILE = "AFSMenuExtra-Info.plist"; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = AFSMenuExtra; + WRAPPER_EXTENSION = menu; + ZERO_LINK = NO; + }; + name = Release; + }; + 49683EE80C34465D0093C7C8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INSTALL_PATH = "$(HOME)/bin"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = afshlp; + ZERO_LINK = YES; + }; + name = Debug; + }; + 49683EE90C34465D0093C7C8 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INSTALL_PATH = "$(HOME)/bin"; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = afshlp; + ZERO_LINK = NO; + }; + name = Release; + }; + 4998A6880DC33BED00146652 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + INSTALL_PATH = /usr/local/bin; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = LoginTimeDaemon; + }; + name = Debug; + }; + 4998A6890DC33BED00146652 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)"; + ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386"; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; + GCC_WARN_UNUSED_PARAMETER = NO; + INSTALL_PATH = /usr/local/bin; + OTHER_LDFLAGS = ( + "-framework", + Foundation, + "-framework", + AppKit, + ); + PREBINDING = NO; + PRODUCT_NAME = LoginTimeDaemon; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DBD214808BA80EA00186707 /* Build configuration list for PBXNativeTarget "OpenAFS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DBD214908BA80EA00186707 /* Debug */, + 1DBD214A08BA80EA00186707 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DBD214C08BA80EA00186707 /* Build configuration list for PBXProject "OpenAFS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DBD214D08BA80EA00186707 /* Debug */, + 1DBD214E08BA80EA00186707 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 32CF013C0C203C4900A8DC58 /* Build configuration list for PBXNativeTarget "Test" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 32CF013D0C203C4900A8DC58 /* Debug */, + 32CF013E0C203C4900A8DC58 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 494BD46C0C43ED0D00DB0A3A /* Build configuration list for PBXNativeTarget "AFSMenuExtra" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 494BD46D0C43ED0D00DB0A3A /* Debug */, + 494BD46E0C43ED0D00DB0A3A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 49683EE70C34465D0093C7C8 /* Build configuration list for PBXNativeTarget "afshlp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 49683EE80C34465D0093C7C8 /* Debug */, + 49683EE90C34465D0093C7C8 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4998A6A10DC33C2000146652 /* Build configuration list for PBXNativeTarget "LoginTimeDaemon" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4998A6880DC33BED00146652 /* Debug */, + 4998A6890DC33BED00146652 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/src/platform/DARWIN/AFSPreference/PListManager.h b/src/platform/DARWIN/AFSPreference/PListManager.h new file mode 100644 index 000000000..dafc026f8 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/PListManager.h @@ -0,0 +1,71 @@ +// +// PListManager.h +// OpenAFS +// +// Created by Claudio Bisegni LNF - INFN on 25/04/08. +// Copyright 2008 Infn. All rights reserved. +// + +#import + +#define DELETE_IN_10_4 @"authinternal" +#define DELETE_IN_10_5 @"builtin:authenticate,privileged" +#define ADD_IN_PLIST @"builtin:krb5authnoverify,privileged" + +#define AUTH_FILE_DIR @"/etc" +#define AUTH_FILE @"/etc/authorization" +#define AUTH_FILE_BK @"/etc/authorization_bk" +#define TMP_FILE @"/tmp/authorization" + +#define HOME_LAUNCHD_AGENT_FOLDER @"~/Library/LaunchAgents" +#define AKLOG_LAUNCHD_CONTROL_FILE @"~/Library/LaunchAgents/it.infn.lnf.afslogintimedaemon.plist" +#define AKLOG_LAUNCHD_TMP_CONTROL_FILE @"/tmp/it.infn.lnf.afslogintimedaemon.plist" +#define LOGIN_TIME_DAEMON_NAME @"LoginTimeDaemon" + +#define LAUNCHD_DAEMON_FOLDER @"/Library/LaunchDaemons" +#define AFS_STARTUP_TMP_CONTROL_FILE @"/tmp/it.infn.lnf.afsstartup.plist" +#define AFS_STARTUP_CONTROL_FILE @"/Library/LaunchDaemons/it.infn.lnf.afsstartup.plist" + +/*! + @class PListManager + @abstract Utility class for modify the plist used by sistem for make login + @discussion <#(comprehensive description)#> +*/ + +@interface PListManager : NSObject { + +} +/*! + @method krb5TiketAtLoginTime + @abstract Enable or disable the system to get kerberos ticket at login time + @discussion <#(comprehensive description)#> + */ ++(void) krb5TiketAtLoginTime:(BOOL)enable; + +/*! + @method checkKrb5AtLoginTimeLaunchdEnable + @abstract check if the system is configured to ket krb5 ticket at login + @discussion <#(comprehensive description)#> + */ ++(BOOL) checkKrb5AtLoginTimeLaunchdEnable; + +/*! + @method installLaunchdFile + @abstract Install the afs agent launchd config file + @discussion <#(comprehensive description)#> + */ ++(void) installLaunchdFile:(BOOL)install resourcePath:(NSString*) rsrcPath; +/*! + @method checkAklogAtLoginTimeLaunchdEnable + @abstract check if the user has installed or enabled the afs agent + @discussion <#(comprehensive description)#> + */ ++(BOOL) checkAklogAtLoginTimeLaunchdEnable; + +/*! + @method installAfsStartupLaunchdFile + @abstract Install the afs daemon launchd config file for startup afs at boot + @discussion <#(comprehensive description)#> + */ ++(void) manageAfsStartupLaunchdFile:(BOOL)enable afsStartupScript:(NSString*)afsStartupScript afsBasePath:(NSString*)afsBasePath afsdPath:(NSString*)afsdPath; +@end diff --git a/src/platform/DARWIN/AFSPreference/PListManager.m b/src/platform/DARWIN/AFSPreference/PListManager.m new file mode 100644 index 000000000..066ec1067 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/PListManager.m @@ -0,0 +1,266 @@ +// +// PListManager.m +// OpenAFS +// +// Created by Claudio Bisegni on 25/04/08. +// Copyright 2008 Infn. All rights reserved. +// + +#import "PListManager.h" +#import "FileUtil.h" +#import "TaskUtil.h" + +@implementation PListManager +// ------------------------------------------------------------------------------- +// krb5TiketAtLoginTime: +// ------------------------------------------------------------------------------- ++(void) krb5TiketAtLoginTime:(BOOL)enable{ + NSData *plistData = nil; + NSString *error = nil; + NSString *toRemove = nil; + NSString *toAdd = nil; + NSPropertyListFormat format; + NSMutableDictionary *plist = nil; + SInt32 osxMJVers = 0; + SInt32 osxMnVers = 0; + FileUtil *futil = nil; + + //check system + if (Gestalt(gestaltSystemVersionMajor, &osxMJVers) != noErr || Gestalt(gestaltSystemVersionMinor, &osxMnVers) != noErr) @throw [NSException exceptionWithName:@"PListManager:krb5TiketAtLoginTime" + reason:@"Error getting system version" + userInfo:nil]; + //get auth plist file + plistData = [NSData dataWithContentsOfFile:AUTH_FILE]; + + //Get plist for updating with NSPropertyListMutableContainersAndLeaves + plist = [NSPropertyListSerialization propertyListFromData:plistData + mutabilityOption:NSPropertyListMutableContainersAndLeaves + format:&format + errorDescription:&error]; + if(!plist) { + @throw [NSException exceptionWithName:@"PListManager:krb5TiketAtLoginTime" + reason:error + userInfo:nil]; + + } + + //Get "rights" dic + NSMutableDictionary *rightsDic = [plist objectForKey:@"rights"]; + + //Get "system.login.console" dic + NSMutableDictionary *loginConsoleDic = [rightsDic objectForKey:@"system.login.console"]; + + //Get "mechanisms" dic + NSMutableArray *mechanismsArray = [loginConsoleDic objectForKey:@"mechanisms"]; + switch(osxMnVers){ + case 4: + if(enable){ + //remove + toRemove = DELETE_IN_10_4; + toAdd = ADD_IN_PLIST; + } else { + toRemove = ADD_IN_PLIST; + toAdd = DELETE_IN_10_4; + } + break; + + case 5: + if(enable){ + //remove + toRemove = DELETE_IN_10_5; + toAdd = ADD_IN_PLIST; + } else { + toRemove = ADD_IN_PLIST; + toAdd = DELETE_IN_10_5; + } + + break; + } + + //Make change + [mechanismsArray removeObject:toRemove]; + [mechanismsArray addObject:toAdd]; + //write plist + plistData = [NSPropertyListSerialization dataFromPropertyList:plist + format:NSPropertyListXMLFormat_v1_0 + errorDescription:&error]; + if(!plistData) { + @throw [NSException exceptionWithName:@"PListManager:krb5TiketAtLoginTime" + reason:error + userInfo:nil]; + + } + if(![plistData writeToFile:TMP_FILE atomically:NO]) { + @throw [NSException exceptionWithName:@"PListManager:krb5TiketAtLoginTime" + reason:@"Temp file write error" + userInfo:nil]; + + } + + //now we can move the file + futil = [[FileUtil alloc] init]; + if([futil startAutorization] == noErr) { + if(![[NSFileManager defaultManager] fileExistsAtPath:AUTH_FILE_BK]) { + //bk file doesn't exist so make it + [futil autorizedCopy:AUTH_FILE toPath:AUTH_FILE_BK]; + } + // chmod on tmp file + [futil autorizedChown:TMP_FILE owner:@"root" group:@"wheel"]; + //mov ethe file + [futil autorizedMoveFile:TMP_FILE toPath:AUTH_FILE_DIR]; + } + [futil release]; +} + +// ------------------------------------------------------------------------------- +// checkAklogAtLoginTimeLaunchdEnable: +// ------------------------------------------------------------------------------- ++(BOOL) checkKrb5AtLoginTimeLaunchdEnable { + BOOL result = false; + NSString *authFileContent = nil; + authFileContent = [NSString stringWithContentsOfFile:AUTH_FILE]; + if(authFileContent) { + result = [authFileContent rangeOfString:ADD_IN_PLIST].location != NSNotFound; + } + return result; +} + + +// ------------------------------------------------------------------------------- +// installLaunchdFile: +// ------------------------------------------------------------------------------- ++(void) installLaunchdFile:(BOOL)install resourcePath:(NSString*) rsrcPath { + NSData *plistData = nil; + NSMutableDictionary *launchdDic = nil; + NSString *error = nil; + NSString *daemonPath = [[rsrcPath stringByAppendingString:@"/"] stringByAppendingString:LOGIN_TIME_DAEMON_NAME]; + + + if(![[NSFileManager defaultManager] fileExistsAtPath:[HOME_LAUNCHD_AGENT_FOLDER stringByExpandingTildeInPath]]) { + @throw [NSException exceptionWithName:@"PListManager:installLaunchdFile" + reason:@"The folder ~/Library/LaunchAgent doesn't exist!" + userInfo:[NSNumber numberWithInt:1]]; + } + + if(install) { + if(![[NSFileManager defaultManager] fileExistsAtPath:[AKLOG_LAUNCHD_CONTROL_FILE stringByExpandingTildeInPath]]) { + launchdDic = [[NSMutableDictionary alloc] init]; + + [launchdDic setObject:@"it.infn.lnf.afslogintimedaemon" + forKey:@"Label"]; + + [launchdDic setObject:@"Aqua" + forKey:@"LimitLoadToSessionType"]; + + [launchdDic setObject:[NSArray arrayWithObject:daemonPath] + forKey:@"ProgramArguments"]; + + [launchdDic setObject:[NSNumber numberWithBool:YES] + forKey:@"RunAtLoad"]; + + plistData = [NSPropertyListSerialization dataFromPropertyList:launchdDic + format:NSPropertyListXMLFormat_v1_0 + errorDescription:&error]; + + if(!plistData) { + @throw [NSException exceptionWithName:@"PListManager:installLaunchdFile" + reason:error + userInfo:nil]; + + } + + if(![plistData writeToFile:AKLOG_LAUNCHD_TMP_CONTROL_FILE atomically:NO]) { + @throw [NSException exceptionWithName:@"PListManager:installLaunchdFile" + reason:@"Temp file write error" + userInfo:nil]; + + } + + //now we can move the file + [TaskUtil executeTaskSearchingPath:@"mv" args:[NSArray arrayWithObjects:AKLOG_LAUNCHD_TMP_CONTROL_FILE, [HOME_LAUNCHD_AGENT_FOLDER stringByExpandingTildeInPath], nil]]; + } + } else { + // delete launchd configuration file + [TaskUtil executeTaskSearchingPath:@"rm" args:[NSArray arrayWithObjects:[AKLOG_LAUNCHD_CONTROL_FILE stringByExpandingTildeInPath], nil]]; + } + +} + +// ------------------------------------------------------------------------------- +// checkAklogAtLoginTimeLaunchdEnable: +// ------------------------------------------------------------------------------- ++(BOOL) checkAklogAtLoginTimeLaunchdEnable { + BOOL result = [[NSFileManager defaultManager] fileExistsAtPath:[AKLOG_LAUNCHD_CONTROL_FILE stringByExpandingTildeInPath]]; + return result; +} + +// ------------------------------------------------------------------------------- +// installAfsStartupLaunchdFile: +// ------------------------------------------------------------------------------- ++(void) manageAfsStartupLaunchdFile:(BOOL)enable + afsStartupScript:(NSString*)afsStartupScript + afsBasePath:(NSString*)afsBasePath + afsdPath:(NSString*)afsdPath { + NSData *plistData = nil; + NSMutableDictionary *launchdDic = nil; + NSMutableArray *argDic = nil; + NSString *error = nil; + OSErr status = noErr; + + + if(![[NSFileManager defaultManager] fileExistsAtPath:[LAUNCHD_DAEMON_FOLDER stringByExpandingTildeInPath]]) { + @throw [NSException exceptionWithName:@"PListManager:installAfsStartupLaunchdFile" + reason:@"The folder /Library/LaunchDaemon doesn't exist!" + userInfo:nil]; + } + + status = [[AuthUtil shared] autorize]; + if(status != noErr)@throw [NSException exceptionWithName:@"PListManager:installAfsStartupLaunchdFile" + reason:@"Autorization Error" + userInfo:nil]; + + if(enable) { + //Check first if the launchd configuration file for startup is present + if(![[NSFileManager defaultManager] fileExistsAtPath:[AFS_STARTUP_CONTROL_FILE stringByExpandingTildeInPath]]) { + launchdDic = [[NSMutableDictionary alloc] init]; + //argDic = [[NSMutableArray alloc] init]; + + [launchdDic setObject:@"it.infn.lnf.afsstartup" + forKey:@"Label"]; + + //[argDic addObject:afsStartupScript]; + //[argDic addObject:afsBasePath/*"/var/db/openafs"*/]; + //[argDic addObject:afsdPath/*"/usr/sbin/afsd"*/]; + + [launchdDic setObject:[NSArray arrayWithObjects:afsStartupScript, afsBasePath, afsdPath, nil] + forKey:@"ProgramArguments"]; + + [launchdDic setObject:[NSNumber numberWithBool:YES] + forKey:@"RunAtLoad"]; + + plistData = [NSPropertyListSerialization dataFromPropertyList:launchdDic + format:NSPropertyListXMLFormat_v1_0 + errorDescription:&error]; + + if(!plistData) { + @throw [NSException exceptionWithName:@"PListManager:installLaunchdFile" + reason:error + userInfo:nil]; + + } + + if(![plistData writeToFile:AFS_STARTUP_TMP_CONTROL_FILE atomically:NO]) { + @throw [NSException exceptionWithName:@"PListManager:installLaunchdFile" + reason:@"Temp file write error" + userInfo:nil]; + + } + + //now we can move the file + [TaskUtil executeTaskSearchingPath:@"mv" args:[NSArray arrayWithObjects:AFS_STARTUP_TMP_CONTROL_FILE, [LAUNCHD_DAEMON_FOLDER stringByExpandingTildeInPath], nil]]; + } + } + +} + +@end diff --git a/src/platform/DARWIN/AFSPreference/SystemUIPlugin.h b/src/platform/DARWIN/AFSPreference/SystemUIPlugin.h new file mode 100644 index 000000000..944056488 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/SystemUIPlugin.h @@ -0,0 +1,220 @@ +/* + * Generated by class-dump 3.1.1. + * + * class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2006 by Steve Nygard. + */ +#import + +@interface NSMenuExtra : NSStatusItem +{ + NSBundle *_bundle; + NSMenu *_menu; + NSView *_view; + float _length; + struct { + unsigned int customView:1; + unsigned int menuDown:1; + unsigned int reserved:30; + } _flags; + id _controller; +} + +- (id)initWithBundle:(id)fp8; +- (id)initWithBundle:(id)fp8 data:(id)fp12; +- (void)willUnload; +- (void)dealloc; +- (id)bundle; +- (float)length; +- (void)setLength:(float)fp8; +- (id)image; +- (void)setImage:(id)fp8; +- (id)alternateImage; +- (void)setAlternateImage:(id)fp8; +- (id)menu; +- (void)setMenu:(id)fp8; +- (id)toolTip; +- (void)setToolTip:(id)fp8; +- (id)view; +- (void)setView:(id)fp8; +- (BOOL)isMenuDown; +- (void)drawMenuBackground:(BOOL)fp8; +- (void)popUpMenu:(id)fp8; +- (void)unload; +- (id)statusBar; +- (SEL)action; +- (void)setAction:(SEL)fp8; +- (id)target; +- (void)setTarget:(id)fp8; +- (id)title; +- (void)setTitle:(id)fp8; +- (id)attributedTitle; +- (void)setAttributedTitle:(id)fp8; +- (BOOL)isEnabled; +- (void)setEnabled:(BOOL)fp8; +- (void)setHighlightMode:(BOOL)fp8; +- (BOOL)highlightMode; +- (void)sendActionOn:(int)fp8; +- (id)_initInStatusBar:(id)fp8 withLength:(float)fp12 withPriority:(int)fp16; +- (id)_window; +- (id)_button; +- (void)_adjustLength; + +@end + +@interface NSMenuExtra (NSMenuExtraPrivate) ++ (unsigned int)defaultLength; +- (void)setController:(id)fp8; +- (id)controller; +- (void)setMenuDown:(BOOL)fp8; +- (float)defaultLength; +- (id)accessibilityAttributeNames; +- (id)accessibilityAttributeValue:(id)fp8; +- (BOOL)accessibilityIsAttributeSettable:(id)fp8; +- (void)accessibilitySetValue:(id)fp8 forAttribute:(id)fp12; +- (id)accessibilityActionNames; +- (id)accessibilityActionDescription:(id)fp8; +- (void)accessibilityPerformAction:(id)fp8; +- (BOOL)accessibilityIsIgnored; +- (id)accessibilityHitTest:(struct _NSPoint)fp8; +- (id)accessibilityFocusedUIElement; +- (id)AXRole; +- (id)AXRoleDescription; +- (id)AXSubrole; +- (id)AXDescription; +- (id)AXChildren; +- (id)AXParent; +- (id)AXTitle; +- (id)AXValue; +- (id)AXEnabled; +- (id)AXSelected; +- (BOOL)isAXSelectedSettable; +- (void)setAXSelected:(id)fp8; +- (id)AXPosition; +- (id)AXSize; +- (void)performAXPress; +- (void)performAXCancel; +@end + +@interface NSDockExtra : NSObject +{ + NSBundle *_bundle; + unsigned int _id; + void *_nativeWindow; + id _controller; + struct { + unsigned int nativeWindow:1; + unsigned int reserved:31; + } _flags; + long _fReserved1; + long _fReserved2; + long _fReserved3; + long _fReserved4; +} + +- (id)initWithBundle:(id)fp8; +- (id)initWithBundle:(id)fp8 data:(id)fp12; +- (void)dealloc; +- (void)willUnload; +- (id)bundle; +- (id)menu; +- (void)toggle; +- (void)handleMenuCommand:(unsigned int)fp8 tag:(unsigned int)fp12; +- (void)setDockLabel:(id)fp8; +- (id)cocoaWindow; +- (void *)carbonCGrafPtr; + +@end + +@interface NSDockExtra (NSDockExtraReallyPrivate) +- (void)_releaseWindow; +@end + +@interface NSDockExtra (NSDockExtraPrivate) +- (id)initWithBundle:(id)fp8 identifier:(unsigned int)fp12 controller:(id)fp16; +- (id)initWithBundle:(id)fp8 identifier:(unsigned int)fp12 data:(id)fp16 controller:(id)fp20; +- (void *)cgWindow; +@end + +@interface NSMutableArray (NSDockExtraMenu) +- (void)insertItem:(id)fp8 atIndex:(int)fp12; +- (void)addItem:(id)fp8; +- (id)insertItemWithTitle:(id)fp8 action:(SEL)fp12 atIndex:(int)fp16; +- (id)addItemWithTitle:(id)fp8 action:(SEL)fp12; +- (void)removeItemAtIndex:(int)fp8; +- (void)setSubmenu:(id)fp8 forItem:(id)fp12; +- (int)indexOfItemWithTitle:(id)fp8; +- (int)indexOfItemWithAction:(SEL)fp8; +- (id)itemWithTitle:(id)fp8; +- (id)itemWithAction:(SEL)fp8; +@end + +@interface NSMutableDictionary (NSDockExtraMenuItem) ++ (id)separatorItem; ++ (id)itemWithTitle:(id)fp8 action:(SEL)fp12; +- (BOOL)hasSubmenu; +- (void)setSubmenu:(id)fp8; +- (id)submenu; +- (void)setSubmenuSelectable:(BOOL)fp8; +- (BOOL)isSubmenuSelectable; +- (void)setTitle:(id)fp8; +- (id)title; +- (BOOL)isSeparatorItem; +- (void)setEnabled:(BOOL)fp8; +- (BOOL)isEnabled; +- (void)setAction:(SEL)fp8; +- (SEL)action; +- (void)setTag:(int)fp8; +- (int)tag; +- (void)setMark:(int)fp8; +- (int)mark; +- (void)setMarkChar:(id)fp8; +- (id)markChar; +- (void)setHeader:(BOOL)fp8; +- (BOOL)isHeader; +- (void)setStyle:(int)fp8; +- (int)style; +- (void)setIndent:(unsigned short)fp8; +- (unsigned short)indent; +- (void)setDynamicMask:(int)fp8; +- (int)dynamicMask; +- (void)removeDynamicMask; +- (void)setDynamicBreak:(BOOL)fp8; +- (BOOL)dynamicBreak; +- (void)setSystemIcon:(unsigned int)fp8; +- (unsigned int)systemIcon; +- (void)setResourceIcon:(id)fp8; +- (id)resourceIcon; +- (void)setIconEnabled:(BOOL)fp8; +- (BOOL)isIconEnabled; +@end + +@interface NSApplicationDockExtra : NSDockExtra +{ +} + +- (void)applicationLaunched; +- (void)applicationDied; +- (void)setDockLabel:(id)fp8; + +@end + +@interface NSMenuExtraView : NSView +{ + NSMenu *_menu; + NSMenuExtra *_menuExtra; + NSImage *_image; + NSImage *_alternateImage; +} + +- (id)initWithFrame:(NSRect)fp8 menuExtra:(id)fp24; +- (void)dealloc; +- (void)setMenu:(id)fp8; +- (id)image; +- (void)setImage:(id)fp8; +- (id)alternateImage; +- (void)setAlternateImage:(id)fp8; +- (void)drawRect:(NSRect)fp8; +- (void)mouseDown:(id)fp8; + +@end + diff --git a/src/platform/DARWIN/AFSPreference/TaskUtil.h b/src/platform/DARWIN/AFSPreference/TaskUtil.h new file mode 100644 index 000000000..b7fc7ecc9 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/TaskUtil.h @@ -0,0 +1,19 @@ +// +// TaskUtil.h +// AFSCommander +// +// Created by Claudio Bisegni on 25/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import +#include +#include + +@interface TaskUtil : NSObject { +} ++(NSString*) searchExecutablePath:(NSString*)unixCommand; ++(NSString*) executeTaskSearchingPath:(NSString*)unixCommand args:(NSArray*)args; ++(NSString*) executeTask:(NSString*) taskName arguments:(NSArray *)args; ++(int) executeTaskWithAuth:(NSString*) taskName arguments:(NSArray *)args authExtForm:(NSData*)auth; +@end diff --git a/src/platform/DARWIN/AFSPreference/TaskUtil.m b/src/platform/DARWIN/AFSPreference/TaskUtil.m new file mode 100644 index 000000000..abc79c93e --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/TaskUtil.m @@ -0,0 +1,126 @@ +// +// TaskUtil.m +// AFSCommander +// +// Created by Claudio Bisegni on 25/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "TaskUtil.h" + + +@implementation TaskUtil + +// ------------------------------------------------------------------------------- +// executeTaskSearchingPath: +// ------------------------------------------------------------------------------- ++(NSString*) executeTaskSearchingPath:(NSString*)unixCommand args:(NSArray*)args +{ + NSString *commResult = nil; + NSString *commPath = [self searchExecutablePath:unixCommand]; + if(commPath != nil){ + commResult = [self executeTask:commPath + arguments:args]; + } + return commResult; +} + +// ------------------------------------------------------------------------------- +// executeTask: +// ------------------------------------------------------------------------------- ++(NSString*) searchExecutablePath:(NSString*)unixCommand +{ + NSString *commPath = [self executeTask:@"/usr/bin/which" arguments:[NSArray arrayWithObjects:unixCommand, nil]]; + return commPath; +} + +// ------------------------------------------------------------------------------- +// executeTask: +// ------------------------------------------------------------------------------- ++(NSString*) executeTask:(NSString*) taskName arguments:(NSArray *)args{ + NSLog(taskName); + NSString *result = nil; + int status = 0; + NSFileHandle *file = nil; + NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys: @"$PATH:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin",@"PATH",nil]; + + NSPipe *pipe = [NSPipe pipe]; + NSTask *taskToRun = [[NSTask alloc] init]; + + [taskToRun setLaunchPath: taskName]; + [taskToRun setArguments: args]; + [taskToRun setEnvironment:environment]; + [taskToRun setStandardOutput: pipe]; + file = [pipe fileHandleForReading]; + [taskToRun launch]; + [taskToRun waitUntilExit]; + status = [taskToRun terminationStatus]; + if (status == 0){ + NSLog(@"Task succeeded."); + NSData *data = [file readDataToEndOfFile]; + // remove the \n character from unix command + if([data length] > 0){ + NSData *realData = [NSData dataWithBytes:[data bytes] + length:[data length]-1]; + + [taskToRun release]; + result = [[NSString alloc] initWithData: realData + encoding: NSUTF8StringEncoding]; + NSLog(result); + } + } else { + NSLog(@"Task failed."); + } + return [result autorelease]; +} + + +// ------------------------------------------------------------------------------- +// executeTask: +// ------------------------------------------------------------------------------- ++(int) executeTaskWithAuth:(NSString*) taskName arguments:(NSArray *)args authExtForm:(NSData*)auth { + NSLog(taskName); + NSString *result = nil; + int status = 0; + NSFileHandle *file = nil; + NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys: @"$PATH:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin",@"PATH",nil]; + + NSPipe *pipe = [NSPipe pipe]; + NSPipe *pipeIn = [NSPipe pipe]; + NSTask *taskToRun = [[NSTask alloc] init]; + + [taskToRun setLaunchPath: taskName]; + [taskToRun setArguments: args]; + [taskToRun setEnvironment:environment]; + [taskToRun setStandardOutput: pipe]; + [taskToRun setStandardInput: pipeIn]; + file = [pipe fileHandleForReading]; + //Write to standard in + [taskToRun launch]; + + NSFileHandle* taskInput = [[ taskToRun standardInput ] fileHandleForWriting ]; + [taskInput writeData:auth]; + [taskToRun waitUntilExit]; + status = [taskToRun terminationStatus]; + if (status == 0){ + NSLog(@"Task succeeded."); + NSData *data = [file readDataToEndOfFile]; + // remove the \n character from unix command + if([data length] > 0){ + NSData *realData = [NSData dataWithBytes:[data bytes] + length:[data length]-1]; + + [taskToRun release]; + result = [[NSString alloc] initWithData: realData + encoding: NSUTF8StringEncoding]; + NSLog(result); + [result release]; + } + } else { + NSLog(@"Task failed."); + } + + return status; +} + +@end diff --git a/src/platform/DARWIN/AFSPreference/TestLib.m b/src/platform/DARWIN/AFSPreference/TestLib.m new file mode 100644 index 000000000..ea22c7716 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/TestLib.m @@ -0,0 +1,35 @@ + +#import "AFSPropertyManager.h" +#import "FileUtil.h" +#import "TaskUtil.h" +#import "global.h" + +int CoreMenuExtraGetMenuExtra(CFStringRef identifier, void *menuExtra); +int CoreMenuExtraAddMenuExtra(CFURLRef path, int position, int whoCares, int whoCares2, int whoCares3, int whoCares4); +int CoreMenuExtraRemoveMenuExtra(void *menuExtra, int whoCares); +void printNSArray(NSArray *array); + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + /*AFSPropertyManager *propMan=[[AFSPropertyManager alloc] initWithAfsPath:@"/var/db/openafs"]; + [propMan loadConfiguration]; + [propMan saveCacheConfigurationFiles:true]; + [propMan release];*/ + + //[AFSPropertyManager aklog]; + + NSAlert *alert = [[NSAlert alloc] init]; + [alert setMessageText:@"test"]; + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + int result = [alert runModal]; + + [pool release]; +} + +void printNSArray(NSArray *array) { + for(int idx = 0; idx < [array count]; idx++) { + NSLog([[array objectAtIndex:idx] description]); + } +} \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/TokenCredentialController.h b/src/platform/DARWIN/AFSPreference/TokenCredentialController.h new file mode 100644 index 000000000..a2e12b035 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/TokenCredentialController.h @@ -0,0 +1,32 @@ +// +// TokenCredentialController.h +// AFSCommander +// +// Created by Claudio Bisegni on 28/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import + + +@interface TokenCredentialController : NSObject { + @public + id credentialPanel; + + @protected + id afsCommanderPref; + id textEditUserName; + id textEditPassword; + + BOOL taken; + NSString *uName; + NSString *uPwd; + +} + +- (IBAction) getToken:(id) sender; +- (IBAction) closePanel:(id) sender; +- (BOOL) takenToken; +- (NSString*) uName; +- (NSString*) uPwd; +@end diff --git a/src/platform/DARWIN/AFSPreference/TokenCredentialController.m b/src/platform/DARWIN/AFSPreference/TokenCredentialController.m new file mode 100644 index 000000000..55adfea2e --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/TokenCredentialController.m @@ -0,0 +1,69 @@ +// +// TokenCredentialController.m +// AFSCommander +// +// Created by Claudio Bisegni on 28/06/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "TokenCredentialController.h" +#import "TaskUtil.h" + +@implementation TokenCredentialController +// ------------------------------------------------------------------------------- +// awakeFromNib: +// ------------------------------------------------------------------------------- +- (void)awakeFromNib +{ + NSLog(@"awakeFromNib"); +} + + +// ------------------------------------------------------------------------------- +// getToken: +// ------------------------------------------------------------------------------- +- (IBAction) getToken:(id) sender +{ + uName = [((NSTextField*) textEditUserName) stringValue]; + uPwd = [((NSTextField*) textEditPassword) stringValue]; + if(uName == @"" || uPwd == @"") return; + taken = YES; + [NSApp endSheet:credentialPanel]; +} + + +// ------------------------------------------------------------------------------- +// closePanel: +// ------------------------------------------------------------------------------- +- (IBAction) closePanel:(id) sender +{ + taken = NO; + [NSApp endSheet:credentialPanel]; +} + + +// ------------------------------------------------------------------------------- +// takenToken: +// ------------------------------------------------------------------------------- +- (BOOL) takenToken +{ + return taken; +} + +// ------------------------------------------------------------------------------- +// takenToken: +// ------------------------------------------------------------------------------- +- (NSString*) uName +{ + return uName; +} + +// ------------------------------------------------------------------------------- +// takenToken: +// ------------------------------------------------------------------------------- +- (NSString*) uPwd +{ + return uPwd; +} + +@end diff --git a/src/platform/DARWIN/AFSPreference/ViewUtility.h b/src/platform/DARWIN/AFSPreference/ViewUtility.h new file mode 100644 index 000000000..ccc9c5ece --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/ViewUtility.h @@ -0,0 +1,16 @@ +// +// ViewUtility.h +// AFSCommander +// +// Created by Claudio Bisegni on 25/12/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import + + +@interface ViewUtility : NSObject { + +} ++(void) enbleDisableControlView: (NSView*)parentView controlState:(BOOL)controlState; +@end diff --git a/src/platform/DARWIN/AFSPreference/ViewUtility.m b/src/platform/DARWIN/AFSPreference/ViewUtility.m new file mode 100644 index 000000000..00291a187 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/ViewUtility.m @@ -0,0 +1,30 @@ +// +// ViewUtility.m +// AFSCommander +// +// Created by Claudio Bisegni on 25/12/07. +// Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved. +// + +#import "ViewUtility.h" + + +@implementation ViewUtility ++(void) enbleDisableControlView:(NSView*)parentView + controlState:(BOOL)controlState +{ + if(!parentView) return; + NSArray *views = [parentView subviews]; + + for(int idx = 0; idx < [views count]; idx++) + { + NSObject *obj = [views objectAtIndex:idx]; + if([obj respondsToSelector:@selector(setEnabled:)]) + { + //[obj setEnabled:controlState]; + [obj performSelector:@selector(setEnabled:) withObject:controlState]; + } + } + +} +@end diff --git a/src/platform/DARWIN/AFSPreference/afscommlogo.png b/src/platform/DARWIN/AFSPreference/afscommlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..3bf86eb100cedcde3ab10823811b29a2fe0ff56a GIT binary patch literal 8019 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 Vg}2NQBBcNT002ovPDHLkV1nf(iwpn& literal 0 HcmV?d00001 diff --git a/src/platform/DARWIN/AFSPreference/afshlp.m b/src/platform/DARWIN/AFSPreference/afshlp.m new file mode 100644 index 000000000..809274b79 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/afshlp.m @@ -0,0 +1,199 @@ +// +// afshlp.m +// AFSCommander +// +// Created by Claudio on 28/06/07. +// + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#import "TaskUtil.h" +#import "AuthUtil.h" +#import "PListManager.h" + void stopAfs(int argc, char *argv[]); + void getPath(char **selfPathPtr); + void selfRepair(char *selfPath); + void runWithSelfRepair(char *selfPath,int argc, char *argv[]); + void runCommand(int argc, char *argv[]); + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + char *selfPath; + + NSLog(@"num of arguments %d", argc); + int status = [[AuthUtil shared] autorize]; + if(status != noErr) exit(-1); + + // Get the path to the tool's executable + getPath(&selfPath); + + //selfRepair(selfPath); + // All done with the executable path + if(selfPath) free(selfPath); + + // Now do the real work of running the command. + runCommand(argc, argv); + [[AuthUtil shared] deautorize]; + [pool release]; + + return 0; +} + +// +void runCommand(int argc, char *argv[]) +{ + NSString *cmdString = [NSString stringWithCString:(const char *)argv[1] encoding:NSUTF8StringEncoding]; + + if(argc == 4 && [cmdString rangeOfString:@"stop_afs"].location!=NSNotFound ){ + NSLog(@"Stop afs from helper"); + stopAfs(argc, argv); + } else if(argc == 4 && [cmdString rangeOfString:@"start_afs"].location!=NSNotFound){ + NSLog(@"Start afs from helper"); + setuid(0); + const char *startArgs[] = {argv[2], argv[3], 0L}; + [[AuthUtil shared] execUnixCommand:argv[1] + args:startArgs + output:nil]; + } else if(argc == 4 && [cmdString rangeOfString:@"enable_krb5_startup"].location!=NSNotFound) { + NSLog(@"Manage KRB5 at login time with option %s from helper", argv[2]); + setuid(0); + int arg2 = atoi(argv[2]); + [PListManager krb5TiketAtLoginTime:[[NSNumber numberWithInt:arg2] boolValue]]; + + } else if(argc == 5 && [cmdString rangeOfString:@"start_afs_at_startup"].location!=NSNotFound){ + setuid(0); + NSLog(@"Manage start_afs_at_startup with option %s from helper", argv[2]); + [PListManager manageAfsStartupLaunchdFile:YES + afsStartupScript:[NSString stringWithCString:argv[2]] + afsBasePath:[NSString stringWithCString:argv[4]] + afsdPath:[NSString stringWithCString:argv[3]]]; + } +} + +void stopAfs(int argc, char *argv[]) +{ + + + setuid(0); + const char *umountArgs[] = {"-f", "/afs", 0L}; + [[AuthUtil shared] execUnixCommand:"/sbin/umount" + args:umountArgs + output:nil]; + + const char *afsdArgs[] = {"-shutdown", 0L}; + [[AuthUtil shared] execUnixCommand:argv[3] + args:afsdArgs + output:nil]; + + const char *kernelExtArgs[] = {argv[2], 0L}; + [[AuthUtil shared] execUnixCommand:"/sbin/kextunload" + args:kernelExtArgs + output:nil]; + + [[AuthUtil shared] deautorize]; +} + + +// Code to get the path to the executable using _NSGetExecutablePath. +void getPath(char **selfPathPtr) +{ + uint32_t selfPathSize = MAXPATHLEN; + if(!(*selfPathPtr = malloc(selfPathSize))) + { + exit(-1); + } + if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) == -1) + { + // Try reallocating selfPath with the size returned by the function. + if(!(*selfPathPtr = realloc(*selfPathPtr, selfPathSize + 1))) + { + NSLog(@"Could not allocate memory to hold executable path."); + exit(-1); + } + if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) != 0) + { + NSLog(@"Could not get executable path."); + exit(-1); + } + } +} + +// Self-repair code. Found somehwere in internet +void selfRepair(char *selfPath) +{ + struct stat st; + int fdTool; + printf("selfRepair"); + +// [[AuthUtil shared] autorize]; + + // Open tool exclusively, noone can touch it when we work on it, this idea i kepped somewhere in internet + fdTool = open(selfPath, O_NONBLOCK | O_RDONLY | O_EXLOCK, 0); + + if(fdTool == -1) + { + NSLog(@"Open Filed: %d.", errno); + exit(-1); + } + + if(fstat(fdTool, &st)) + { + NSLog(@"fstat failed."); + exit(-1); + } + + if(st.st_uid != 0) + { + fchown(fdTool, 0, st.st_gid); + } else NSLog(@"st_uid = 0"); + + // Disable group and world writability and make setuid root. + fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH))) | S_ISUID); + + close(fdTool); + + NSLog(@"Self-repair done."); +} + + +// Code to execute the tool in self-repair mode. +void runWithSelfRepair(char *selfPath, int argc, char *argv[]) +{ + int status; + int pid; + + + // Make the qargs array for passing to child the same args of father + const char *arguments = {argv[1], argv[2], argv[3], "--self-repair", 0L}; + + // Get the privileged AuthorizationRef + [[AuthUtil shared] autorize]; + [[AuthUtil shared] execUnixCommand:selfPath + args:arguments + output:nil]; + + pid = wait(&status); + if(pid == -1 || !WIFEXITED(status)) + { + NSLog(@"Error returned from wait()."); + exit(-1); + } + + // Exit with the same exit code as the self-repair child + exit(WEXITSTATUS(status)); +} \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/afslogo.psd b/src/platform/DARWIN/AFSPreference/afslogo.psd new file mode 100644 index 0000000000000000000000000000000000000000..145299e8e5c8b7f4d5e03374c36bc1bad175feab GIT binary patch literal 428255 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

9D<%npsV2r~Y)9 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

7lfbXZk1Y^ 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 jZ``G*k$`)ZTFa4_tcLIJv5&IOFccD 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 I|NdY90~$&jWB>pF literal 0 HcmV?d00001 diff --git a/src/platform/DARWIN/AFSPreference/afsltd.m b/src/platform/DARWIN/AFSPreference/afsltd.m new file mode 100644 index 000000000..207dc11f6 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/afsltd.m @@ -0,0 +1,85 @@ +// +// afsltd.m +// OpenAFS +// +// Created by Claudio Bisegni LNF-INFN on 26/04/08. +// Copyright 2008 Infn. All rights reserved. +// +#import "global.h" +#import "AFSPropertyManager.h" +#include + +BOOL useAklog = NO; +NSString *afsSysPath = nil; +AFSPropertyManager *propManager = nil; + +void readPreferenceFile(); +void makeAFSPropertyManager(); +void callAKlog(); + +int main(int argc, char *argv[]) +{ + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + NSLog(@"Start AFS Preference Daemon"); + // read the preference file + readPreferenceFile(); + + //check if base afs path is set + if(!afsSysPath) return 1; + + //Sleep ten seconds + sleep(10); + + //make the afs property manager and load all afs configuration + makeAFSPropertyManager(); + + //call aklog + callAKlog(); + if(propManager) [propManager release]; + + [pool release]; + return 0; +} + +// ------------------------------------------------------------------------------- +// readPreferenceFile: +// ------------------------------------------------------------------------------- +void readPreferenceFile() +{ + // read the preference for afs path + afsSysPath = (NSString*)CFPreferencesCopyAppValue((CFStringRef)PREFERENCE_AFS_SYS_PAT, (CFStringRef)afsCommanderID); + + + // read the preference for aklog use + NSNumber *useAklogPrefValue = (NSNumber*)CFPreferencesCopyAppValue((CFStringRef)PREFERENCE_USE_AKLOG, (CFStringRef)afsCommanderID); + useAklog = [useAklogPrefValue boolValue]; + +} + +// ------------------------------------------------------------------------------- +// makeAFSPropertyManager: +// ------------------------------------------------------------------------------- +void makeAFSPropertyManager() { + if(propManager) { + [propManager release]; + } + propManager = [[AFSPropertyManager alloc] initWithAfsPath:afsSysPath]; + [propManager loadConfiguration]; +} + +// ------------------------------------------------------------------------------- +// makeAFSPropertyManager: +// ------------------------------------------------------------------------------- +void callAKlog() { + //call aklog for all selected cell, but first check if afs is up + if([propManager checkAfsStatus] && useAklog) { + [propManager getTokens:false + usr:nil + pwd:nil]; + + // send notification to + [[NSDistributedNotificationCenter defaultCenter] postNotificationName:kAFSMenuExtraID object:kMExtraAFSStateChange]; + } +} \ No newline at end of file diff --git a/src/platform/DARWIN/AFSPreference/global.h b/src/platform/DARWIN/AFSPreference/global.h new file mode 100644 index 000000000..803a5d898 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/global.h @@ -0,0 +1,57 @@ +/* + * global.h + * AFSCommander + * + * Created by Claudio on 13/07/07. + * Copyright 2007 INFN. All rights reserved. + * + */ + +#define kMenuBarHeight 22 +#define TOKENS_REFRESH_TIME_IN_SEC 60 + +// Localized string +#define kDevelopInfo NSLocalizedStringFromTableInBundle(@"DevelopInfo",nil,[NSBundle bundleForClass:[self class]],@"DevelopInfo") +#define kConfigurationSaved NSLocalizedStringFromTableInBundle(@"ConfigurationSaved",nil,[NSBundle bundleForClass:[self class]],@"ConfigurationSaved") +#define kSavedCacheConfiguration NSLocalizedStringFromTableInBundle(@"SavedCacheConfiguration",nil,[NSBundle bundleForClass:[self class]],@"SavedCacheConfiguration") +#define kAfsOn NSLocalizedStringFromTableInBundle(@"AfsOn",nil,[NSBundle bundleForClass:[self class]],@"AfsOn") +#define kAfsOff NSLocalizedStringFromTableInBundle(@"AfsOff",nil,[NSBundle bundleForClass:[self class]],@"AfsOff") +#define kAfsButtonShutdown NSLocalizedStringFromTableInBundle(@"AfsButtonShutdown",nil,[NSBundle bundleForClass:[self class]],@"AfsButtonShutdown") +#define kAfsButtonStartup NSLocalizedStringFromTableInBundle(@"AfsButtonStartup",nil,[NSBundle bundleForClass:[self class]],@"AfsButtonStartup") +#define kNewCellName NSLocalizedStringFromTableInBundle(@"NewCellName",nil,[NSBundle bundleForClass:[self class]],@"NewCellName") +#define kNewCellComment NSLocalizedStringFromTableInBundle(@"NewCellComment",nil,[NSBundle bundleForClass:[self class]],@"NewCellComment") +#define kMenuLogin NSLocalizedStringFromTableInBundle(@"MenuLogin",nil,[NSBundle bundleForClass:[self class]],@"MenuLogin") +#define kMenuUnlog NSLocalizedStringFromTableInBundle(@"MenuUnlog",nil,[NSBundle bundleForClass:[self class]],@"MenuUnlog") +#define kBadAfsRootMountPoint NSLocalizedStringFromTableInBundle(@"BadAfsRootMountPoint",nil,[NSBundle bundleForClass:[self class]],@"BadAfsRootMountPoint") +#define kDoYouWantCreateTheDirectory NSLocalizedStringFromTableInBundle(@"DoYouWantCreateTheDirectory",nil,[NSBundle bundleForClass:[self class]],@"DoYouWantCreateTheDirectory") +#define kDirectoryCreated NSLocalizedStringFromTableInBundle(@"DirectoryCreated",nil,[NSBundle bundleForClass:[self class]],@"DirectoryCreated") +#define kErrorCreatingDirectory NSLocalizedStringFromTableInBundle(@"ErrorCreatingDirectory",nil,[NSBundle bundleForClass:[self class]],@"ErrorCreatingDirectory") +#define kErrorGettongSystemVersion NSLocalizedString(@"ErrorGettongSystemVersion",@"ErrorGettongSystemVersion"); + + +// PREFERENCE KEY +#define PREFERENCE_AFS_SYS_PAT @"PREFERENCE_AFS_SYS_PAT" +#define PREFERENCE_AFS_SYS_PAT_STATIC @"/var/db/openafs" +#define PREFERENCE_USE_AKLOG @"PREFERENCE_USE_AKLOG" +#define PREFERENCE_START_AFS_AT_STARTUP @"PREFERENCE_START_AFS_AT_STARTUP" + +// AFSMENUEXTRA INFO +#define kAFSMenuExtra [NSURL fileURLWithPath:[[self bundle] pathForResource:@"AFSMenuExtra" ofType:@"menu" inDirectory:@""]] +#define kMenuCrakerMenuExtra [NSURL fileURLWithPath:[[self bundle] pathForResource:@"MenuCracker" ofType:@"menu" inDirectory:@""]] +#define kAFSMenuExtraID @"it.infn.lnf.network.AFSMenuExtra" +#define kMenuCrakerMenuExtraID @"net.sourceforge.menucracker2" + + +//Application id +#define afsCommanderID @"it.infn.lnf.network.openafs" +// Changed preference notification key +#define kPrefChangeNotification @"preference_changed" +//KLog menuextra window close +#define kLogWindowClosed @"klog_window_closed" +//Fired when some work as appened in AFSMenuExtra +#define kMenuExtraEventOccured @"menu_extra_event_occured" +// Changed preference notification key +#define kMExtraClosedNotification @"preference_changed" +// Update MenuExtra AfsState notification key +#define kMExtraAFSStateChange @"menu_extra_afs_state_change" + diff --git a/src/platform/DARWIN/AFSPreference/hasToken.png b/src/platform/DARWIN/AFSPreference/hasToken.png new file mode 100644 index 0000000000000000000000000000000000000000..d2dcda0f1b02b2bde700be156c88f8ce48d4b821 GIT binary patch literal 3679 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 U?uM-+&j0`b07*qoM6N<$f=&&=i2wiq literal 0 HcmV?d00001 diff --git a/src/platform/DARWIN/AFSPreference/start_afs.sh b/src/platform/DARWIN/AFSPreference/start_afs.sh new file mode 100755 index 000000000..1cdd9c735 --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/start_afs.sh @@ -0,0 +1,111 @@ +#!/bin/sh + +# start_afs.sh +# +# +# Created by Claudio Bisegni on 24/06/07. +# Copyright 2007 INFN. All rights reserved. +# +# Portions Copyright (c) 2003 Apple Computer, Inc. +# +# Updated to match standard service scripts +# Phil Holland + +. /etc/rc.common + +CheckForNetwork + +VICEETC=$1/etc +AFSD=$2 + +CONFIG=$VICEETC/config +AFSDOPT=$CONFIG/afsd.options +PACKAGE=$CONFIG/package.options +VERBOSE= +if [ -x /usr/sbin/kextstat ]; then KMODSTAT=/usr/sbin/kextstat; fi +if [ -x /usr/sbin/kmodstat ]; then KMODSTAT=/usr/sbin/kmodstat; fi + + +if [ -f $CONFIG/afs.conf ]; then + . $CONFIG/afs.conf +fi + +# Check this file second so that if users have altered the file, it will +# override the default options +if [ -f $AFSDOPT ]; then + OPTIONS=`cat $AFSDOPT` +fi + + echo "Starting OpenAFS" + + if [ -z "$OPTIONS" ] || [ "$OPTIONS" = "AUTOMATIC" ] ; then + AFSD_OPTIONS="$VERBOSE" + else + AFSD_OPTIONS="$OPTIONS $VERBOSE" + fi + + if [ "${NETWORKUP}" = "-NO-" ]; then + echo $AFSD_OPTIONS | grep -e '-dynroot' || exit + fi + +# Need the commands ps, awk, kill, sleep + PATH=${PATH}${PATH:+:}/sbin:/bin:/usr/bin + + if [ -d $VICEETC/afs.kext ]; then + echo "Loading AFS kernel extensions" + kextload $VICEETC/afs.kext + else + echo "$VICEETC/afs.kext does not exist. Skipping AFS startup." + exit 1 + fi + + if $KMODSTAT | perl -e 'exit not grep /openafs/, <>' ; then + : + else + echo "AFS kernel extensions failed to initialize. Skipping AFS startup." + exit 1 + fi + +# +# Check that all of the client configuration files exist +# + + for file in $AFSD $VICEETC/cacheinfo \ + $VICEETC/ThisCell $VICEETC/CellServDB + do + if [ ! -f ${file} ]; then + echo "${file} does not exist. Not starting AFS client." + exit 1 + fi + done + +# +# Check that the root directory for AFS (/afs) +# and the cache directory (/usr/vice/cache) both exist +# + + for dir in `awk -F: '{print $1, $2}' $VICEETC/cacheinfo` + do + if [ ! -d ${dir} ]; then + echo "${dir} does not exist. Not starting AFS client." + exit 2 + fi + done + + echo "Starting afsd" + $AFSD $AFSD_OPTIONS + +# +# From /var/db/openafs/etc/config/afs.conf, call a post-init function or +# command if it's been defined +# + $AFS_POST_INIT + +# +# Call afssettings (if it exists) to set customizable parameters +# + if [ -x $CONFIG/afssettings ]; then + sleep 2 + $CONFIG/afssettings + fi + diff --git a/src/platform/DARWIN/AFSPreference/stop_afs.sh b/src/platform/DARWIN/AFSPreference/stop_afs.sh new file mode 100755 index 000000000..301b8b06f --- /dev/null +++ b/src/platform/DARWIN/AFSPreference/stop_afs.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# stop_afs.sh +# +# +# Created by Claudio Bisegni on 24/06/07. +# Copyright 2007 INFN. All rights reserved. + +VICEETC=$1/etc +AFSD=$2 +echo "Stopping AFS" + +echo "Unmounting /afs" +umount -f /afs 2>&1 > /dev/console + +echo "Shutting down afsd processes" +$AFSD -shutdown 2>&1 > /dev/console + +echo "Unloading AFS kernel extensions" +kextunload $VICEETC/afs.kext 2>&1 > /dev/console + -- 2.39.5