This is Controller.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 "Controller.h"
#import "Users.h"
#import "Printers.h"
#import "Hosts.h"
#import "Services.h"
#import "DomainLogin.h"
#import "NetInfoKeys.h"
#import "NIDirectory.h"
#import "NIProperty.h"
#import <libc.h>
#import <stdio.h>
#import <string.h>
#import <sys/types.h>
#import <sys/stat.h>
#import <pwd.h>
#define INETD_CONF "/etc/inetd.conf"
#define INETD_BACK "/etc/inetd.conf~"
@implementation Controller
// ****************************************************
// Local methods:
- (BOOL)menuActive:menuCell
{
id theClass = [[[NXApp mainWindow] delegate] class];
BOOL hs = (theClass == [Hosts class]) || (theClass == [Services class]);
BOOL up = (theClass == [Users class]) || (theClass == [Printers class]);
BOOL shouldBeEnabled = hs || up;
if (shouldBeEnabled) {
if (menuCell == menuDelete)
shouldBeEnabled = [[[NXApp mainWindow] delegate] isOld:self] && hs;
else if (menuCell == menuSaveToDomain)
shouldBeEnabled = hs;
else if (menuCell == menuRevert)
shouldBeEnabled = [[[NXApp mainWindow] delegate] isOld:self];
else
shouldBeEnabled = (menuCell == menuClose) || [[NXApp mainWindow] isDocEdited];
if ([menuCell isEnabled] != shouldBeEnabled) {
[menuCell setEnabled:shouldBeEnabled];
return YES;
}
} else if ([menuCell isEnabled] != shouldBeEnabled) {
[menuCell setEnabled:shouldBeEnabled];
return YES;
}
return NO;
}
// The method called by the NIDirectory open method. It should check if the requested
// object is already open.
- (BOOL)niDirOk:(const char *)domain path:(const char *)directory
{
int windows, i;
id obj;
// Check all opened windows of this class.
// (Can't use the window list; miniwindows don't have a delegate!)
// If we already have an open window, show it.
windows = [serviceList count];
for (i = 0; i < windows; i++) {
obj = [serviceList objectAt:i];
if ([obj isSame:directory inDomain:domain]) {
[obj show:self];
return NO;
}
}
return YES;
}
// Check if the given directory with its property value pairs exists.
// If p2 is NULL, v2 is assumed to be the second value of p1.
// Return self if the directory exists or was saved successfully.
- checkNetInfoIn:(const char *)domainPath forDir:(const char *)dirName
prop1:(const char *)p1 val1:(const char *)v1
prop2:(const char *)p2 val2:(const char *)v2
prop3:(const char *)p3 val3:(const char *)v3
{
id retVal = self;
NIDirectory *NIDir = [[NIDirectory alloc] init:self dom:domainPath root:dirName dir:v1 errors:NO];
NIProperty *nameProp = [NIDir addProperty:p1];
if (![[NIDir property:p1] values]) {
if (p2) {
[nameProp updateValue:v1 at:0];
[[NIDir addProperty:p2] updateValue:v2 at:0];
[[NIDir addProperty:p3] updateValue:v3 at:0];
} else {
[[nameProp updateValue:v1 at:0] updateValue:v2 at:1];
[[NIDir addProperty:p3] updateValue:v3 at:0];
}
retVal = [NIDir save];
}
[NIDir close];
return retVal;
}
- setNMBD:(const char *)line
{
unsigned char token[1024];
int d, r, i = 0, p = 0;
while ((i < 6) && ((r = sscanf(line, "%s%n", token, &p)) != EOF)) {
i++;
line+= p;
}
// Here we should have the fully qualified file name
if (r != EOF) {
[fieldnmbProgram setStringValue:token];
r = sscanf(line, "%s%n", token, &p); // Skip the daemon's name
line+= p;
r = sscanf(line, "%s%n", token, &p);
while (r != EOF) { // Options
line+= p;
if (*token == '-')
switch (token[1]) {
case 'd' : // Debug level
while (*line && (*line <= ' ')) line++;
r = sscanf(line, "%d%n", &d, &p);
if ((d >= 10) || (*line == 'A'))
d = 10;
[buttonNMBLogging setTitle:[[matrixNMBLogging findCellWithTag:d] title]];
[matrixNMBLogging selectCellWithTag:d];
line+= p;
break;
case 'n' : // Log method
r = sscanf(line, "%s%n", token, &p);
[fieldnmbNetBiosName setStringValue:token];
line+= p;
break;
case 'l' : // Log file
r = sscanf(line, "%s%n", token, &p);
[fieldnmbLogFile setStringValue:token];
line+= p;
break;
default : ;
}
r = sscanf(line, "%s%n", token, &p);
}
}
return self;
}
- setSMBD:(const char *)line
{
unsigned char token[1024], *t;
int d, r, i = 0, p = 0;
while ((i < 6) && ((r = sscanf(line, "%s%n", token, &p)) != EOF)) {
i++;
line+= p;
}
// Here we should have the fully qualified file name
if (r != EOF) {
[fieldsmbProgram setStringValue:token];
r = sscanf(line, "%s%n", token, &p); // Skip the daemon's name
line+= p;
r = sscanf(line, "%s%n", token, &p);
while (r != EOF) { // Options
line+= p;
if (*token == '-')
switch (token[1]) {
case 'a' : // Log method
[buttonSMBLogMethod setTitle:[[matrixSMBLogMethod findCellWithTag:1] title]];
[matrixSMBLogMethod selectCellWithTag:1];
break;
case 'd' : // Debug level
while (*line && (*line <= ' ')) line++;
r = sscanf(line, "%d%n", &d, &p);
if ((d >= 10) || (*line == 'A'))
d = 10;
[buttonSMBLogging setTitle:[[matrixSMBLogging findCellWithTag:d] title]];
[matrixSMBLogging selectCellWithTag:d];
line+= p;
break;
case 'l' : // Log file
r = sscanf(line, "%s%n", token, &p);
[fieldsmbLogFile setStringValue:token];
line+= p;
break;
case 'O' : // Socket options
r = sscanf(line, "%s%n", token, &p);
while ((r != EOF) && (*token != '-')) {
line+= p;
if (*token == '"')
t = token+1;
else
t = token;
if (!strncmp(t, "SO_KEEPALIVE", strlen("SO_KEEPALIVE")))
[checkKeepAlive setIntValue:1];
else if (!strncmp(t, "SO_REUSEADDR", strlen("SO_REUSEADDR")))
[checkReuse setIntValue:1];
else if (!strncmp(t, "SO_BROADCAST", strlen("SO_BROADCAST")))
[checkBroadcast setIntValue:1];
else if (!strncmp(t, "TCP_NODELAY", strlen("TCP_NODELAY")))
[checkNoDelay setIntValue:1];
else if (!strncmp(t, "SO_SNDBUF", strlen("SO_SNDBUF")))
[fieldSendBufSize setIntValue:atoi(t+strlen("SO_SNDBUF")+1)];
else if (!strncmp(t, "SO_RCVBUF", strlen("SO_RCVBUF")))
[fieldRecBufSize setIntValue:atoi(t+strlen("SO_RCVBUF")+1)];
else if (!strncmp(t, "SO_SNDLOWAT", strlen("SO_SNDLOWAT")))
[fieldSendLowWat setIntValue:atoi(t+strlen("SO_SNDLOWAT")+1)];
else if (!strncmp(t, "SO_RCVLOWAT", strlen("SO_RCVLOWAT")))
[fieldRecLowWat setIntValue:atoi(t+strlen("SO_RCVLOWAT")+1)];
r = sscanf(line, "%s%n", token, &p);
}
break;
default : ;
}
r = sscanf(line, "%s%n", token, &p);
}
}
return self;
}
- clearStartup
{
// Clear all fields and reset popups.
[fieldnmbProgram setStringValue:""];
[fieldnmbNetBiosName setStringValue:""];
[buttonNMBLogging setTitle:[[matrixNMBLogging findCellWithTag:0] title]];
[matrixNMBLogging selectCellWithTag:0];
[fieldnmbLogFile setStringValue:""];
[fieldsmbProgram setStringValue:""];
[checkKeepAlive setIntValue:0];
[checkReuse setIntValue:0];
[checkBroadcast setIntValue:0];
[checkNoDelay setIntValue:0];
[fieldSendBufSize setStringValue:""];
[fieldRecBufSize setStringValue:""];
[fieldSendLowWat setStringValue:""];
[fieldRecLowWat setStringValue:""];
[buttonSMBLogging setTitle:[[matrixSMBLogging findCellWithTag:0] title]];
[matrixSMBLogging selectCellWithTag:0];
[buttonSMBLogMethod setTitle:[[matrixSMBLogMethod findCellWithTag:0] title]];
[matrixSMBLogMethod selectCellWithTag:0];
[fieldsmbLogFile setStringValue:""];
// Set the buttons.
[buttonStop setEnabled:NO];
[buttonStart setEnabled:NO];
[buttonRemove setEnabled:NO];
[buttonRevert setEnabled:NO];
[buttonSave setEnabled:NO];
[windowStartup setDocEdited:NO];
return self;
}
- (BOOL)alertChoice:(const char *)msg buttons:(BOOL)YesNo
{
int choice = NXRunAlertPanel([strings valueForStringKey:"Alert:Alert"],
[strings valueForStringKey:msg],
[strings valueForStringKey:YesNo?"Button:Yes":"Button:OK"],
YesNo?[strings valueForStringKey:"Button:No"]:NULL,
NULL, INETD_CONF, strerror(errno));
return (choice == NX_ALERTDEFAULT);
}
- (BOOL)smbdLine:(char *)buffer
{
BOOL keep = [checkKeepAlive state],
reuse = [checkReuse state],
broadcast = [checkBroadcast state],
noDelay = [checkNoDelay state],
logMode = [[matrixSMBLogMethod selectedCell] tag];
int d = [[matrixSMBLogging selectedCell] tag],
snd = [fieldSendBufSize intValue],
rcv = [fieldRecBufSize intValue],
sndlo = [fieldSendLowWat intValue],
rcvlo = [fieldRecLowWat intValue],
statRet;
const char *smbd = [fieldsmbProgram stringValue],
*log = [fieldsmbLogFile stringValue];
struct stat status;
FILE *pipe;
char pbuffer[4096];
if (!*smbd || (d && !*log)) {
[self alertChoice:*log?"Message:No smb daemon":"Message:No smbd log file" buttons:NO];
return NO;
}
// Try to execute the daemon. If it doesn't exist, return NO.
// If it doesn't return NetInfo ..., warn about using SambaManager.app.
status.st_mode = 0;
statRet = stat(smbd, &status);
if ((statRet != 0) || !(status.st_mode&S_IEXEC)) {
[self alertChoice:"Message:Cannot find smb daemon" buttons:NO];
return NO;
}
(void)strcpy(pbuffer, smbd);
(void)strcat(pbuffer, " -V");
pipe = popen(pbuffer, "r");
fscanf(pipe, "%s", pbuffer);
pclose(pipe);
if (strcmp(pbuffer, "NetInfo"))
[self alertChoice:"Message:SMB daemon not NetInfo enhanced" buttons:NO];
(void)strcpy(buffer, "netbios-ssn stream tcp nowait root ");
(void)strcat(buffer, smbd);
if (logMode)
(void)strcat(buffer, " -a");
if (d < 10)
sprintf(buffer+strlen(buffer), " smbd -d %d", d);
else
(void)strcat(buffer," smbd -d All");
if (d)
sprintf(buffer+strlen(buffer), " -l %s", log);
if (keep | reuse | broadcast | noDelay | snd | rcv | sndlo | rcvlo) {
sprintf(buffer+strlen(buffer), " -O \"%s%s%s%s",
keep?"SO_KEEPALIVE ":"", reuse?"SO_REUSEADDR ":"",
broadcast?"SO_BROADCAST ":"", noDelay?"TCP_NODELAY ":"");
if (snd)
sprintf(buffer+strlen(buffer), "SO_SNDBUF=%d ", snd);
if (rcv)
sprintf(buffer+strlen(buffer), "SO_RCVBUF=%d ", rcv);
if (sndlo)
sprintf(buffer+strlen(buffer), "SO_SNDLOWAT=%d ", sndlo);
if (rcvlo)
sprintf(buffer+strlen(buffer), "SO_RCVLOWAT=%d ", rcvlo);
sprintf(buffer+strlen(buffer)-1, "\"");
}
(void)strcat(buffer, " -f /tmp/smbd.pid\n");
return YES;
}
- (BOOL)nmbdLine:(char *)buffer
{
int d = [[matrixNMBLogging selectedCell] tag],
statRet;
const char *nmbd = [fieldnmbProgram stringValue],
*log = [fieldnmbLogFile stringValue],
*nbName = [fieldnmbNetBiosName stringValue];
struct stat status;
FILE *pipe;
char pbuffer[4096];
if (!*nmbd || (d && !*log)) {
[self alertChoice:*log?"Message:No nmb daemon":"Message:No nmbd log file" buttons:NO];
return NO;
}
// Try to execute the daemon. If it doesn't exist, return NO.
// If it doesn't return NetInfo ..., warn about using SambaManager.app.
status.st_mode = 0;
statRet = stat(nmbd, &status);
if ((statRet != 0) || !(status.st_mode&S_IEXEC)) {
[self alertChoice:"Message:Cannot find nmb daemon" buttons:NO];
return NO;
}
(void)strcpy(pbuffer, nmbd);
(void)strcat(pbuffer, " -V");
pipe = popen(pbuffer, "r");
fscanf(pipe, "%s", pbuffer);
pclose(pipe);
if (strcmp(pbuffer, "NetInfo"))
[self alertChoice:"Message:NMB daemon not NetInfo enhanced" buttons:NO];
(void)strcpy(buffer, "netbios-ns dgram udp wait root ");
(void)strcat(buffer, nmbd);
sprintf(buffer+strlen(buffer), " nmbd -d %d", d);
if (d)
sprintf(buffer+strlen(buffer), " -l %s", log);
if (*nbName)
sprintf(buffer+strlen(buffer), " -n %s", nbName);
(void)strcat(buffer, " -f /tmp/nmbd.pid\n");
return YES;
}
- scanEtcInetdConf:(int)mode
// Mode is: 0 for reading, 1 for writing, 2 for stopping, 3 for starting, 4 for removing
{
NXStream *rStream = NXMapFile(INETD_CONF, NX_READONLY),
*wStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
unsigned char line[1024], c;
char buf[MAXPATHLEN + 1];
int i, both = 0, o, have = 0, smbd, nmbd;
BOOL retVal = YES;
FILE *pipe;
struct passwd *pwEnt;
char salt[3];
[windowStartup disableFlushWindow];
if (!mode)
[self clearStartup];
if (!rStream) {
NXCloseMemory(wStream, NX_FREEBUFFER);
[windowStartup reenableFlushWindow];
[windowStartup display];
return nil;
}
c = NXGetc(rStream);
while (!NXAtEOS(rStream) && (both < 2)) {
while (!NXAtEOS(rStream) && (c <= ' ')) {
NXPutc(wStream, c);
c = NXGetc(rStream);
}
i = 0;
while (!NXAtEOS(rStream) && (i < 1024) && (c != '\n')) {
line[i++] = c;
c = NXGetc(rStream);
}
line[i] = '\0';
o = ((*line == '#') && (*(line+1) == '!'))?2:0;
if ((*line == '#') && !o) {
line[i++] = '\n';
NXWrite(wStream, line, i);
*line = '\0';
}
if (*(line+o)) {
smbd = !strncmp(line+o, SMNIP_NBSSN, strlen(SMNIP_NBSSN));
nmbd = !strncmp(line+o, SMNIP_NBNS, strlen(SMNIP_NBNS));
if (smbd || nmbd) {
[buttonRemove setEnabled:!uid || !euid];
[buttonStart setEnabled:o && (!uid || !euid)];
[buttonStop setEnabled:!o && (!uid || !euid)];
switch (mode) {
case 0:
if (smbd)
[self setSMBD:line+o];
else
[self setNMBD:line+o];
both++;
break;
case 1: // write
have|= smbd?1:2;
// We'll continue and back out before saving.
if (smbd)
retVal&= [self smbdLine:line];
else
retVal&= [self nmbdLine:line];
NXWrite(wStream, line, strlen(line));
break;
case 2: // stop
NXWrite(wStream, "#!", 2);
case 3: // start
NXWrite(wStream, line+o, i-o);
NXPutc(wStream, '\n');
break;
case 4: // remove
default: ;
}
} else {
NXWrite(wStream, line, i);
NXPutc(wStream, '\n');
}
}
c = NXGetc(rStream);
}
if (mode && retVal) {
if ((mode == 1) && !(have&1)) {
retVal&= [self smbdLine:line];
NXWrite(wStream, "#!", 2);
NXWrite(wStream, line, strlen(line));
}
if (retVal && (mode == 1) && !(have&2)) {
retVal&= [self nmbdLine:line];
NXWrite(wStream, "#!", 2);
NXWrite(wStream, line, strlen(line));
}
// If we are root (uid = 0) save. If we have set uid, validate the root password.
if (retVal && (uid && !euid) && !rootOk) {
pwEnt = getpwuid(0);
strncpy(salt, pwEnt->pw_passwd, 2);
salt[2] = '\0';
[fieldPassword selectText:self];
i = [NXApp runModalFor:panelAuthenicate];
[panelAuthenicate close];
switch(i) {
case NX_RUNSTOPPED:
rootOk = retVal = !strcmp(crypt((char *)[fieldPassword stringValue], salt), pwEnt->pw_passwd);
break;
default:
retVal = NO;
}
}
if (retVal) {
if (retVal = (rename(INETD_CONF, INETD_BACK) == 0)) {
if (retVal = !NXSaveToFile(wStream, INETD_CONF))
switch (mode) {
case 1: // save
[windowStartup setDocEdited:NO];
[buttonRevert setEnabled:NO];
[buttonSave setEnabled:NO];
[buttonStart setEnabled:!have && (!uid || !euid)];
[buttonRemove setEnabled:have && (!uid || !euid)];
break;
case 2: // stop
[buttonStop setEnabled:NO];
[buttonStart setEnabled:!uid || !euid];
break;
case 3: // start
[buttonStart setEnabled:NO];
[buttonStop setEnabled:!uid || !euid];
break;
case 4: // clear
[self clearStartup];
}
else
NXRunAlertPanel([strings valueForStringKey:"Alert:Alert"],
[strings valueForStringKey:"Message:Could not save configuraton"],
[strings valueForStringKey:"Button:OK"],
NULL, NULL, INETD_CONF);
} else
NXRunAlertPanel([strings valueForStringKey:"Alert:Alert"],
[strings valueForStringKey:"Message:Could not rename"],
[strings valueForStringKey:"Button:OK"],
NULL, NULL, INETD_CONF, strerror(errno));
}
}
NXCloseMemory(wStream, NX_FREEBUFFER);
NXCloseMemory(rStream, NX_FREEBUFFER);
// If no daemons set, search for them!
if (!*[fieldsmbProgram stringValue]) {
if (![[NXBundle mainBundle] getPath:buf forResource:"smbd" ofType:NULL])
if (![NXBundle getPath:buf forResource:"smbd" ofType:NULL
inDirectory:"/LocalLibrary/SambaManager" withVersion:0])
if (![NXBundle getPath:buf forResource:"smbd" ofType:NULL
inDirectory:"/LocalLibrary/SambaManager/samba" withVersion:0])
if (![NXBundle getPath:buf forResource:"smbd" ofType:NULL
inDirectory:"/users/local/samba/bin" withVersion:0])
*buf = '\0';
if (*buf) {
[fieldsmbProgram setStringValue:buf];
[windowStartup setDocEdited:YES];
[buttonSave setEnabled:!uid || !euid];
}
}
if (!*[fieldnmbProgram stringValue]) {
if (![[NXBundle mainBundle] getPath:buf forResource:"nmbd" ofType:NULL])
if (![NXBundle getPath:buf forResource:"nmbd" ofType:NULL
inDirectory:"/LocalLibrary/SambaManager" withVersion:0])
if (![NXBundle getPath:buf forResource:"nmbd" ofType:NULL
inDirectory:"/LocalLibrary/SambaManager/samba" withVersion:0])
if (![NXBundle getPath:buf forResource:"nmbd" ofType:NULL
inDirectory:"/users/local/samba/bin" withVersion:0])
*buf = '\0';
if (*buf) {
[fieldnmbProgram setStringValue:buf];
[windowStartup setDocEdited:YES];
[buttonSave setEnabled:!uid || !euid];
}
}
[windowStartup reenableFlushWindow];
[windowStartup display];
// Send a hangup to the inetd process.
if (retVal && (mode > 1)) {
have = (pipe = popen("/bin/ps ax | /bin/grep inetd | /bin/grep -v grep", "r")) != NULL;
i = -1;
if (have) {
fscanf(pipe, "%d", &i);
pclose(pipe);
have = kill(i, SIGHUP) == 0;
}
// Warn that inetd wasn't restarted if no pipe or kill fails.
if (!have)
if (i > 0)
NXRunAlertPanel([strings valueForStringKey:"Alert:Alert"],
[strings valueForStringKey:"Message:Could not signal inetd pid"],
[strings valueForStringKey:"Button:OK"],
NULL, NULL, i);
else
[self alertChoice:"Message:Could not signal inetd" buttons:NO];
// If disable, try to stop the daemons. Remove any pid files.
if ((mode == 2) || (mode == 4)) {
if ((pipe = fopen("/tmp/nmbd.pid", "r")) != NULL) {
if (fscanf(pipe, "%d", &i) == 1)
kill(i, SIGKILL);
fclose(pipe);
}
unlink("/tmp/nmbd.pid");
if ((pipe = fopen("/tmp/smbd.pid", "r")) != NULL) {
if (fscanf(pipe, "%d", &i) == 1)
kill(i, SIGKILL);
fclose(pipe);
}
unlink("/tmp/smbd.pid");
}
}
return self;
}
- markEdited:sender
{
[windowStartup setDocEdited:YES];
[buttonSave setEnabled:!uid || !euid];
[buttonRevert setEnabled:YES];
return self;
}
- openFilePath:(BOOL)dirsOnly field:outlet
{
const char *docFileType[1] = {NULL};
char buffer[4096], hostName[128];
id openPanel;
openPanel = [[OpenPanel new] allowMultipleFiles:NO];
[openPanel chooseDirectories:dirsOnly];
[openPanel setTitle:[strings valueForStringKey:dirsOnly?"Title:Select Directory":"Title:Select File"]];
switch([openPanel runModalForTypes:docFileType]) {
case NX_OKTAG:
if (dirsOnly) {
strcpy(buffer, [openPanel filename]);
strcat(buffer, "/");
if (gethostname(hostName, 128))
strcpy(hostName, "log");
strcat(buffer, hostName);
[outlet setStringValue:buffer];
} else
[outlet setStringValue:[openPanel filename]];
[self markEdited:self];
default: ;
}
return self;
}
// Check and possibly set the NetInfo values for the samba daemons.
- setNetInfo
{
if ([self checkNetInfoIn:"." forDir:SMNI_SERVICES
prop1:SMNIP_NAME val1:SMNIP_NBSSN
prop2:SMNIP_PORT val2:"139"
prop3:SMNIP_PROTOCOL val3:"tcp"])
if ([self checkNetInfoIn:"." forDir:SMNI_SERVICES
prop1:SMNIP_NAME val1:SMNIP_NBNS
prop2:SMNIP_PORT val2:"137"
prop3:SMNIP_PROTOCOL val3:"udp"])
if ([self checkNetInfoIn:"." forDir:SMNIP_PROTOCOLS
prop1:SMNIP_NAME val1:"tcp"
prop2:NULL val2:"TCP"
prop3:SMNIP_NUMBER val3:"6"])
if ([self checkNetInfoIn:"." forDir:SMNIP_PROTOCOLS
prop1:SMNIP_NAME val1:"udp"
prop2:NULL val2:"UDP"
prop3:SMNIP_NUMBER val3:"17"])
return self;
return nil;
}
// ****************************************************
// Other methods:
- removeFromServiceList:sender
// Rmove the sender from the list of opened services.
{
[serviceList removeObject:sender];
return self;
}
// ****************************************************
// Actions from the menus, window, and panel:
- cancelPassword:sender
{
[NXApp abortModal];
return self;
}
- okayPassword:sender
{
[NXApp stopModal];
return self;
}
- info:sender
{
return self;
}
- preferences:sender
{
return self;
}
- showStartup:sender
{
[fieldnmbProgram selectText:self];
[windowStartup makeKeyAndOrderFront:self];
return self;
}
- saveStartup:sender
{
if ([self scanEtcInetdConf:1])
[self setNetInfo];
return self;
}
- revertStartup:sender
{
[self scanEtcInetdConf:0];
return self;
}
- openUser:sender
{
return [serviceList addObject:[Users open:self at:&offset]];
}
- openPrinter:sender
{
return [serviceList addObject:[Printers open:self at:&offset]];
}
- newHost:sender
{
return [serviceList addObject:[Hosts new:self at:&offset]];
}
- newService:sender
{
return [serviceList addObject:[Services new:self at:&offset]];
}
- openHost:sender
{
return [serviceList addObject:[Hosts open:self at:&offset]];
}
- openService:sender
{
return [serviceList addObject:[Services open:self at:&offset]];
}
- saveToDomain:sender
{
if ([NXApp mainWindow] != nil)
[[[NXApp mainWindow] delegate] saveToDomain:self];
return self;
}
- delete:sender
{
if ([NXApp mainWindow] != nil)
[[[NXApp mainWindow] delegate] delete:self];
return self;
}
- close:sender
{
id obj;
if ([NXApp mainWindow] != nil) {
obj = [[NXApp mainWindow] delegate];
if ([obj close:self])
[obj free];
}
return self;
}
// Remove a samba daemon from this system
- remove:sender
{
[self scanEtcInetdConf:4];
return self;
}
- revert:sender
{
if ([NXApp mainWindow] != nil)
[[[NXApp mainWindow] delegate] revert:self];
return self;
}
- save:sender
{
if ([NXApp mainWindow] != nil)
[[[NXApp mainWindow] delegate] save:self];
return self;
}
- start:sender
{
if ([windowStartup isDocEdited])
if ([self alertChoice:"Message:Save before enabling?" buttons:YES])
if (![self saveStartup:self])
return self;
[self scanEtcInetdConf:3];
return self;
}
- stop:sender
{
[self scanEtcInetdConf:2];
return self;
}
- setNameDaemon:sender
{
return [self openFilePath:NO field:fieldnmbProgram];
}
- setNameLogging:sender
{
return [self openFilePath:YES field:fieldnmbLogFile];
}
- setSambaDaemon:sender
{
return [self openFilePath:NO field:fieldsmbProgram];
}
- setSambaLogging:sender
{
return [self openFilePath:YES field:fieldsmbLogFile];
}
- testParameters:sender
{
char buf[4096];
FILE *pipe;
if (![[NXBundle mainBundle] getPath:buf forResource:"testparm" ofType:NULL])
if (![NXBundle getPath:buf forResource:"testparm" ofType:NULL
inDirectory:"/LocalLibrary/SambaManager" withVersion:0])
if (![NXBundle getPath:buf forResource:"testparm" ofType:NULL
inDirectory:"/LocalLibrary/SambaManager/samba" withVersion:0])
if (![NXBundle getPath:buf forResource:"testparm" ofType:NULL
inDirectory:"/users/local/samba/bin" withVersion:0])
*buf = '\0';
[textParameters setEditable:YES];
[textParameters selectText:self];
if (*buf) {
[textParameters replaceSel:""];
(void)strcat(buf,"\n\n");
pipe = popen(buf, "r");
while (fgets(buf, 4096, pipe)) {
[textParameters setSel:[textParameters textLength] :[textParameters textLength]];
[textParameters replaceSel:buf];
}
pclose(pipe);
} else {
[textParameters replaceSel:"Could not find the testparm program.\nLooked for it in:\n the bundle\n /LocalLibrary/SambaManager\n /LocalLibrary/SambaManager/samba\n /users/local/samba/bin"];
}
[textParameters setEditable:NO];
[windowParameters makeKeyAndOrderFront:self];
return self;
}
// ****************************************************
// Delegates
-appDidInit:sender
{
id menu;
id popup;
// Allocate and initialize the lists of opened windows.
serviceList = [[List alloc] initCount:1];
offset = 0.0;
uid = getuid();
euid = geteuid();
rootOk = NO;
// Set up the popups for the logging level
popup = [buttonSMBLogging target];
[popup setTarget:self];
[popup setAction:@selector(markEdited:)];
matrixSMBLogging = [popup itemList];
popup = [buttonSMBLogMethod target];
[popup setTarget:self];
[popup setAction:@selector(markEdited:)];
matrixSMBLogMethod = [popup itemList];
popup = [buttonNMBLogging target];
[popup setTarget:self];
[popup setAction:@selector(markEdited:)];
matrixNMBLogging = [popup itemList];
// Scan the INETD.CONF file.
[self scanEtcInetdConf:0];
// Set up menu enabling/disabling methods.
menu = [menuCellSamba target];
[menuDelete setUpdateAction:@selector(menuActive:) forMenu:menu];
[menuSave setUpdateAction:@selector(menuActive:) forMenu:menu];
[menuSaveToDomain setUpdateAction:@selector(menuActive:) forMenu:menu];
[menuRevert setUpdateAction:@selector(menuActive:) forMenu:menu];
[menuClose setUpdateAction:@selector(menuActive:) forMenu:menu];
// Set up automatic menu enabling/disabling.
[NXApp setAutoupdate:YES];
return self;
}
-appWillTerminate:sender
{
int i, elements = [serviceList count];
if ([windowStartup isDocEdited] && (!uid || !euid)) {
i = NXRunAlertPanel([strings valueForStringKey:"Alert:Alert"],
[strings valueForStringKey:"Message:Save changes to daemon startup?"],
[strings valueForStringKey:"Button:Save"],
[strings valueForStringKey:"Button:Don't Save"],
[strings valueForStringKey:"Button:Cancel"]);
switch (i) {
case NX_ALERTDEFAULT:
if (![self setNetInfo])
return nil;
case NX_ALERTALTERNATE:
break;
default:
return nil;
}
}
for (i = 0; i < elements; i++)
if (![[serviceList objectAt:i] close:self])
return nil;
return self;
}
- textDidGetKeys:sender isEmpty:(BOOL)flag
{
return [self markEdited:self];
}
- textDidEnd:textObject endChar:(unsigned short)whyEnd
{
if (([textObject superview] == fieldPassword) && (whyEnd == NX_RETURN))
[NXApp stopModal];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.