home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / OPENSTEP / Connectivity / OmniDNSHelper-1.0b3 / ResolverWindowController.m < prev    next >
Encoding:
Text File  |  1997-10-29  |  11.2 KB  |  370 lines

  1. /* ResolverWindowController.m created by andrew on Sat 05-Jul-1997 */
  2.  
  3.  
  4. #import "ResolverWindowController.h"
  5.  
  6.  
  7. #import <Foundation/Foundation.h>
  8. #import <AppKit/AppKit.h>
  9. #import <NIAccess/NIAccess.h>
  10. #import <NIInterface/NIInterface.h>
  11. // for geteuid
  12. #import <System/bsd/sys/types.h>
  13. #import <System/bsd/unistd.h>
  14.  
  15.  
  16. @interface ResolverWindowController (Private)
  17. - (NIDirectory *)_resolverDirectoryCreateIfNeeded:(BOOL)createIfNeeded;
  18. - (NIDirectory *)_resolverDirectory;
  19. @end
  20.  
  21.  
  22. @implementation ResolverWindowController
  23.  
  24. static NSString *netinfoAuthenticationBugString = nil;
  25. static NSString *savePartialAttributesString = nil;
  26. static NSString *authenticationFailedString = nil;
  27. static NSString *canNotSaveChangesString = nil;
  28. static NSString *nameserverIPString = nil;
  29. static NSString *canNotCreateNIDirectoryString = nil;
  30. static NSString *canNotCreateParticularNIDirectoryString = nil;
  31. static NSString *saveString = nil;
  32. static NSString *cancelString = nil;
  33.  
  34. static NSMutableArray *windowControllers = nil;
  35.  
  36. + (void)initialize;
  37. {
  38.     static BOOL initialized = NO;
  39.     
  40.     [super initialize];
  41.  
  42.     if (initialized)
  43.         return;
  44.  
  45.     initialized = YES;
  46.  
  47.     windowControllers = [[NSMutableArray alloc] init];
  48.  
  49.     netinfoAuthenticationBugString = NSLocalizedString (@"NetInfoAuthenticationBug", user has hit up against the netinfo authentication crasher);
  50.     savePartialAttributesString = NSLocalizedString (@"SavePartialAttributes", user has defined only a subset of the attributes - which can be bad);
  51.     authenticationFailedString = NSLocalizedString (@"AuthenticationFailed", user entered an incorrect password for the NetInfo domain);
  52.     canNotSaveChangesString = NSLocalizedString (@"CanNotSaveChangesWithReason", unable to save changes for some reason);
  53.     nameserverIPString = NSLocalizedString (@"NameserverIPAddress", prompt to enter a nameserver IP);
  54.     canNotCreateNIDirectoryString = NSLocalizedString (@"CanNotCreateNIDirectory", unable to create a NetInfo directory);
  55.     canNotCreateParticularNIDirectoryString = NSLocalizedString (@"CanNotCreateParticularNIDirectory", unable to create a specific NetInfo directory);
  56.     saveString = NSLocalizedString (@"Save", save prompt);
  57.     cancelString = NSLocalizedString (@"Cancel", cancel prompt);
  58. }
  59.  
  60. + resolverWindowControllerForDomain:(NIDomain *)aDomain;
  61. {
  62.     NSEnumerator *enumerator;
  63.     ResolverWindowController *controller;
  64.  
  65.     enumerator = [windowControllers objectEnumerator];
  66.     while ((controller = [enumerator nextObject]))
  67.         if ([[controller domain] isEqual:aDomain])
  68.             return controller;
  69.     
  70.     controller = [[self alloc] initWithDomain:aDomain];
  71.     [controller release];
  72.  
  73.     return controller;
  74. }
  75.  
  76. + resolverWindowControllerForLocalDomain;
  77. {
  78.     return [self resolverWindowControllerForDomain:[NIDomain localDomain]];
  79. }
  80.  
  81. + resolverWindowControllerForRootDomain;
  82. {
  83.     return [self resolverWindowControllerForDomain:[NIDomain rootDomain]];
  84. }
  85.  
  86. + (BOOL)applicationShouldTerminate:(NSApplication *)application;
  87. {
  88.     NSEnumerator *enumerator;
  89.     ResolverWindowController *controller;
  90.  
  91.     enumerator = [windowControllers objectEnumerator];
  92.     while ((controller = [enumerator nextObject]))
  93.         if (![controller shouldClose])
  94.             return NO;
  95.  
  96.     enumerator = [windowControllers objectEnumerator];
  97.     while ((controller = [enumerator nextObject]))
  98.         [controller close];
  99.     
  100.     return YES;
  101. }
  102.  
  103. - init;
  104. {
  105.     return [self initWithDomain:[NIDomain localDomain]];
  106. }
  107.  
  108. - initWithDomain:(NIDomain *)aDomain;
  109. {
  110.     [super initLazily];
  111.     domain = [aDomain retain];
  112.     nameservers = [[NSMutableArray alloc] initWithCapacity:2];
  113.     [windowControllers addObject:self];
  114.  
  115.     return self;
  116. }
  117.  
  118. - (void)dealloc;
  119. {
  120.     [domain release];
  121.     [nameservers release];
  122.     [super dealloc];
  123. }
  124.  
  125. - (NIDomain *)domain;
  126. {
  127.     return domain;
  128. }
  129.  
  130. - (void)revertChanges;
  131. {
  132.     NIDirectory *resolverDirectory;
  133.  
  134.     [super revertChanges];
  135.     
  136.     resolverDirectory = [self _resolverDirectory];
  137.     if (resolverDirectory) {
  138.         NSString *domainName;
  139.  
  140.         domainName = [resolverDirectory firstValueForKey:@"domain"];
  141.         [domainField setStringValue:domainName ? domainName : @""];
  142.         [nameservers release];
  143.         nameservers = [[NSMutableArray alloc] initWithArray:[resolverDirectory valuesForKey:@"nameserver"]];
  144.     } else {
  145.         [domainField setStringValue:@""];
  146.         [nameservers release];
  147.         nameservers = [[NSMutableArray alloc] initWithCapacity:2];
  148.     }
  149.     [nameserverTable reloadData];
  150. }
  151.  
  152. - (void)prepareToSaveChanges;
  153. {
  154.     NSString *domainName;
  155.     int numAttributes;
  156.  
  157.     [super prepareToSaveChanges];
  158.     [window makeFirstResponder:window];
  159.  
  160.     // try to ensure that both attributes (or neither) are set
  161.     numAttributes = 0;
  162.  
  163.     domainName = [domainField stringValue];
  164.     if ([domainName length] > 0)
  165.         numAttributes++;
  166.  
  167.     if ([nameservers count] > 0)
  168.         numAttributes++;
  169. #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
  170.  
  171.     if ((numAttributes != 2) && (numAttributes != 0)) {
  172.         int choice;
  173.  
  174.         choice = NSRunAlertPanel (nil, savePartialAttributesString, saveString, cancelString, nil);
  175.         if (choice != NSAlertDefaultReturn)
  176.             [NSException raise:@"DidNotSave" format:@"User cancelled save operation"];
  177.     }
  178.  
  179.     // see if we can avoid the authentication panel
  180.     if (!authenticated) {
  181.         // if the user is editing a domain on the current host and they are root, no need to authenticate
  182.         if ([[[domain currentServer] host] isEqual:[NSHost currentHost]])
  183.             authenticated = (geteuid() == 0);
  184.     }
  185.     
  186.     // authenticate user
  187.     if (!authenticated) {
  188.         NIAuthenticationPanel *authenticationPanel;
  189.  
  190. #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?)
  191.         if ([[[[NSBundle mainBundle] infoDictionary] objectForKey:@"useNetInfoAuthenticationHack"] isEqualToString:@"YES"]) {
  192.             NSHost *currentHost;
  193.  
  194.             currentHost = [NSHost currentHost];
  195.             if (([[[domain currentServer] host] isEqual:currentHost]) && ([[[[NIDomain rootDomain] currentServer] host] isEqual:currentHost])) {
  196.                 NSRunAlertPanel(nil, netinfoAuthenticationBugString, nil, nil, nil);
  197.                 [NSException raise:@"NetInfoAuthenticationBug" format:netinfoAuthenticationBugString];
  198.             }
  199.         }
  200.  
  201.         authenticationPanel = [NIAuthenticationPanel authenticationPanel];
  202.         authenticated = [authenticationPanel runModalForDomain:domain];
  203.     }
  204.     
  205.     if (!authenticated) {
  206.         NSRunAlertPanel (nil, authenticationFailedString, nil, nil, nil);
  207.         [NSException raise:@"DidNotSave" format:authenticationFailedString];
  208.     }
  209. }
  210.  
  211. - (void)saveChanges;
  212. {
  213.     NIDirectory *resolverDirectory;
  214.     NSString *domainName;
  215.  
  216.     [super saveChanges];
  217.  
  218.     // get the resolver directory - create if necessary
  219.     NS_DURING {
  220.         resolverDirectory = [self _resolverDirectoryCreateIfNeeded:YES];
  221.     } NS_HANDLER {
  222.         NSRunAlertPanel (nil, canNotSaveChangesString, nil, nil, nil, [localException reason]);
  223.         [NSException raise:@"DidNotSave" format:@"Error finding or creating resolver directory"];
  224.     } NS_ENDHANDLER;
  225.  
  226.     // save the domain
  227.     domainName = [domainField stringValue];
  228.     if ([domainName length] > 0)
  229.         [resolverDirectory replaceValues:[NSArray arrayWithObject:domainName] forKey:@"domain"];
  230.     else
  231.         [resolverDirectory removeKey:@"domain"];
  232.  
  233.     // save the DNS servers
  234.     if ([nameservers count] > 0)
  235.         [resolverDirectory replaceValues:nameservers forKey:@"nameserver"];
  236.     else
  237.         [resolverDirectory removeKey:@"nameserver"];
  238.  
  239.     // if the resolver directory is empty, it can be bad to leave it around - destroy it
  240.     // (keys == 1 means we're empty - the last one must [well, should] be the name key)
  241.     if ((![resolverDirectory hasSubdirectories]) && ([[resolverDirectory allKeys] count] == 1))
  242.         [resolverDirectory destroy];
  243. }
  244.  
  245. - (void)newNameServer:sender;
  246. {
  247.     int count;
  248.  
  249.     count = [nameservers count];
  250.     if (count == 0)
  251.         [nameservers addObject:nameserverIPString];
  252.     else
  253.         [nameservers addObject:[[nameservers objectAtIndex:count - 1] copy]];
  254.     [nameserverTable reloadData];
  255.     [nameserverTable selectRow:count byExtendingSelection:NO];
  256.     [nameserverTable editColumn:0 row:count withEvent:nil select:YES];
  257.     
  258.     [window setDocumentEdited:YES];
  259. }
  260.  
  261. - (void)deleteNameServer:sender;
  262. {
  263.     NSEnumerator *enumerator;
  264.     NSMutableArray *deletedServers;
  265.     NSString *server;
  266.     NSNumber *row;
  267.  
  268.     deletedServers = [NSMutableArray arrayWithCapacity:2];
  269.     
  270.     enumerator = [nameserverTable selectedRowEnumerator];
  271.     while ((row = [enumerator nextObject]))
  272.         [deletedServers addObject:[nameservers objectAtIndex:[row intValue]]];
  273.  
  274.     enumerator = [deletedServers objectEnumerator];
  275.     while ((server = [enumerator nextObject]))
  276.         [nameservers removeObjectIdenticalTo:server];
  277.  
  278.     [nameserverTable reloadData];
  279.     
  280.     [window setDocumentEdited:YES];
  281. }
  282.  
  283. @end
  284.  
  285.  
  286. @implementation ResolverWindowController (WindowControllerSubclass)
  287.  
  288. - (void)load;
  289. {
  290.     [super load];
  291.     [window setTitle:[domain name]];
  292.     [nameserverTable setDataSource:self];
  293.     [self revert:nil];
  294. }
  295.  
  296. @end
  297.  
  298.  
  299. @implementation ResolverWindowController (NSTableViewDataSource)
  300.  
  301. - (int)numberOfRowsInTableView:(NSTableView *)aTableView;
  302. {
  303.     return [nameservers count];
  304. }
  305.  
  306. - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row;
  307. {
  308.     return [nameservers objectAtIndex:row];
  309. }
  310.  
  311. - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(int)row;
  312. {
  313.     NSString *oldNameserver;
  314.  
  315.     oldNameserver = [nameservers objectAtIndex:row];
  316.     if ([oldNameserver isEqualToString:object])
  317.         return;
  318.     [window setDocumentEdited:YES];
  319.     [nameservers replaceObjectAtIndex:row withObject:object];
  320. }
  321.  
  322. @end
  323.  
  324.  
  325. @implementation ResolverWindowController (Private)
  326.  
  327. - (NIDirectory *)_resolverDirectoryCreateIfNeeded:(BOOL)createIfNeeded;
  328. {
  329.     NIDirectory *resolverDirectory;
  330.  
  331.     resolverDirectory = [domain directoryWithPath:@"/locations/resolver"];
  332.     if (!resolverDirectory && createIfNeeded) {
  333.         NIDirectory *rootDirectory;
  334.  
  335.         rootDirectory = [domain directoryWithPath:@"/"];
  336.         if (![rootDirectory createPath:@"locations/resolver"])
  337.             [NSException raise:canNotCreateNIDirectoryString format:canNotCreateParticularNIDirectoryString, @"/locations/resolver"];
  338.         resolverDirectory = [domain directoryWithPath:@"/locations/resolver"];
  339.     }
  340.  
  341.     return resolverDirectory;
  342. }
  343.  
  344. - (NIDirectory *)_resolverDirectory;
  345. {
  346.     NIDirectory *resolverDirectory = nil;
  347.     
  348.     NS_DURING {
  349.         resolverDirectory = [self _resolverDirectoryCreateIfNeeded:NO];
  350.     } NS_HANDLER {
  351.         NSRunAlertPanel (nil, [localException reason], nil, nil, nil);
  352.     } NS_ENDHANDLER;
  353.  
  354.     return resolverDirectory;
  355. }
  356.  
  357. @end
  358.  
  359.  
  360. @implementation ResolverWindowController (NSWindowDelegate)
  361.  
  362. - (void)windowWillClose:(NSNotification *)notification;
  363. {
  364.     [super windowWillClose:notification];
  365.     [[self retain] autorelease];        // ensure we aren't freed by next line
  366.     [windowControllers removeObject:self];
  367. }
  368.  
  369. @end
  370.