This is Hosts.m in view mode; [Download] [Up]
/* SambaManger. A graphical frontend to configure the NetInfo enhanced samba. Copyright (C) 1998 Robert Frank This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Robert Frank, frank@ifi.unibas.ch */ #import "Hosts.h" #import "Controller.h" #import "NIDirectory.h" #import "NIProperty.h" #import "NetInfoKeys.h" // The property names of a host's directory: #define H_NAME "name" #define H_NETBIOSNAME "netbios name" #define H_IPADDRESS "ip_address" #define H_ETHERNET "en_address" #define H_NETGROUPS "netgroups" #define H_SYSTEM "system_type" #define H_OWNER "owner" #define H_BOOTFILE "bootfile" #define H_BOOTPARAMS "bootparams" // Class variable with the string for the open/save panel's title. static const char *title; static unsigned char hexOk[128] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; @implementation Hosts // ************************************************************************ // ************************************************************************ // Class methods: + initialize // Called once by the run time system { title = [Service stringFor:"Title:Hosts"]; return self; } + new:sender at:(NXCoord *)offset { NIDirectory *NIDir; Hosts *host = [Hosts alloc]; if ((NIDir = [NIDirectory new:sender root:SMNI_HOSTS directory:NULL])) { [NIDir setDelegate:host]; if ([host init:sender dirObj:NIDir delta:offset service:NULL]) { [NIDir setSaveTitle:title]; return host; } [NIDir close]; } return [host free]; } + open:sender at:(NXCoord *)offset { NIDirectory *NIDir; Hosts *host = [Hosts alloc]; if ((NIDir = [NIDirectory open:sender root:SMNI_HOSTS withTitle:title])) { [NIDir setDelegate:host]; if ([host init:sender dirObj:NIDir delta:offset service:[NIDir baseName]]) return host; [NIDir close]; } return [host free]; } - getBootParms:parameter { int i; NIProperty *prop; const ni_namelist *values; if (!(prop = [ni_dirObj property:H_BOOTPARAMS])) return self; values = [prop valueList]; [textRootDirectory setStringValue:""]; [textPrivateDirectory setStringValue:""]; for (i = 0; i < values->ni_namelist_len; i++) if (!strncasecmp(values->ni_namelist_val[i], "root", 4)) [textRootDirectory setStringValue:values->ni_namelist_val[i]+5]; else if (!strncasecmp(values->ni_namelist_val[i], "private", 7)) [textPrivateDirectory setStringValue:values->ni_namelist_val[i]+8]; return self; } - setBootParms { char *root = NULL, *private = NULL; const char *s = NULL; NIProperty *prop; if (!(prop = [ni_dirObj property:H_BOOTPARAMS])) return nil; s = [textRootDirectory stringValue]; if (s && *s) { root = (char *)NXZoneMalloc([self zone], strlen(s) + 6); strcpy(root, "root="); strcat(root, s); } s = [textPrivateDirectory stringValue]; if (s && *s) { private = (char *)NXZoneMalloc([self zone], strlen(s) + 9); strcpy(private, "private="); strcat(private, s); } // Search. If inexistant, create! If exists and root/private non-null, // update, otherwise delete [prop updateValue:root at:[prop findValue:"^root.*" how:NI_FIND_REGEX]]; [prop updateValue:private at:[prop findValue:"^private.*" how:NI_FIND_REGEX]]; if (root) NXZoneFree([self zone], root); if (private) NXZoneFree([self zone], private); return self; } - selectAlias:sender { [textAliases setStringValue:[[sender selectedCell] stringValue]]; [textAliases selectText:self]; return self; } - (BOOL)minimumOK { char value[32], *c = value; int l, ival; if (!*[textHostname stringValue] || !*[textInternetAddress stringValue]) { NXRunAlertPanel(getString("Alert:Alert"), getString("Message:Must have a name and address"), getString("Button:OK"),NULL,NULL); return NO; } // Let's check a few values for correctnes: // The Netbios name may be atmost 15 characters if (strlen([textNetbiosname stringValue]) > 15 ) { NXRunAlertPanel(getString("Alert:Alert"), getString("Message:Netbios Name may have atmost 15 characters."), getString("Button:OK"),NULL,NULL); return NO; } // The IP address must be four values with three dots: // nnn.nnn.nnn.nnn bzero(value, 32); if (*strncpy(value, [textInternetAddress stringValue], 30)) { value[strlen(value)] = '.'; for (l = 4; l && c; l--) { ival = atoi(c); if ((ival > 0) && (ival < 256)) { if (c = strchr(c, '.')) c++; } else c = NULL; } if (!c) { NXRunAlertPanel(getString("Alert:Alert"), getString("Message:Invalid IP address.\nMust be of the form: `nnn.nnn.nnn.nnn'."), getString("Button:OK"),NULL,NULL); return NO; } } // The Ethernet address must be six hex values with five colons, // no leading zeros: 0:0:f:0:81:f9 bzero(value, 32); c = value; if (*strncpy(value, [textEthernetAddress stringValue], 30)) { value[strlen(value)] = ':'; for (l = 6; l && c; l--) { if (!hexOk[*c++&0x7f]) { c = NULL; break; } if (*c != ':') if (!((*(c-1) != '0') && hexOk[*c++&0x7f])) { c = NULL; break; } if (*c != ':') c = NULL; else c++; } if (!c) { NXRunAlertPanel(getString("Alert:Alert"), getString("Message:Invalid Ethernet address.\nMust be: `hh:hh:hh:hh:hh:hh' with no leading zeros."), getString("Button:OK"),NULL,NULL); return NO; } } return YES; } // ************************************************************************ // Methods: - revert:sender { [super revert:sender]; [browserAliases loadColumnZero]; return self; } - delete:sender { if (!strcmp([ni_dirObj baseName], "localhost") || !strcmp([ni_dirObj baseName], "broadcasthost")) { NXRunAlertPanel(getString("Alert:Alert"), getString("Message:Cannot delete localhost or broadcasthost!"), getString("Button:OK"), NULL, NULL); return self; } return [super delete:self]; } - setupAndLoad { NIProperty *nbname, *name; char *NBName, *p; // Initialize the parameter list name = [ni_dirObj addString:H_NAME outlet:textHostname]; nbname = [ni_dirObj addString:H_NETBIOSNAME outlet:textNetbiosname]; [ni_dirObj addString:H_IPADDRESS outlet:textInternetAddress]; [ni_dirObj addString:H_ETHERNET outlet:textEthernetAddress]; [ni_dirObj addString:H_OWNER outlet:textSystemOwner]; [ni_dirObj addPopup:H_SYSTEM outlet:popupSystemType default:"Unknown"]; [ni_dirObj addBrowser:H_NETGROUPS browser:browserNetGroups text:textNetgroups add:buttonAddNetGroup remove:buttonDelNetGroup]; [ni_dirObj addString:H_BOOTFILE outlet:textKernel]; [ni_dirObj addCall:H_BOOTPARAMS displayAction:@selector(getBootParms:)]; // Scan the loaded NetInfo values and update the GUI. [ni_dirObj scan]; // Check for a netbios name. If none exists, uppercase the hostname. if (([nbname index] == NI_VALUE_NOT_FOUND) && (*[name valueAt:0])) { NBName = NXCopyStringBufferFromZone([name valueAt:0],[self zone]); for (p = NBName; *p; p++) *p = NXToUpper(*p); [nbname insertValue:NBName]; [textNetbiosname setStringValue:NBName]; NXZoneFree([self zone], NBName); } // Set up the alias browser and text. [browserAliases setDelegate:self]; [browserAliases setAction:@selector(selectAlias:)]; [browserAliases loadColumnZero]; [textAliases setTextDelegate:self]; [textRootDirectory setTextDelegate:self]; [textPrivateDirectory setTextDelegate:self]; // Select the top field. [textHostname selectText:self]; return self; } // ************************************************************************ // Actions: - addAlias:sender { const char *v; int i; NIProperty *prop; const ni_namelist *values; if (!(prop = [ni_dirObj property:H_NAME])) return 0; values = [prop valueList]; v = [textAliases stringValue]; if (values->ni_namelist_len) { for (i = 1; i < values->ni_namelist_len; i++) if (!strcasecmp(values->ni_namelist_val[i], v)) { [[browserAliases matrixInColumn:0] selectCellAt:i-1 :0]; return self; } else if (strcasecmp(values->ni_namelist_val[i], v) > 0) break; [prop insertValue:v at:i--]; [window setDocEdited:YES]; [browserAliases reloadColumn:0]; [[browserAliases matrixInColumn:0] selectCellAt:i :0]; [textAliases selectText:self]; } return self; } - removeAlias:sender { int i; NIProperty *prop; const ni_namelist *values; id cell = [browserAliases selectedCell]; if (!cell || !(prop = [ni_dirObj property:H_NAME])) return self; values = [prop valueList]; i = ni_namelist_match(*values, [[browserAliases selectedCell] stringValue]); if ((i != NI_INDEX_NULL) && (i > 0)) { // Must not delete the name! [prop deleteValue:i]; [window setDocEdited:YES]; [browserAliases reloadColumn:0]; i-= 2; // The browser starts with value index 1! if (i > 0) [[browserAliases matrixInColumn:0] selectCellAt:i :0]; else if (values->ni_namelist_len) [[browserAliases matrixInColumn:0] selectCellAt:0 :0]; } return self; } - setNetBoot:sender { BOOL edited = [window isDocEdited]; int signal; char *bootFile = NXCopyStringBufferFromZone([textKernel stringValue],[self zone]), *bootParms1 = NXCopyStringBufferFromZone([textRootDirectory stringValue],[self zone]), *bootParms2 = NXCopyStringBufferFromZone([textPrivateDirectory stringValue],[self zone]); [textKernel selectText:self]; // Run a modal for the panel. signal = [NXApp runModalFor:panel]; [panel close]; switch (signal) { case NX_RUNABORTED: // Restore to previos values [[ni_dirObj property:H_BOOTFILE] updateProperty:bootFile default:(!bootFile || !*bootFile)]; [textKernel setStringValue:bootFile]; [textRootDirectory setStringValue:bootParms1]; [textPrivateDirectory setStringValue:bootParms2]; [window setDocEdited:edited]; break; case NX_RUNSTOPPED: default: ; } NXZoneFree([self zone], bootFile); NXZoneFree([self zone], bootParms1); NXZoneFree([self zone], bootParms2); return self; } // Actions from the Net Boot configuration panel - configOK:sender { [NXApp stopModal]; [self setBootParms]; return self; } - configCancel:sender { [NXApp abortModal]; return self; } // ************************************************************************ // Delegates: - (BOOL)textWillEnd:textObject { const char *alert = NULL, *path = [[textObject superview] stringValue], *p = strchr(path,':'); if ([textObject superview] == textRootDirectory) alert = getString("Alert:Invalid root directory."); else if ([textObject superview] == textPrivateDirectory) alert = getString("Alert:Invalid private directory."); // Accept the empty input and check for ':/'. if (alert && path && *path && ((p && (*(p+1) != '/')) || !p)) { NXRunAlertPanel(getString("Alert:Alert"), alert, getString("Button:OK"), NULL, NULL); return YES; } return NO; } - textDidEnd:textObject endChar:(unsigned short)whyEnd { if (([textObject superview] == textAliases) && (whyEnd == NX_RETURN)) [self addAlias:self]; return self; } - (int) browser:sender fillMatrix:matrix inColumn:(int) column { NIProperty *prop; const ni_namelist *values; int rows = 0, i = 0; id cell; if (!(prop = [ni_dirObj property:H_NAME])) // Can be called before ni_dirObj is set. return 0; if ([prop index] == NI_INDEX_NULL) return 0; values = [prop valueList]; for (i = 1; i < values->ni_namelist_len; i++) { [matrix addRow]; cell = [matrix cellAt:rows :0]; [cell setStringValue:values->ni_namelist_val[i]]; [cell setLoaded:YES]; [cell setLeaf:YES]; rows++; } return rows; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.