This is Controller.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "Controller.h" #import <stdio.h> #import <syscall.h> #import <pwd.h> #import <strings.h> #import <sys/types.h> #import <netdb.h> #import <signal.h> #import <defaults.h> #import <objc/Storage.h> #import <soundkit/Sound.h> @implementation Controller void killCr(char *c, int len) { int i; for(i=0;((i<len) && (c[i]!='\0'));i++) if (c[i] == '\n') c[i] = '\0'; return; } int membercmp(MemberRecord *r1, MemberRecord *r2) { return ((!strncmp(r1->user,r2->user,STRING_LENGTH)) && (!strncmp(r1->username,r2->username,STRING_LENGTH)) && (!strncmp(r1->machine,r2->machine,STRING_LENGTH))); } void copymember(MemberRecord *r1, MemberRecord *r2) { strncpy(r1->user,r2->user,STRING_LENGTH); strncpy(r1->username,r2->username,STRING_LENGTH); strncpy(r1->machine,r2->machine,STRING_LENGTH); r1->port = r2->port; return; } DPSTimedEntryProc networkEntryHandler(DPSTimedEntry num, double now, char *userData) { [(id)userData doNetworkTimedEntry:(id)userData]; return 0; } DPSTimedEntryProc alarmEntryHandler(DPSTimedEntry num, double now, char *userData) { [(id)userData doAlarmTimedEntry:(id)userData]; return 0; } - init { [super init]; alertSound = nil; numberAlarms = 0; netTimedEntry = 0; return self; } - addMachineQuit:sender { [NXApp abortModal]; return self; } - addMachineOk:sender { [NXApp stopModal]; return self; } - fetchSound:sender { id pan; const char * const tps[2] = {"snd",NULL}; char str[STRING_LENGTH]; pan = [OpenPanel new]; [pan allowMultipleFiles:NO]; if ([pan runModalForTypes:tps]) { if (alertSound) [alertSound free]; strncpy(str,[pan filename],STRING_LENGTH); if (str && str[0]) alertSound = [[Sound alloc] initFromSoundfile:str]; else alertSound = nil; [soundFileTextField setStringValue:str]; [self setDefaults:soundFileTextField]; } return self; } - doAlarmTimedEntry:sender { if (numberAlarms < (MAXALARMS *2)) { numberAlarms++; [coverButton setState:(![coverButton state])]; } else { numberAlarms = 0; DPSRemoveTimedEntry(alarmTimedEntry); [coverButton setState:NO]; } return self; } - handleAlarm { if ([noisyAlertSwitch state]) { if (alertSound) [alertSound play:self]; else NXBeep(); } if ([visualAlertSwitch state]) { alarmTimedEntry=DPSAddTimedEntry(ALARMENTRYPERIOD, (DPSTimedEntryProc)alarmEntryHandler, (void *)self, 30); } if ([activateOnAlertSwitch state]) { if ([NXApp isHidden]) [NXApp unhide:self]; } return self; } - doOutput:(char *)msg withSender:(MemberRecord *)owner andBold:(BOOL)bold { int l; id p; char str[STRING_LENGTH*3+10]; [self getBrowserString:str fromMember:owner]; sprintf(str,"%s: ",str); p = [logText docView]; l = [p textLength]; [p setSel:l :l]; [p replaceSel:str]; [p setSel:l :[p textLength]]; if (bold) [p setSelFontStyle:NX_BOLD]; else [p setSelFontStyle:NX_ITALIC]; l = [p textLength]; [p setSel:l :l]; [p replaceSel:msg]; l = [p textLength]; [p setSel:l :l]; [p replaceSel:"\n"]; l = [p textLength]; [p setSel:l :l]; return self; } - input:sender { id matrix; int i,s; MemberRecord *temp; char str[1024]; i = [sender textLength]; if (1024 < i) i = 1024; [sender selectAll:self]; s = [sender getSubstring:str start:0 length:i]; [sender replaceSel:""]; str[s] = '\0'; [self doOutput:str withSender:(&me) andBold:YES]; matrix = [memberBrowser matrixInColumn:0]; for(i=0;(i<[matrix cellCount]);i++) { if ([[matrix cellAt:i :0] state]) { temp = [memberStore elementAt:i]; [speak setSendPort:temp->port]; [speak sendMessage:str from:(char *)(&me) length:(sizeof(me))]; } } [sender selectText:self]; return self; } - quit:sender { int i; MemberRecord *temp; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; [speak setSendPort:temp->port]; [speak goodByeIAmLeaving:(char *)(&me) length:(sizeof(me))]; } [memberStore free]; [listen removePort]; [listen free]; [speak free]; [NXApp terminate:self]; return self; } - (BOOL)gotMemberWithMachine:(const char *)machine { int i; MemberRecord *temp; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; if (!strncmp(temp->machine,machine,STRING_LENGTH)) return YES; } return NO; } - (BOOL)gotMember:(MemberRecord *)mem { int i; MemberRecord *temp; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; if (membercmp(mem,temp)) return YES; } return NO; } - changePref:sender { [self setDefaults:sender]; return self; } - getDefaults:sender { const char *c; c = NXReadDefault([NXApp appName],"ShowLogin"); [loginSwitch setState:((c == NULL) || (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"ShowReal"); [realSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"ShowMachine"); [machineSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"UseConference"); [useConferenceSwitch setState:((c == NULL) || (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"UseNetwork"); [useNetworkSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"UseNoiseAlert"); [noisyAlertSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"UseVisualAlert"); [visualAlertSwitch setState:((c == NULL) || (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"ActivateOnAlert"); [activateOnAlertSwitch setState:((c != NULL) && (!strncmp("YES",c,3)))]; c = NXReadDefault([NXApp appName],"SoundFile"); [soundFileTextField setStringValue:c]; return self; } - setDefaults:sender { char str[10]; char param[20]; const char *c; char strn[64]; // Yes, in case you were wondering, this _is_ Evil, not to mention // sloppy in the extreme. if (sender == loginSwitch) strncpy(param,"ShowLogin",20); else if (sender == realSwitch) strncpy(param,"ShowReal",20); else if (sender == machineSwitch) strncpy(param,"ShowMachine",20); else if (sender == useConferenceSwitch) strncpy(param,"UseConference",20); else if (sender == useNetworkSwitch) strncpy(param,"UseNetwork",20); else if (sender == noisyAlertSwitch) strncpy(param,"UseNoiseAlert",20); else if (sender == visualAlertSwitch) strncpy(param,"UseVisualAlert",20); else if (sender == activateOnAlertSwitch) strncpy(param,"ActivateOnAlert",20); else if (sender == soundFileTextField) { NXWriteDefault([NXApp appName],"SoundFile",[sender stringValue]); if (alertSound) [alertSound free]; c = [sender stringValue]; if (c && c[0]) { strncpy(strn,c,64); alertSound = [[Sound alloc] initFromSoundfile:str]; } return self; } if ([sender state]) strncpy(str,"YES",10); else strncpy(str,"NO",10); NXWriteDefault([NXApp appName],param,str); if ((sender == useConferenceSwitch) && ([sender state]) && (NX_ALERTDEFAULT==NXRunAlertPanel("Hey!","Load .Conference File now?", "Ok","Cancel",NULL))) [self doConferenceFile:self]; if ((sender == useNetworkSwitch) && ([sender state]) && (NX_ALERTDEFAULT==NXRunAlertPanel("Hey!","Scan network now?", "Ok","Cancel",NULL))) [self doNetwork:self]; [memberBrowser reloadColumn:0]; return self; } - selectAllMembers:sender { id p; int i; p = [memberBrowser matrixInColumn:0]; for(i=0;(i<[p cellCount]);i++) { [p selectCellAt:i :0]; } return self; } - connectTo:(const char *)machine { int s; MemberRecord *temp; int i; port_t pt; if ((!machine) || (!machine[0]) || (machine[0] == '\0')) return self; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; if (!strncmp(machine,temp->machine,STRING_LENGTH)) return self; } s=NXRunAlertPanel("Hey!", "Attempt to connect to %s?", "Connect","Do Not Connect",NULL,machine); if (s == NX_ALERTDEFAULT) { pt = NXPortNameLookup(APPNAME,machine); if (PORT_NULL!=pt) { [speak setSendPort:pt]; [speak helloIAm:(char *)(&me) length:(sizeof(me))]; } } return self; } - disconnectFrom:(const char *)machine { int s; MemberRecord *temp; int i; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; if (!strncmp(machine,temp->machine,STRING_LENGTH)) { s = NXRunAlertPanel("Hey!", "Attempt to disconnect from %s?", "Disconnect","Stay Connected",NULL,machine); if (s == NX_ALERTDEFAULT) { [speak setSendPort:temp->port]; [speak goodByeIAmLeaving:(char *)&me length:sizeof(me)]; [memberStore removeAt:i]; return self; } } } return self; } - connectMember:sender { char c[STRING_LENGTH]; [addMachinePanel makeKeyAndOrderFront:self]; [addMachineField selectText:self]; if (NX_RUNABORTED == [NXApp runModalFor:addMachinePanel]) { [addMachinePanel close]; return self; } [addMachinePanel close]; strncpy(c,[addMachineField stringValue],STRING_LENGTH); killCr(c,STRING_LENGTH); [self connectTo:c]; [memberBrowser reloadColumn:0]; return self; } - disconnectMember:sender { id p; int i; char c[STRING_LENGTH]; MemberRecord *temp; c[0] = '\0'; p = [memberBrowser matrixInColumn:0]; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; if ([[p cellAt:i :0] state]) { strncpy(c,temp->machine,STRING_LENGTH); killCr(c,STRING_LENGTH); } } if (c[0]) { [self disconnectFrom:c]; } [memberBrowser reloadColumn:0]; return self; } - connectMachine:sender { id p,q; char c[STRING_LENGTH]; p = machineBrowser; q = [[p matrixInColumn:[p selectedColumn]] selectedCell]; if (q == nil) return self; strncpy(c,[q stringValue],STRING_LENGTH); killCr(c,STRING_LENGTH); [self connectTo:c]; [memberBrowser reloadColumn:0]; return self; } - disconnectMachine:sender { id p,q; char c[STRING_LENGTH]; p = machineBrowser; q = [[p matrixInColumn:[p selectedColumn]] selectedCell]; if (q == nil) return self; strncpy(c,[q stringValue],STRING_LENGTH); killCr(c,STRING_LENGTH); [self disconnectFrom:c]; [memberBrowser reloadColumn:0]; return self; } - addMachineToConferenceFile:(const char *)machine { FILE *fd; char str[STRING_LENGTH+30]; char lstr[STRING_LENGTH]; char *cont; sprintf(str,"%s/%s",homedir,".ConferenceMachines"); fd = fopen(str,"r"); if (fd != NULL) { for(cont = fgets(lstr,STRING_LENGTH,fd); cont; cont = fgets(lstr,STRING_LENGTH,fd)) { killCr(lstr,STRING_LENGTH); if (!strncmp(lstr,machine,STRING_LENGTH)) { fclose(fd); return self; } } fclose(fd); } fd = fopen(str,"a"); if (fd != NULL) { fputs(machine,fd); fputc('\n',fd); fclose(fd); } else { fd = fopen(str,"w"); if (fd != NULL) { fputs(machine,fd); fputc('\n',fd); fclose(fd); } } return self; } - removeMachineFromConferenceFile:(const char *)machine { FILE *fd; char str[STRING_LENGTH+30]; char lstr[STRING_LENGTH]; int i; char *cont; char mach[STRING_LENGTH]; id tempStore; strncpy(mach,machine,STRING_LENGTH); killCr(mach,STRING_LENGTH); tempStore = [[Storage alloc] initCount:0 elementSize:(sizeof(char) * STRING_LENGTH) description:MACHINESTORAGEDESCRIPTION]; sprintf(str,"%s/%s",homedir,".ConferenceMachines"); fd = fopen(str,"r"); if (fd != NULL) { for(cont = fgets(lstr,STRING_LENGTH,fd); cont; cont = fgets(lstr,STRING_LENGTH,fd)) { killCr(lstr,STRING_LENGTH); if (strncmp(lstr,mach,STRING_LENGTH)) { [tempStore addElement:lstr]; } } fclose(fd); } fd = fopen(str,"w"); if (fd == NULL) return self; for(i=0;(i<[tempStore count]);i++) { fputs([tempStore elementAt:i],fd); fputc('\n',fd); } fclose(fd); [tempStore free]; return self; } - addMachine:sender { char c[STRING_LENGTH]; [addMachinePanel makeKeyAndOrderFront:self]; [addMachineField selectText:self]; if (NX_RUNABORTED == [NXApp runModalFor:addMachinePanel]) { [addMachinePanel close]; return self; } [addMachinePanel close]; strncpy(c,[addMachineField stringValue],STRING_LENGTH); killCr(c,STRING_LENGTH); if (c[0]) { [self addMachineToConferenceFile:c]; [machineBrowser reloadColumn:0]; if (strncmp(me.machine,c,STRING_LENGTH)) { [self connectTo:c]; [memberBrowser reloadColumn:0]; } } return self; } - removeMachine:sender { id p,q; char c[STRING_LENGTH]; p = machineBrowser; q = [[p matrixInColumn:[p selectedColumn]] selectedCell]; if (q == nil) return self; strncpy(c,[q stringValue],STRING_LENGTH); killCr(c,STRING_LENGTH); if (c && c[0]) { [self removeMachineFromConferenceFile:c]; [machineBrowser reloadColumn:0]; if (strncmp(me.machine,c,STRING_LENGTH)) [self disconnectFrom:c]; [memberBrowser reloadColumn:0]; } return self; } - getBrowserString:(char *)str fromMember:(MemberRecord *)mem { str[0] = '\0'; if ([loginSwitch state]) { sprintf(str,"%s",mem->user); } if ([realSwitch state]) { if (str[0]) sprintf(str,"%s (%s)",str,mem->username); else sprintf(str,"(%s)",mem->username); } if ([machineSwitch state]) { if (str[0]) sprintf(str,"%s@%s",str,mem->machine); else sprintf(str,"%s",mem->machine); } return self; } - yeahRight:sender { if (!strcmp([sender title],"Thomas K. Burkholder")) { [sender setTitle:"Waddya want, a picture?"]; } else { [sender setTitle:"Thomas K. Burkholder"]; } return self; } - doConferenceFile:sender { char *cont; port_t pt; FILE *fd; char str[STRING_LENGTH+30]; sprintf(str,"%s/%s",homedir,".ConferenceMachines"); fd = fopen(str,"r"); if (fd == NULL) return self; for(cont = fgets(str,STRING_LENGTH,fd); cont; cont = fgets(str,STRING_LENGTH,fd)) { killCr(str,STRING_LENGTH); if ((![self gotMemberWithMachine:str]) && (strncmp("localhost",str,STRING_LENGTH)) && (strncmp("broadcasthost",str,STRING_LENGTH)) && (strncmp(me.machine,str,STRING_LENGTH))) { pt = NXPortNameLookup(APPNAME,str); if (PORT_NULL!=pt) { [speak setSendPort:pt]; [speak helloIAm:(char *)(&me) length:(sizeof(me))]; } } } return self; } - doNetworkTimedEntry:sender { port_t pt; struct hostent *he; he = gethostent(); if (he == NULL) { DPSRemoveTimedEntry(netTimedEntry); netTimedEntry = 0; return self; } if ((![self gotMemberWithMachine:he->h_name]) && (strncmp("localhost",he->h_name,STRING_LENGTH)) && (strncmp("broadcasthost",he->h_name,STRING_LENGTH)) && (strncmp(me.machine,he->h_name,STRING_LENGTH))) { pt = NXPortNameLookup(APPNAME,he->h_name); if (PORT_NULL!=pt) { [speak setSendPort:pt]; [speak helloIAm:(char *)(&me) length:(sizeof(me))]; } } return self; } - doNetwork:sender { sethostent(1); if (!netTimedEntry) netTimedEntry = DPSAddTimedEntry(NETWORKENTRYPERIOD, (DPSTimedEntryProc)networkEntryHandler, (void *)self, NX_BASETHRESHOLD); return self; } - appDidInit:sender { struct passwd *pwent; char str[64]; const char *c; [self getDefaults:sender]; // Initialize sound alert c = [soundFileTextField stringValue]; if (c && c[0]) { strncpy(str,c,64); alertSound = [[Sound alloc] initFromSoundfile:str]; } // Initialize visual alert alertWindow = [NXApp appIcon]; [[alertWindow setContentView:coverButton] free]; pwent = getpwuid(getuid()); strncpy(homedir,pwent->pw_dir,STRING_LENGTH); strncpy(me.user,pwent->pw_name,STRING_LENGTH); sscanf(pwent->pw_gecos,"%[^,]",me.username); gethostname(me.machine,STRING_LENGTH); killCr(me.machine,STRING_LENGTH); memberStore = [[Storage alloc] initCount:0 elementSize:(sizeof(MemberRecord)) description:MEMBERSTORAGEDESCRIPTION]; speak = [[ConferenceSpeaker alloc] init]; listen = [[ConferenceListener alloc] init]; [listen setDelegate:self]; [listen checkInAs:APPNAME]; [listen addPort]; if ([useConferenceSwitch state]) [self doConferenceFile:self]; [machineBrowser reloadColumn:0]; if ([useNetworkSwitch state]) [self doNetwork:self]; [memberBrowser reloadColumn:0]; [[inputText docView] setDelegate:self]; [[inputText docView] setCharFilter:(NXCharFilterFunc)NXFieldFilter]; [[inputText window] makeKeyAndOrderFront:self]; [[inputText docView] selectAll:sender]; return self; } -(int)browser:sender fillMatrix:matrix inColumn:(int)column { id currentCell; int i; if (sender == memberBrowser) { MemberRecord *temp; char l[STRING_LENGTH*3 + 10]; for(i=0;(i<[memberStore count]);i++) { [matrix addRow]; currentCell = [matrix cellAt:i :column]; temp = [memberStore elementAt:i]; [self getBrowserString:l fromMember:temp]; [currentCell setStringValue:l]; [currentCell setLeaf:YES]; [currentCell setLoaded:YES]; [currentCell setTag:i]; } return i; } else { // sender is machineBrowser FILE *fd; char str[STRING_LENGTH+30]; char lstr[STRING_LENGTH]; char *cont; sprintf(str,"%s/%s",homedir,".ConferenceMachines"); fd = fopen(str,"r"); if (fd == NULL) return 0; for(i = 0,cont = fgets(lstr,STRING_LENGTH,fd); cont; cont = fgets(lstr,STRING_LENGTH,fd)) { if (lstr && lstr[0] && (lstr[0] != '\n')) { [matrix addRow]; currentCell = [matrix cellAt:i:0]; [currentCell setStringValue:lstr]; [currentCell setLeaf:YES]; [currentCell setLoaded:YES]; [currentCell setTag:i]; i++; } } fclose(fd); return i; } } - textDidEnd:sender endChar:(unsigned short)whyEnd { if (whyEnd != 0) [self input:sender]; return self; } - (int)helloIAm:(char *)fr length:(int)len { MemberRecord temp,*mr; mr = (MemberRecord *)fr; if ([self gotMember:mr]) return 0; copymember(&temp,mr); temp.port = NXPortNameLookup(APPNAME,mr->machine); [memberStore addElement:&temp]; [speak setSendPort:temp.port]; [speak helloIAm:(char *)(&me) length:(sizeof(me))]; [memberBrowser reloadColumn:0]; return 0; } - (int)goodByeIAmLeaving:(char *)fr length:(int)len { int i; MemberRecord *temp; for(i=0;(i<[memberStore count]);i++) { temp = [memberStore elementAt:i]; if (membercmp((MemberRecord *)fr,temp)) { [memberStore removeAt:i]; } } [memberBrowser reloadColumn:0]; return 0; } - (int)sendMessage:(char *)msg from:(char *)fr length:(int)len { id p; if ([NXApp isHidden]) { [self handleAlarm]; } [self doOutput:msg withSender:(MemberRecord *)fr andBold:NO]; p = [inputText docView]; [p setSel:[p textLength] :[p textLength]]; return 0; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.