This is Controller.m in view mode; [Download] [Up]
#import "Controller.h"
#import "EnhancedText.h"
#import "Defaults.h"
#import "TokenString.h"
#import "Subprocess.h"
#import "Boolean.h"
#import "UpDownView.h"
#import "EnhancedMatrix.h"
#define STRING_BUF_SIZE 100
void tickTock(DPSTimedEntry te, double now, void *userData );
@implementation Controller
- init
{
_defaults = [Defaults new];
_logProcess = nil;
_sound = [[Sound alloc] init];
_currentHostName = [[StringStorage alloc] init];
_totalTimeDWrite = [[StringStorage alloc] init];
_startDWrite = [[StringStorage alloc] init];
_lastResetDWrite = [[StringStorage alloc] init];
return self;
}
- awakeFromNib
{
id myConnection;
[self setCurrentHostName: [_defaults get: "DefaultHost"]];
/* Remote object connection */
_connectionStatus = [[Boolean alloc] init];
[_connectionStatus setDelegate: self];
myConnection = [NXConnection registerRoot: _connectionStatus withName: [NXApp appName]];
[myConnection runFromAppKit];
[self updateCounters: self];
[upDownView setIsUp: NO];
if(!strcmp("Yes",[_defaults get: "DisplayLog"]))
[self openLog: self];
if(!strcmp("Yes",[_defaults get: "DisplayMeter"]))
[meterPanel makeKeyAndOrderFront: self];
[self initUpStatus]; /* Are we alreay up? */
/* Do we want to autolaunch ppp... try it if we do - won't hurt. */
if(!strcmp("Yes",[_defaults get: "StartPPPOnLaunch"]))
[self start: self];
return self;
}
- updateCounters: sender
{
char tbuf[64];
time_t upTime, newTotal;
[[total window] setTitle: [self currentHostName]];
[upDownView display];
upTime = [upDownView upTime];
newTotal = totalTime + upTime;
if(!(newTotal % 60) || (sender == nil))
{
sprintf(tbuf,"%ld",newTotal);
[_defaults writeDB: [self totalTimeDWrite] as: tbuf];
}
sprintf(tbuf,"%d:%02d:%02d", newTotal / 3600 , (newTotal % 3600) / 60, newTotal % 60);
[total setStringValue: tbuf];
sprintf(tbuf,"%d:%02d:%02d", upTime / 3600 , (upTime % 3600) / 60, upTime % 60);
[session setStringValue: tbuf];
return self;
}
- resetCounters: sender
{
totalTime = 0L;
[upDownView resetUpTime];
[self setLastResetDate: time((time_t *)0)];
return [self updateCounters: sender];
}
- startDefault: sender
{
[self setCurrentHostName: [_defaults get: "DefaultHost"]];
[self start: sender];
return self;
}
- start: sender
{
id proc;
if(![_connectionStatus boolState])
proc = [[Subprocess alloc] init: [_defaults get: [self startDWrite]] withDelegate: nil
andPtySupport: YES andStdErr: NO];
return self;
}
- stop: sender
{
id proc;
if([_connectionStatus boolState])
proc = [[Subprocess alloc] init: [_defaults get: "PPPStop"]];
return self;
}
- openLog:sender
{
if(!_logProcess)
{
id cmd = [[[StringStorage alloc] init] autorelease];
[cmd setFStringValue: "tail -1f %s",[_defaults get: "LogFile"]];
_logProcess = [[Subprocess alloc] init: [cmd stringValue] withDelegate: self
andPtySupport: NO andStdErr: NO];
}
[logPanel makeKeyAndOrderFront: self];
return self;
}
- (void) setLastResetDate: (time_t) atime
{
id string = [[[StringStorage alloc] init] autorelease];
char *dateStr;
if(!atime)
atime = (time_t)atol(((dateStr = (char *)[_defaults get: [self lastResetDWrite]])?dateStr:"0"));
else
{
[string setFStringValue: "%ld", (long) atime];
[_defaults writeDB: [self lastResetDWrite] as: [string stringValue]];
}
dateStr = ctime(&atime);
[string setFStringValue: "%6.6s %4.4s", dateStr + 4, dateStr + 20];
[lastReset setStringValue: [string stringValue]];
}
- (void) setIsUp: (BOOL) aValue since: (time_t) aTime
{
if(aValue)
[upDownView setIsUp: aValue since: aTime];
[_connectionStatus setBoolState: aValue];
}
- (void) initUpStatus
{
id str;
FILE *proc;
char buf[STRING_BUF_SIZE + 1], *ptr;
BOOL isUp = NO;
time_t since = (time_t)0, now;
now = time((time_t *)0);
/* See if ppp0 is up already.... */
if(proc = popen("/usr/etc/ifconfig ppp0 | fgrep UP","r"))
{
if(fgets(buf,STRING_BUF_SIZE,proc) && strstr(buf,"UP"))
{ /* it is... since when? */
isUp = YES;
pclose(proc);
/* look for the uptime message pppstatus places in */
str = [[[StringStorage alloc] init] autorelease];
[str setFStringValue: "/usr/bin/fgrep 'PPPMeter uptime:' %s | /usr/ucb/tail -1",
[_defaults get: "LogFile"]];
if(proc = popen([str stringValue],"r"))
{
if(fgets(buf,STRING_BUF_SIZE,proc) && (ptr = strstr(buf,"uptime:")))
{ /* found it! */
sscanf(ptr,"uptime:%ld",&since);
[str setFStringValue:
"PPP is up! I found an uptime of %14.14s - use that or NOW?", ctime(&since) + 4];
if(NXRunAlertPanel([NXApp appName], [str stringValue], "Use it", "Use NOW", NULL) ==
NX_ALERTALTERNATE)
since = now;
}
else
{
NXRunAlertPanel([NXApp appName], "PPP is up! I can't tell from when - starting meter NOW.",
"OK", NULL, NULL);
since = now;
}
}
}
pclose(proc);
}
[self setIsUp: isUp since: since];
}
- (const char *) currentHostName
{
return [_currentHostName stringValue];
}
- (void) setCurrentHostName: (const char *)aHost
{
const char *str;
[_currentHostName setStringValue: aHost];
[_totalTimeDWrite setFStringValue: "%s TotalTime", aHost];
[_startDWrite setFStringValue: "%s PPPStart", aHost];
[_lastResetDWrite setFStringValue: "%s LastReset", aHost];
totalTime = atol(((str = [_defaults get: [self totalTimeDWrite]])?str:"0"));
[self setLastResetDate: (time_t)0];
[upDownView resetUpTime];
[self updateCounters: self];
}
- (const char *) totalTimeDWrite
{
return [_totalTimeDWrite stringValue];
}
- (const char *) startDWrite
{
return [_startDWrite stringValue];
}
- (const char *) lastResetDWrite
{
return [_lastResetDWrite stringValue];
}
- startHost: sender
{
[hosts loadFromString: [_defaults get: "Hosts"]];
[hosts setTarget:self];
[hosts setDoubleAction: @selector(setHost:)];
[[hosts window] makeKeyAndOrderFront: sender];
return self;
}
- setHost: sender
{
[self setCurrentHostName: [hosts selectedStringValue]];
[[hosts window] orderOut:sender];
[self start: sender];
return self;
}
- showStats: sender
{
id hostList = [[[TokenString alloc] init: [_defaults get: "Hosts"]] autorelease];
id str = [[[StringStorage alloc] init] autorelease];
const char *label, *ptr;
time_t uTime;
[hostList setSeparator: ';'];
[stats empty: self];
while((label = [hostList popStringValue]))
{
[stats appendStringValue: label];
[str setFStringValue: "%s TotalTime",label];
uTime = atol((ptr = [_defaults get: [str stringValue]])? ptr : "0");
[str setFStringValue: "%d:%02d:%02d", uTime/3600,(uTime % 3600)/60,uTime%60];
[stats appendStringValue: " has "];
[stats appendStringValue: [str stringValue]];
[stats appendStringValue: " connect time since "];
[str setFStringValue: "%s LastReset",label];
uTime = atol((ptr = [_defaults get: [str stringValue]])? ptr : "0");
ptr = ctime(&uTime);
[str setFStringValue: "%6.6s %4.4s", ptr + 4, ptr + 20];
[stats appendStringValue: [str stringValue]];
[stats appendStringValue: "\n"];
}
[[stats window] makeKeyAndOrderFront: self];
return self;
}
@end
@implementation Controller (ControllerAppDelegate)
- appDidInit: sender
{
[[[NXApp appIcon] contentView] addSubview: upDownView];
[[NXApp appIcon] display];
return self;
}
- appWillTerminate: sender
{
char tbuf[60];
if(_logProcess)
[_logProcess terminate: self];
if([_connectionStatus boolState])
[self stop: self];
sprintf(tbuf,"%ld",totalTime + [upDownView upTime]);
[_defaults writeDB: [self totalTimeDWrite] as: tbuf];
return self;
}
@end
@implementation Controller (ControllerSubprocessDelegate)
- subprocessDone
{
if(_logProcess)
_logProcess = [_logProcess free];
return self;
}
- subprocessOutput:(char *)buf
{
[logText appendStringValue: buf];
return self;
}
@end
@implementation Controller (ControllerBooleanDelegate)
- (void) boolStateSetTo: (BOOL) aValue
{
const char *sndFile;
if(aValue)
{
if(![upDownView isUp]) /* just started... */
{
[upDownView setIsUp: YES]; /* start new one */
sndFile = [_defaults get: "UpSound"];
if(sndFile && *sndFile)
{
[_sound readSoundfile: sndFile];
[_sound play];
}
}
ticker = DPSAddTimedEntry(1, tickTock, (void *)self, NX_MODALRESPTHRESHOLD + 1);
}
else if (!aValue && [upDownView isUp])
{
DPSRemoveTimedEntry(ticker);
[self updateCounters: nil]; /* pass nil to force it to write out value */
[upDownView setIsUp: NO];
sndFile = [_defaults get: "DownSound"];
if(sndFile && *sndFile)
{
[_sound readSoundfile: sndFile];
[_sound play];
}
}
[upDownView display];
}
@end
void tickTock(DPSTimedEntry te, double now, void *userData )
{
[(id)userData updateCounters: userData];
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.