home *** CD-ROM | disk | FTP | other *** search
Wrap
/* ResolverWindowController.m created by andrew on Sat 05-Jul-1997 */ #import "ResolverWindowController.h" #import <Foundation/Foundation.h> #import <AppKit/AppKit.h> #import <NIAccess/NIAccess.h> #import <NIInterface/NIInterface.h> // for geteuid #import <System/bsd/sys/types.h> #import <System/bsd/unistd.h> @interface ResolverWindowController (Private) - (NIDirectory *)_resolverDirectoryCreateIfNeeded:(BOOL)createIfNeeded; - (NIDirectory *)_resolverDirectory; @end @implementation ResolverWindowController static NSString *netinfoAuthenticationBugString = nil; static NSString *savePartialAttributesString = nil; static NSString *authenticationFailedString = nil; static NSString *canNotSaveChangesString = nil; static NSString *nameserverIPString = nil; static NSString *canNotCreateNIDirectoryString = nil; static NSString *canNotCreateParticularNIDirectoryString = nil; static NSString *saveString = nil; static NSString *cancelString = nil; static NSMutableArray *windowControllers = nil; + (void)initialize; { static BOOL initialized = NO; [super initialize]; if (initialized) return; initialized = YES; windowControllers = [[NSMutableArray alloc] init]; netinfoAuthenticationBugString = NSLocalizedString (@"NetInfoAuthenticationBug", user has hit up against the netinfo authentication crasher); savePartialAttributesString = NSLocalizedString (@"SavePartialAttributes", user has defined only a subset of the attributes - which can be bad); authenticationFailedString = NSLocalizedString (@"AuthenticationFailed", user entered an incorrect password for the NetInfo domain); canNotSaveChangesString = NSLocalizedString (@"CanNotSaveChangesWithReason", unable to save changes for some reason); nameserverIPString = NSLocalizedString (@"NameserverIPAddress", prompt to enter a nameserver IP); canNotCreateNIDirectoryString = NSLocalizedString (@"CanNotCreateNIDirectory", unable to create a NetInfo directory); canNotCreateParticularNIDirectoryString = NSLocalizedString (@"CanNotCreateParticularNIDirectory", unable to create a specific NetInfo directory); saveString = NSLocalizedString (@"Save", save prompt); cancelString = NSLocalizedString (@"Cancel", cancel prompt); } + resolverWindowControllerForDomain:(NIDomain *)aDomain; { NSEnumerator *enumerator; ResolverWindowController *controller; enumerator = [windowControllers objectEnumerator]; while ((controller = [enumerator nextObject])) if ([[controller domain] isEqual:aDomain]) return controller; controller = [[self alloc] initWithDomain:aDomain]; [controller release]; return controller; } + resolverWindowControllerForLocalDomain; { return [self resolverWindowControllerForDomain:[NIDomain localDomain]]; } + resolverWindowControllerForRootDomain; { return [self resolverWindowControllerForDomain:[NIDomain rootDomain]]; } + (BOOL)applicationShouldTerminate:(NSApplication *)application; { NSEnumerator *enumerator; ResolverWindowController *controller; enumerator = [windowControllers objectEnumerator]; while ((controller = [enumerator nextObject])) if (![controller shouldClose]) return NO; enumerator = [windowControllers objectEnumerator]; while ((controller = [enumerator nextObject])) [controller close]; return YES; } - init; { return [self initWithDomain:[NIDomain localDomain]]; } - initWithDomain:(NIDomain *)aDomain; { [super initLazily]; domain = [aDomain retain]; nameservers = [[NSMutableArray alloc] initWithCapacity:2]; [windowControllers addObject:self]; return self; } - (void)dealloc; { [domain release]; [nameservers release]; [super dealloc]; } - (NIDomain *)domain; { return domain; } - (void)revertChanges; { NIDirectory *resolverDirectory; [super revertChanges]; resolverDirectory = [self _resolverDirectory]; if (resolverDirectory) { NSString *domainName; domainName = [resolverDirectory firstValueForKey:@"domain"]; [domainField setStringValue:domainName ? domainName : @""]; [nameservers release]; nameservers = [[NSMutableArray alloc] initWithArray:[resolverDirectory valuesForKey:@"nameserver"]]; } else { [domainField setStringValue:@""]; [nameservers release]; nameservers = [[NSMutableArray alloc] initWithCapacity:2]; } [nameserverTable reloadData]; } - (void)prepareToSaveChanges; { NSString *domainName; int numAttributes; [super prepareToSaveChanges]; [window makeFirstResponder:window]; // try to ensure that both attributes (or neither) are set numAttributes = 0; domainName = [domainField stringValue]; if ([domainName length] > 0) numAttributes++; if ([nameservers count] > 0) numAttributes++; #warning AFA: it would be nice to validate the actual IP addresses here, and ask the user to confirm them if we are unable to reach any if ((numAttributes != 2) && (numAttributes != 0)) { int choice; choice = NSRunAlertPanel (nil, savePartialAttributesString, saveString, cancelString, nil); if (choice != NSAlertDefaultReturn) [NSException raise:@"DidNotSave" format:@"User cancelled save operation"]; } // see if we can avoid the authentication panel if (!authenticated) { // if the user is editing a domain on the current host and they are root, no need to authenticate if ([[[domain currentServer] host] isEqual:[NSHost currentHost]]) authenticated = (geteuid() == 0); } // authenticate user if (!authenticated) { NIAuthenticationPanel *authenticationPanel; #warning AFA: workaround for NetInfo bug: if the local domain is also the root domain, the app will croak when the user hits the "authenticate" button (on OPENSTEP the root must also have no password?) if ([[[[NSBundle mainBundle] infoDictionary] objectForKey:@"useNetInfoAuthenticationHack"] isEqualToString:@"YES"]) { NSHost *currentHost; currentHost = [NSHost currentHost]; if (([[[domain currentServer] host] isEqual:currentHost]) && ([[[[NIDomain rootDomain] currentServer] host] isEqual:currentHost])) { NSRunAlertPanel(nil, netinfoAuthenticationBugString, nil, nil, nil); [NSException raise:@"NetInfoAuthenticationBug" format:netinfoAuthenticationBugString]; } } authenticationPanel = [NIAuthenticationPanel authenticationPanel]; authenticated = [authenticationPanel runModalForDomain:domain]; } if (!authenticated) { NSRunAlertPanel (nil, authenticationFailedString, nil, nil, nil); [NSException raise:@"DidNotSave" format:authenticationFailedString]; } } - (void)saveChanges; { NIDirectory *resolverDirectory; NSString *domainName; [super saveChanges]; // get the resolver directory - create if necessary NS_DURING { resolverDirectory = [self _resolverDirectoryCreateIfNeeded:YES]; } NS_HANDLER { NSRunAlertPanel (nil, canNotSaveChangesString, nil, nil, nil, [localException reason]); [NSException raise:@"DidNotSave" format:@"Error finding or creating resolver directory"]; } NS_ENDHANDLER; // save the domain domainName = [domainField stringValue]; if ([domainName length] > 0) [resolverDirectory replaceValues:[NSArray arrayWithObject:domainName] forKey:@"domain"]; else [resolverDirectory removeKey:@"domain"]; // save the DNS servers if ([nameservers count] > 0) [resolverDirectory replaceValues:nameservers forKey:@"nameserver"]; else [resolverDirectory removeKey:@"nameserver"]; // if the resolver directory is empty, it can be bad to leave it around - destroy it // (keys == 1 means we're empty - the last one must [well, should] be the name key) if ((![resolverDirectory hasSubdirectories]) && ([[resolverDirectory allKeys] count] == 1)) [resolverDirectory destroy]; } - (void)newNameServer:sender; { int count; count = [nameservers count]; if (count == 0) [nameservers addObject:nameserverIPString]; else [nameservers addObject:[[nameservers objectAtIndex:count - 1] copy]]; [nameserverTable reloadData]; [nameserverTable selectRow:count byExtendingSelection:NO]; [nameserverTable editColumn:0 row:count withEvent:nil select:YES]; [window setDocumentEdited:YES]; } - (void)deleteNameServer:sender; { NSEnumerator *enumerator; NSMutableArray *deletedServers; NSString *server; NSNumber *row; deletedServers = [NSMutableArray arrayWithCapacity:2]; enumerator = [nameserverTable selectedRowEnumerator]; while ((row = [enumerator nextObject])) [deletedServers addObject:[nameservers objectAtIndex:[row intValue]]]; enumerator = [deletedServers objectEnumerator]; while ((server = [enumerator nextObject])) [nameservers removeObjectIdenticalTo:server]; [nameserverTable reloadData]; [window setDocumentEdited:YES]; } @end @implementation ResolverWindowController (WindowControllerSubclass) - (void)load; { [super load]; [window setTitle:[domain name]]; [nameserverTable setDataSource:self]; [self revert:nil]; } @end @implementation ResolverWindowController (NSTableViewDataSource) - (int)numberOfRowsInTableView:(NSTableView *)aTableView; { return [nameservers count]; } - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row; { return [nameservers objectAtIndex:row]; } - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row; { NSString *oldNameserver; oldNameserver = [nameservers objectAtIndex:row]; if ([oldNameserver isEqualToString:object]) return; [window setDocumentEdited:YES]; [nameservers replaceObjectAtIndex:row withObject:object]; } @end @implementation ResolverWindowController (Private) - (NIDirectory *)_resolverDirectoryCreateIfNeeded:(BOOL)createIfNeeded; { NIDirectory *resolverDirectory; resolverDirectory = [domain directoryWithPath:@"/locations/resolver"]; if (!resolverDirectory && createIfNeeded) { NIDirectory *rootDirectory; rootDirectory = [domain directoryWithPath:@"/"]; if (![rootDirectory createPath:@"locations/resolver"]) [NSException raise:canNotCreateNIDirectoryString format:canNotCreateParticularNIDirectoryString, @"/locations/resolver"]; resolverDirectory = [domain directoryWithPath:@"/locations/resolver"]; } return resolverDirectory; } - (NIDirectory *)_resolverDirectory; { NIDirectory *resolverDirectory = nil; NS_DURING { resolverDirectory = [self _resolverDirectoryCreateIfNeeded:NO]; } NS_HANDLER { NSRunAlertPanel (nil, [localException reason], nil, nil, nil); } NS_ENDHANDLER; return resolverDirectory; } @end @implementation ResolverWindowController (NSWindowDelegate) - (void)windowWillClose:(NSNotification *)notification; { [super windowWillClose:notification]; [[self retain] autorelease]; // ensure we aren't freed by next line [windowControllers removeObject:self]; } @end