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.