This is Coordinator.m in view mode; [Download] [Up]
//*****************************************************************************
//
// Coordinator.m
//
// NXApp delegate, central control object for GateKeeper
//
// by Felipe A. Rodriguez
//
// This code is supplied "as is" the author makes no warranty as to its
// suitability for any purpose. This code is free and may be distributed
// in accordance with the terms of the:
//
// GNU GENERAL PUBLIC LICENSE
// Version 2, June 1991
// copyright (C) 1989, 1991 Free Software Foundation, Inc.
// 675 Mass Ave, Cambridge, MA 02139, USA
//
//*****************************************************************************
#import <appkit/nextstd.h>
#import <appkit/Application.h>
#import <objc/NXStringTable.h>
#import <defaults/defaults.h>
#import <bsd/c.h>
#import <sys/dir.h> /* POSIX applications #include <dirent.h> */
#import <mach/mach.h>
#import <kernserv/kern_loader.h>
#import "GKdefs.h"
#import "Animator.h"
#import "EParse.h"
#import "OptionsEditor.h"
#import "options.h"
#import "IconView.h"
#import "ToolBar.h"
#import "DialServer.h"
#import "Timer.h"
#import "IdleAnimator.h"
#import "Coordinator.h"
#import "CommandScroll.h"
#import "GateDocEditor.h"
#import "InfoAnimator.h"
#import "DLDelegate.h"
#import "pppstats.h"
#import "./MiG/Library/pppd_rpc_defs.h" // pppd RPC related defs
@interface Coordinator (Private)
// RPC routines
#import "pppd_rpc_types.h"
#import "pppd_rpc.h"
extern void gk_listen(void);
extern void gk_check_out(void);
@end
@implementation Coordinator (Private)
@end
@implementation Coordinator
//*****************************************************************************
//
// state machine which monitors ppp daemon
//
//*****************************************************************************
- setPhase:(int)phase
{
switch(phase)
{
case 0: // pppd hangup
[theTimer stopTimer];
[theAnimator standBy];
// disable the disconnect button
[[[NXApp mainMenu] findCellWithTag:1] setEnabled:NO];
[statusButton setEnabled:NO];
[theOpenButton setEnabled:YES]; // enable the open doc button
[dial setEnabled:YES]; // enable dial button
[connectionSpeedField setStringValue:" "];
[timeField setStringValue:" "];
[timeCell setStringValue:" "];
[self displayStatus:"pppdn"];
break;
case 2: // initial state after GK launch
[theTimer stopTimer];
[theAnimator standBy];
[self displayStatus:"ppp is ready"];
[statusButton setEnabled:NO];
[connectionSpeedField setStringValue:" "];
[timeField setStringValue:" "];
[timeCell setStringValue:" "];
[[[NXApp mainMenu] findCellWithTag:1] setEnabled:NO];
[[[NXApp mainMenu] findCellWithTag:2] setEnabled:YES];
break;
case 8: // Holdoff
[self displayStatus:"ppp daemon in holdoff"];
break;
case GK_CONNECT_FAIL: // Connect script failed
[theAnimator standBy];
[connectionSpeedField setStringValue:" "];
[self displayStatus:"connect script failed"];
break;
case GK_DIALING: // dialing?
if(!wasHidden) // if sw not set chk if we are hidden
wasHidden = [NXApp isHidden]; // app hidden?
if(strcmp("YES",NXGetDefaultValue([NXApp appName], DISPLAYS)) == 0)
[[statusView window] makeKeyAndOrderFront:self];
// if auto unhide switch is set wait msec before hiding
if(strcmp(NXGetDefaultValue([NXApp appName], "autoUnhide"),"YES") == 0)
[NXApp perform:@selector(unhide:) with:self
afterDelay:2000
cancelPrevious:YES];
case MAN_DIAL:
[self playSound:"Servo_2"];
[theAnimator dialing];
[dial setEnabled:NO]; // disable dial button
[theOpenButton setEnabled:NO]; // disable the open doc button
[self displayStatus:"Connecting..."];
break;
case 6: // PPP link is up
[[[NXApp mainMenu] findCellWithTag:1] setEnabled:YES];
[[[NXApp mainMenu] findCellWithTag:2] setEnabled:NO];
[self displayStatus:"pppup"];
[self gotIt];
break;
case GK_INACTIVITY: // Inactivity timeout
[self displayStatus:"ppp idle timeout is imminent"];
idleZone = NXCreateZone(vm_page_size, vm_page_size, YES);
[NXApp loadNibSection:"IdlePanel.nib"
owner:self
withNames:NO
fromZone:idleZone];
[iTimer startAnimTimer];
break;
case GK_DIE: // pppd died
[theAnimator standBy];
[[[NXApp mainMenu] findCellWithTag:1] setEnabled:NO];
[[[NXApp mainMenu] findCellWithTag:2] setEnabled:YES];
[statusButton setEnabled:NO];
[self displayStatus:"ppp daemon died"];
break;
case GK_NO_LKS: // pppd found no LKS support
[self displayStatus:"loading BPF LKS"];
[self loadKernelServer:"bpf_reloc"];
[self displayStatus:"loading PPP LKS"];
[self loadKernelServer:"ppp_reloc"];
[self displayStatus:"launching PPP daemon"];
[docLDelegate link]; // link, use preferences selected doc
break;
default:
break;
}
NXPing();
return self;
}
//*****************************************************************************
//
// return our string table (contains key->value localization pairs)
//
//*****************************************************************************
- stringTable;
{
return stringTable;
}
//*****************************************************************************
//
// localize error messages using stringTable as appropriate, displays
// the message in an alert panel
//
//*****************************************************************************
- showAlert:(const char *)errorString
{
NXRunAlertPanel(0, [self localString:errorString],
[stringTable valueForStringKey:"OK"], NULL, NULL);
return self;
}
//*****************************************************************************
//
// localize string messages using stringTable as appropriate
//
//*****************************************************************************
- (const char *)localString:(const char *)aString
{
const char *returnedString;
if (returnedString = [stringTable valueForStringKey:aString])
return returnedString;
return aString;
}
//*****************************************************************************
//
// display status messages in status panel and on console
//
//*****************************************************************************
- displayStatus:(const char *)status
{
const char *statusString = [self localString:status];
[statusView setStringValue:statusString];
[commandView appendString:statusString];
[commandView appendString:"\n"];
return self;
}
//*****************************************************************************
//
// Called when link is established
//
//*****************************************************************************
- gotIt
{
[theAnimator pppup];
[self playSound:"majestic"]; // play ppp up snd
[theTimer Fire:self]; // session timer start cnt
[self pppstats:commandView];
if(!onImage) // display ppp up app icon
onImage = [NXImage findImageNamed:"g4"];
[theIconView setImage:onImage];
[statusButton setEnabled:YES];
// if auto hide switch is set wait 5 sec before hiding
if((strcmp(NXGetDefaultValue([NXApp appName],"autoHide"),"YES") == 0) &&
wasHidden)
[NXApp perform:@selector(hide:) with:self
afterDelay:3000
cancelPrevious:YES];
wasHidden = NO; // reset sw
return self;
}
//*****************************************************************************
//
// registers connection speed
//
//*****************************************************************************
- connectedAt:(const char *)speed
{
strncpy(Path, [stringTable valueForStringKey:"connectAt"], MAXPATHLEN);
strncat(Path, speed, MAXPATHLEN - strlen(Path));
[connectionSpeedField setStringValue:Path];
[commandView appendString:Path];
[commandView appendString:"\n"];
return self;
}
//*********************** Application Object Delegation ***********************
//*****************************************************************************
//
// setup defaults data base cache before app is init'd
//
//*****************************************************************************
- appWillInit:sender
{
static NXDefaultsVector myDefaults = { // setup defaults database
{VERSION, "0"}, // version string
{DISPLAYD, "YES"}, // display diagnostics window
{DISPLAYS, "YES"}, // display status window
{"autoHide", "YES"}, // auto hide upon link
{"autoUnhide", "YES"}, // auto appear while linking
{"DispPPP", "YES"}, // display pppstats
{DISPLAYT, "YES"}, // display toolbar
{SOUND, "YES"}, // play sound
{AITIMER, "YES"}, // icon displayed online time
{"iTimeout", "Off"}, // inactivity unlink's us
{"iTimeThreshold", "0"}, // inactivity threshold
{SELCELL, "0"}, // cell selected in hotList
{DOD, "YES"}, // dial on demand
{"options", "/etc/ppp/options"},
{"ip-down", "/etc/ppp/ip-down"},
{"ip-up", "/etc/ppp/ip-up"},
{"resolv", "/etc/resolv.conf"},
{"messages", "/usr/adm/messages"},
{"remote", "/etc/remote"},
{LIBPATH, "/Library/GateKeeper"}, // path for .Gate documents
{"BaudStr", "CARRIER"}, // pref form end
{DIALINIT, "ATZ&D0L3"}, // modem init str for manual Dial
{"dialPrefix", "ATD"}, // modem AT command prefix for dialing
{MODEMPORT, "cufa"}, // modem port, used in releasing locks
{EDOC, "/"}, // path for .Gate documents
{CDOC, " "}, // current .Gate document
{"lastNumDialed", "8675309"}, // default man dial number
{"savedTime", "000000000000"}, // save time used this mo
{"monthTime", "000000000000"}, // save mo,yr of this ses'n
{"preMonthTime", "000000000000"}, // save previous mo,yr
{NULL}}; // make local cache of ddb
NXRegisterDefaults([NXApp appName], myDefaults);
return self;
}
//*****************************************************************************
//
// standard init
//
//*****************************************************************************
- appDidInit:sender
{
kern_return_t ret; // MiG return value variable
port_t server; // port id
static int c;
static char buf[256];
theAnimator = [[Animator alloc] init]; // get appIcon window
theIconView = [theAnimator iconView];
timeCell = [theIconView getTextCell]; // ret the iconView's textCell
// load console window and have it remember its size and loc
[NXApp loadNibSection:"Console.nib" owner:self withNames:NO];
[[commandView window] setFrameUsingName:[[commandView window] title]];
[[commandView window] setFrameAutosaveName:[[commandView window] title]];
if(strcmp(NXGetDefaultValue([NXApp appName], DISPLAYD),"YES") == 0)
[[commandView window] makeKeyAndOrderFront:self]; // show console win
if(strcmp("YES", NXGetDefaultValue([NXApp appName], DISPLAYS)) == 0)
[[statusView window] makeKeyAndOrderFront:self]; // show status panel
if(strcmp(NXGetDefaultValue([NXApp appName], VERSION), CURRVERSION) != 0)
{ // if first time this version was launched
if(!NXWriteDefault([NXApp appName], VERSION, CURRVERSION))
NXRunAlertPanel(0,
[stringTable valueForStringKey:"ddbWriteError"],
[stringTable valueForStringKey:"OK"],
NULL,
NULL);
[self showInfo:self];
}
// primary thread should listen for DO messages
// since appkit is not thread-safe
GKAppDelegate = [NXConnection registerRoot:self withName:"GKAppDelegate"];
[GKAppDelegate runFromAppKit]; // listen for DO messages from appKit
gk_listen(); // create RPC listener thread
if(strcmp("YES", NXGetDefaultValue([NXApp appName], AITIMER)) == 0)
appIconTime = YES; // show online time in app icon
theTimer = [[Timer allocFromZone:[self zone]] init];
// if dock autolaunched at startup
if(strcmp("YES", NXGetDefaultValue([NXApp appName], "NXAutoLaunch")) == 0)
{
// if auto hide switch is set wait x sec before hiding
if((strcmp(NXGetDefaultValue([NXApp appName],"autoHide"),"YES")==0))
[NXApp perform:@selector(hide:) with:self
afterDelay:100
cancelPrevious:YES];
}
[docLDelegate awake]; // initialize the doc delegate
if(strcmp("YES", NXGetDefaultValue([NXApp appName], DISPLAYT)) == 0)
[self toolBar:self]; // show toolbar if set
usleep(200);
server = pppd_rpc_server_look_up(); // find pppd
if (server != PORT_NULL) // pppd is active
{
if ((ret = pppd_status(server, &c)) != KERN_SUCCESS)
[self showAlert:"Error getting ppp daemon status."];
else
{
sprintf(buf,"pppd returned status: %d \n",(int) c);
[commandView appendString:buf];
[self setPhase:c];
}
}
else // if pppd did not respond launch it
{
// if not opeining a doc we were launched by double clicking
// on the application icon instead of a document.
if(!NXGetDefaultValue([NXApp appName], "NXOpen") &&
!NXGetDefaultValue([NXApp appName], "NXOpenTemp") &&
!NXGetDefaultValue([NXApp appName], "NXServiceLaunch"))
{ // set dial on demand if enabled
if(strcmp("YES", NXGetDefaultValue([NXApp appName], DOD)) == 0)
[self startDaemon:self]; // start the daemon
else
{ // allow user to start daemon from tools menu
[cDaemonButton setAction:@selector(startDaemon:)];
[cDaemonButton setTitle:[self localString:"Start pppd"]];
}
}
}
return self;
}
//*****************************************************************************
//
// This method is performed whenever a user double-clicks on an icon in
// the Workspace Manager representing a Gate program document.
//
// Brings up the gate doc editor which can edit or link using the doc
//
//*****************************************************************************
- (int)app:sender openFile:(const char *)path type:(const char *)type
{
[theGateDocEditor editGateDoc:path];
return 1;
}
//*****************************************************************************
//
// invoked immediately after app is hidden and unhidden respectively
//
// the following two methods are implemented to produce
// normal main window/menu app behavior when toolBar is open
//
//******************************************************************************
- appDidHide:sender
{
[[NXApp mainMenu] close]; // close the main menu
return self;
}
- appDidUnhide:sender
{
[[NXApp mainMenu] makeKeyAndOrderFront:self];
return self;
}
//*****************************************************************************
//
// Instantantiates the subprocess object which exec's pppd
//
//*****************************************************************************
- linkWithFile:(const char *)path
{
static char commandLine[MAXPATHLEN + 1], buf[8];
int timeout;
id image;
if([self runScript:"preLink"]) // exec pre link script
{
// build command line
strncpy(commandLine, [[NXBundle mainBundle] directory], MAXPATHLEN);
strncat(commandLine, "/pppd", MAXPATHLEN - strlen(commandLine));
// idle timeout is set
if(strcmp("Off", NXGetDefaultValue([NXApp appName], "iTimeout")) != 0)
{
strncat(commandLine, " idle ", MAXPATHLEN - strlen(commandLine));
timeout = atoi(NXGetDefaultValue([NXApp appName],"iTimeout")) * 60;
sprintf(buf,"%d",(int)timeout);
strncat(commandLine, buf, MAXPATHLEN - strlen(commandLine));
}
if(path == NULL)
{
lastCall[0] = '\0';
if([docLDelegate selGateDocOptionsPath] == NULL)
commandLine[0] = '\0';
else // if hotlist points to valid
{
strncat(commandLine, " ipcp-accept-local ipcp-accept-remote",
MAXPATHLEN - strlen(commandLine));
strncat(commandLine," file ",MAXPATHLEN - strlen(commandLine));
strncat(commandLine, [docLDelegate selGateDocOptionsPath],
MAXPATHLEN - strlen(commandLine));
strncpy(BPath,[docLDelegate selGateDocOptionsPath],MAXPATHLEN);
[providerField setStringValue:[self localString:"manDial"]];
}
}
else
{ // set dial on demand if enabled
if(strcmp("YES", NXGetDefaultValue([NXApp appName], DOD)) == 0)
{
strncat(commandLine,
" demand :192.42.172.4 ipcp-accept-local ipcp-accept-remote",
MAXPATHLEN - strlen(commandLine));
manDial = NO; // daemon should persist
}
else
manDial = YES; // kill pppd upon session term
strcpy(lastCall, path); // stores path of last invocation
// setup status panel
[statusView setStringValue:[self localString:"connecting"]];
[providerField setStringValue:[docLDelegate extractName:path]];
strncpy(Path, path, MAXPATHLEN);
strncat(Path, "/Icon.tiff", MAXPATHLEN - strlen(Path));
if(!(image = [[NXImage alloc] initFromFile:Path])) // if image
image = [NXImage findImageNamed: ".dir"]; // else use blank
[statusImageView setImage:image];
if((strlen([[NXBundle mainBundle] directory]) + 45 +
(2 * strlen(path)) + strlen(commandLine)) < MAXPATHLEN)
{ // if we won't overrun buffer
strcat(commandLine, " file ");
strcat(commandLine, path);
strcat(commandLine, OPTION); // options file name wrapper
strcat(commandLine, " connect \"");
strcat(commandLine, [[NXBundle mainBundle] directory]);
strcat(commandLine, "/chat -v -f ");
strcat(commandLine, path);
strcat(commandLine, PPPUP); // pppup file name wrapper
strcat(commandLine, "\"");
}
else
perror("command line is longer than MAXPATHLEN");
strncpy(BPath, path , MAXPATHLEN);
strncat(BPath, OPTION, MAXPATHLEN - strlen(BPath)); // options
}
if(commandLine[0] != '\0') // if we have a valid commline
{
if([self debugFlag:BPath])
{ // if debug sw set in options disg commandline
[commandView appendString:commandLine];
[commandView appendString:"\n\r"];
}
system(commandLine);
}
else
[self showAlert:"GateKeeper error building ppp command line."];
}
return self;
}
//*****************************************************************************
//
// Use terminal to do a manual link
//
//*****************************************************************************
- Dial:sender
{
if([self runScript:"preLink"])
{
manDial = YES;
[self stopDaemon:self]; // kill the daemon
usleep(800);
[self setPhase:MAN_DIAL];
if(!theGateServer) // create distributed Obj server
theGateServer = [[DialServer alloc] init];
GateConnection = [NXConnection registerRoot: theGateServer
withName:"GateKeeperDialServer"];// DO name of server
[GateConnection runFromAppKit]; // listen for DO messages from appKit
// ask workspace to launch MODEM tool
if(![[NXBundle mainBundle]getPath:Path forResource:"MODEM"ofType:NULL])
[self showAlert:"Error getting path for MODEM file"];
[[Application workspace] openFile:Path withApplication:"Terminal"];
}
return self;
}
//*****************************************************************************
//
// Called when menu item Unlink is pressed.
//
//*****************************************************************************
- disconnect:sender
{
kern_return_t ret; // MiG return value variable
port_t server; // port id
if([self runScript:"preUnLink"])
{
[self displayStatus:"terminating ppp session"];
server = pppd_rpc_server_look_up(); // find pppd
if (server == PORT_NULL)
[self showAlert:"unable to find pppd server"];
else
{
ret = set_pppd(server, GK_TERMINATE); // set pppd state
if (ret != KERN_SUCCESS)
[self showAlert:"Call to pppd server failed."];
}
if(manDial)
[self stopDaemon:self];
manDial = NO;
}
return self;
}
//*****************************************************************************
//
// run the preLink or preUnLink scripts, proceed if exit status true
//
//*****************************************************************************
- runScript:(const char *)type
{
id exitStatus = self;
int fd;
strncpy(Path, [[NXBundle mainBundle] directory], MAXPATHLEN);
strncat(Path, "/", MAXPATHLEN - strlen(Path));
strncat(Path, type, MAXPATHLEN - strlen(Path));
if(fd = open(Path, O_RDONLY) != -1) // if script exists
{
close(fd);
if(system(Path) != 0) // exec script, test exit
exitStatus = nil;
strcpy(Path, type);
if(!exitStatus)
strcat(Path," script exit status prevents requested action\n");
else
strcat(Path, " script executed sucessfully\n");
[commandView appendStringUseFixedFont:Path];
}
return exitStatus;
}
//*****************************************************************************
//
// we can always edit another gate doc
//
//*****************************************************************************
- (BOOL)appAcceptsAnotherFile:sender
{
return YES;
}
//*****************************************************************************
//
// termination is imminent
//
//*****************************************************************************
- appWillTerminate:sender
{
int ret;
if((ret = NXRunAlertPanel(0, [self localString:"Terminate ppp daemon?"],
[stringTable valueForStringKey:"Yes"],
[stringTable valueForStringKey:"No"],
"Cancel")) == NX_OKTAG)
{
[self killDaemon];
[self runScript:"postPPP"]; // to do after daemon is killed
}
gk_check_out(); // remove our name from net name server
[theAnimator removeTimedEntry];
if(theGateServer)
[theGateServer appWillTerminate];
if(docLDelegate)
[docLDelegate appWillTerminate];
return (ret != NX_ALERTOTHER ? self : nil);
}
//*****************************************************************************
//
// kill pppd
//
//*****************************************************************************
- killDaemon
{
port_t server; // port id
FILE *ff;
int pid;
server = pppd_rpc_server_look_up(); // find pppd
if (server == PORT_NULL)
fprintf(stderr,"lookup of pppd server failed in (killDaemon).\n");
else
die_pppd(server, GK_KILL); // async RPC call to pppd
usleep(900);
// if the lock file is still around kill
// the daemon with extreme prejudice
if((ff = fopen( "/etc/ppp/ppp0.pid", "r")) != NULL)
{
fprintf(stderr,"Killing ppp daemon with extreme prejudice.\n");
if( fscanf( ff, "%d", &pid) < 1)
perror("Unable to read pid from ppp0.pid\n");
else
{
fclose( ff);
if( kill( pid, SIGKILL) == -1)
fprintf(stderr,"Error killing ppp daemon in (killDaemon).\n");
}
}
return self;
}
//*****************************************************************************
//
// start and stop the ppp daemon
//
//*****************************************************************************
- stopDaemon:sender
{
[self setPhase:0];
[commandView appendString:[self localString:"Killing ppp daemon\n"]];
[self killDaemon];
[cDaemonButton setAction:@selector(startDaemon:)];
[cDaemonButton setTitle:[self localString:"Start pppd"]];
return self;
}
//*****************************************************************************
//
// start and stop the ppp daemon
//
//*****************************************************************************
- startDaemon:sender
{
[commandView appendString:[self localString:"Starting ppp daemon\n"]];
// preferences selected HotList doc for launching pppd
[docLDelegate link];
[cDaemonButton setAction:@selector(stopDaemon:)];
[cDaemonButton setTitle:[self localString:"Stop pppd "]];
return self;
}
//*****************************************************************************
//
// view the ppp log file
//
//*****************************************************************************
- viewLog:sender
{
const char *logFile;
// if readable
if([self readable:(logFile = [self logFile])]) // open with edit
[[Application workspace] openFile:logFile withApplication:"Edit"];
return self;
}
//*****************************************************************************
//
// show the info panel
//
//*****************************************************************************
- showInfo:sender
{
if(!infoPanel)
[NXApp loadNibSection:"InfoPanel.nib" owner:self withNames:NO];
[infoPanel startAnimTimer];
return self;
}
//*****************************************************************************
//
// show preferences panel
//
//*****************************************************************************
- preferences:sender
{
if(!preferencesPanel)
{
[self loadBundlesOfType:"gkPreference" owner:NXApp nib:NO];
preferencesPanel = [NXApp loadNibSection:"Preferences.nib" owner:NXApp
withNames:YES];
}
[preferencesPanel makeKeyAndOrderFront:self];
return self;
}
//*****************************************************************************
//
// show NXHelpPanel
//
//*****************************************************************************
- showHelpPanel:sender
{
if(!helpPanel)
helpPanel = [NXHelpPanel new];
[helpPanel display];
[helpPanel makeKeyAndOrderFront:self];
return self;
}
//*****************************************************************************
//
// display the Status panel
//
//*****************************************************************************
- showStatusPanel:sender
{
if(!NXWriteDefault([NXApp appName], DISPLAYS, "YES"))
[self showAlert:"ddbWriteError"];
return [[statusView window] makeKeyAndOrderFront:self];
}
//*****************************************************************************
//
// display the Console window
//
//*****************************************************************************
- showConsole:sender
{
if(!NXWriteDefault([NXApp appName], DISPLAYD, "YES"))
[self showAlert:"ddbWriteError"];
return [[commandView window] makeKeyAndOrderFront:self];
}
//*****************************************************************************
//
// show the timer
//
//*****************************************************************************
- showTimerPanel:sender
{
return [theTimer showTimerPanel:self];
}
//*****************************************************************************
//
// called by timer in order to pass us appIcon time string
//
// also used in determining inactivity timeout (since this is called
// once per minute during ppp sessions).
//
//*****************************************************************************
- showMenuTimer:(char *)buffer
{
if(appIconTime)
[timeCell setStringValue:buffer];
[timeField setStringValue:buffer];
[theIconView setImage:onImage];
[self pppstats];
return self;
}
//*****************************************************************************
//
// enable/disable display of online time in app icon
//
//*****************************************************************************
- setAppIconTimer:(BOOL)onOff
{
appIconTime = onOff;
return self;
}
//*****************************************************************************
//
// return a pointer to the document list delegate
//
//*****************************************************************************
- docLDelegate
{
return docLDelegate;
}
//*****************************************************************************
//
// returns whether a Gate doc may be opened or edited by real user
//
//*****************************************************************************
- readable:(const char *)nameOfFile
{
FILE *fp;
if ((fp = fopen(nameOfFile, "r+")) == NULL)
[self showAlert:"Unable to open Gate doc"];
else
{
if(readable(fileno(fp)))
{
fclose(fp);
return self; // we have permission
}
[self showAlert:"Access to Gate doc denied"];
fclose(fp);
}
return nil; // we do not have permission
}
//*****************************************************************************
//
// returns the Gate doc options editor
//
//*****************************************************************************
- optionsEditor
{
if(!theOptionsEditor)
theOptionsEditor = [[OptionsEditor alloc] init];
return theOptionsEditor;
}
//*****************************************************************************
//
// returns the state of the debug flag in an options file
//
//*****************************************************************************
- (BOOL)debugFlag:(const char *)optionFile
{
return [[[self optionsEditor] parseOptions:optionFile] debug];
}
//*****************************************************************************
//
// show the Tool Bar
//
//*****************************************************************************
- toolBar:sender
{
if(!NXWriteDefault([NXApp appName], DISPLAYT, "YES"))
[self showAlert:"ddbWriteError"];
if(!toolBar)
[NXApp loadNibSection:"ToolBar.nib" owner:self withNames:NO];
[toolBar makeKeyAndOrderFront:self];
return toolBar;
}
//*****************************************************************************
//
// return the app icons view
//
//*****************************************************************************
- appIconView
{
return theIconView;
}
//*****************************************************************************
//
// return commandview
//
//*****************************************************************************
- commandView
{
return commandView;
}
//*****************************************************************************
//
// called by Dial server when remote manual Dial Tool's ports are
// invalidated
//
//*****************************************************************************
- DOFinished
{
[self setPhase:0];
[self stopDaemon:self]; // restart the daemon
manDial = NO;
return self;
}
//*****************************************************************************
//
// free simply gets rid of everything we created
// This is how nice objects clean up.
//
//*****************************************************************************
- free
{
[timeCell free];
if(onImage)
[onImage free];
if(toolBar)
[toolBar free];
if(iTimer)
[iTimer free];
return [super free];
}
//*****************************************************************************
//
// search /etc/syslog.conf to find the location of the named pipe used
// in recieving the output from pppd/syslog
//
//*****************************************************************************
- (const char *)logFile
{
static char del1[] = {". =:|\t\r\n"}, del2[] = {" \t\r\n"};
static char *logFile = NULL; // ppp log file path
if(logFile)
free(logFile);
if(!Parser)
Parser = [[EParse alloc] init]; // create parser to find port
[[Parser setKey1:"local2"] setKey2:"debug"]; // set search pattern
[[Parser setDelim1:del1] setDelim2:del2]; // and delimiters
if(!(logFile = [Parser parseFile:"/etc/syslog.conf"]))
[self showAlert:"Error parsing syslog.conf for ppp log file name."];
return logFile;
}
//*****************************************************************************
//
// checks the mail queue for mail awaiting delivery
//
//*****************************************************************************
- (BOOL)mailInQueue
{
int eCntr = 0;
struct direct *dirp;
DIR *dp;
BOOL mail = NO;
if ((dp = opendir("/usr/spool/mqueue")) != NULL)
{
while ((dirp = readdir(dp)) && eCntr < 3) // read dir and cnt entries
{
if(*dirp->d_name != '.') // don't count if sys file
eCntr++;
}
if(eCntr > 2)
mail = YES;
closedir(dp);
}
else
[self showAlert:"Error opening Mail queue directory"];
return mail;
}
//*****************************************************************************
//
// search app wrapper and load bundles of the specified type
//
//*****************************************************************************
- loadBundlesOfType:(const char *)bundleType owner:o nib:(BOOL)loadNib
{
struct direct *dirp;
DIR *dp = NULL;
char *ptr, *p;
if ((DIR *)(dp = opendir([[NXBundle mainBundle] directory])) != NULL)
{ // open DIR stream
while (dirp = readdir(dp)) // read dir and find all
{ // entries with ext .bundle
if(dirp->d_namlen > strlen(bundleType))
{
ptr = dirp->d_name;
// str end - strlen of ext
ptr += (dirp->d_namlen - strlen(bundleType));
if(strcmp(ptr, bundleType) == 0) // if extension is of type
{
p = ptr = NXCopyStringBuffer(dirp->d_name);
// str end - strlen of ext
ptr += (dirp->d_namlen - strlen(bundleType) - 1);
*ptr = '\0';
[self loadBundle:p ofType:bundleType owner:o nib:loadNib];
free(p);
}
}
};
closedir(dp);
}
else
[[NXApp delegate] showAlert:"Error opening mainbundle directory."];
return self;
}
//*****************************************************************************
//
// load a bundle of the specified type
//
//*****************************************************************************
- loadBundle:(const char *)p ofType:(const char *)bType owner:o nib:(BOOL)lNib
{
NXBundle *myBundle = nil;
if(![[NXBundle mainBundle] getPath:Path forResource:p ofType:bType])
NXRunAlertPanel(0,"Error getting bundle path",0, 0, 0);
else
{
if(myBundle = [[NXBundle alloc] initForDirectory:Path])
{
[myBundle principalClass];
if(lNib) // should we load a nib
{
if(![myBundle getPath:Path forResource:p ofType:"nib"])
{
NXRunAlertPanel(0,"Error getting nib path",0,0,0);
NXRunAlertPanel(0, Path,0,0,0);
}
else
[NXApp loadNibFile:Path owner:o withNames:YES
fromZone:[self zone]];
}
}
}
return self;
}
//*****************************************************************************
//
// enable pppstats, if aView is nil open w/o a view for stats only
//
//*****************************************************************************
- pppstats:aView
{
// display pppstats?
if(strcmp(NXGetDefaultValue([NXApp appName], "DispPPP"),"YES") == 0)
{
openSocket(aView); // open IP datagram socket, pass a view
intpr();
pppstats = YES;
}
else
pppstats = NO;
return self;
}
//*****************************************************************************
//
// poll pppstats
//
//*****************************************************************************
- pppstats
{
struct pppIO *pppStat;
if(pppstats)
pppStat = intpr();
return self;
}
//*****************************************************************************
//
// load the specified LKS into the kernel
//
//*****************************************************************************
- loadKernelServer:(char *)lks
{
kern_return_t r;
port_name_t kl_port;
task_t kernel_task;
strncpy(BPath,[[NXBundle mainBundle] directory],MAXPATHLEN -strlen(BPath));
strncat(BPath, "/", MAXPATHLEN - strlen(BPath));
strncat(BPath, lks, MAXPATHLEN - strlen(BPath));
if ((r = kern_loader_look_up(&kl_port)) != KERN_SUCCESS)
fprintf(stderr, "GateKeeper: can't find kernel loader %d\n", r);
// Get the kernel's task port.
if ((r = task_by_unix_pid(task_self(), 0, &kernel_task)) != KERN_SUCCESS)
fprintf(stderr, "GateKeeper: get kernel_task %d\n", r);
if ((r = kern_loader_add_server(kl_port,kernel_task,BPath))!= KERN_SUCCESS)
{
fprintf(stderr, "GateKeeper: couldn't allocate kernel server %d\n", r);
fprintf(stderr, "server: %s\n", BPath);
}
if ((r = kern_loader_load_server(kl_port, lks)) != KERN_SUCCESS)
{
fprintf(stderr, "GateKeeper: couldn't load kernel server %d\n", r);
fprintf(stderr, "server: %s\n", BPath);
}
return self;
}
//*****************************************************************************
//
// plays sound
//
//*****************************************************************************
- playSound:(const char *)soundFile
{
id aSound;
if(strcmp(NXGetDefaultValue([NXApp appName], SOUND), "YES") == 0)
{
aSound = [Sound findSoundFor:soundFile];
if(aSound)
[[aSound setDelegate:self] play:nil];
}
return self;
}
//*****************************************************************************
//
// Sound delegate method
//
// Sent to the delegate when the Sound stops playing.
//
//*****************************************************************************
- didPlay:sender
{
return self;
}
//*****************************************************************************
//
// Idle Panel countdown is complete.
//
//*****************************************************************************
- idleFinished
{
[iTimer cleanUp];
[NXApp delayedFree:iTimer];
return self;
}
//*****************************************************************************
//
// Diagnostics Window delegate methods
//
// called whenever the user minituriazes our Diagnostics window.
// called whenever the user closes our Diagnostics window.
//
//*****************************************************************************
- windowWillMiniaturize:sender toMiniwindow:miniwindow
{
return [sender setMiniwindowIcon:"miniWinIcon"];
}
- windowWillClose:sender
{
if(![sender isKindOf:[Panel class]]) // simple test to see if diag
{ // win is what is being closed
if(!NXWriteDefault([NXApp appName], DISPLAYD, "NO"))
[self showAlert:"ddbWriteError"];
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.