This is Storm.m in view mode; [Download] [Up]
/* * Object to peck on a remote network weather service. * * Michael Hawley * MIT Media Laboratory * 20 Ames Street * Cambridge, MA 02139 * mike@media-lab.mit.edu * Copyright (c) 1991 MIT Media Laboratory * Burn before reading! This means you!! * * Please forward any comments/revisions. * Keep in mind that this was a one-day knock off; * much of the complexity is due to the fact that * we have to parse a telnet conversation that was * never intended for such. */ #import "Storm.h" #import "Process.h" #import "MyMenuCell.h" #import "Defaults.h" #import "License.h" #import "util.h" #import "state.h" @implementation Storm static int localblank(char *s){ while (*s && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')) s++; return *s? 0 : 1; } static id _status; static id _Parrot; /* compiler hated _P ! */ static id _text, _scroll; static id fid = (id)0; static int canconvert = 0; static id me; char * path(char *s) /* * if 's' is in [NXArgv[0]], return [NXArgv[0]]/s. * (for looking up internal commands and files in .../Opener.app/...). */ { char t[1024], *q, *r; static char p[1024]; extern char **NXArgv; *t = '\0'; sscanf(s,"%s",t); if (!*t || *t=='(') return s; r = s + strlen(t); strcpy(p,*NXArgv); if (q=rindex(p,'/')) strcpy(q+1,t); else strcpy(p,t); if (access(p,0)==0){ strcpy(p+strlen(p),r); return p; } return s; } void message(char *fmt, ...) { char p[1024]; va_list ap; va_start(ap, fmt); vsprintf(p,fmt,ap); [_status setStringValue:p]; [_status display]; NXPing(); va_end(ap); } static int eq(char *a, char *b){ return strncmp(a,b,strlen(b))==0; } static char *localstrindex(char *s, char *t){ int n = strlen(t); if (s) while (*s) if (!strncmp(s, t, n)) return s; else s++; return (char *)0; } void Put(char *fmt, ...) { va_list ap; char p[1024]; va_start(ap, fmt); vsprintf(p, fmt, ap); if (Verbose) printf("+ %s\n",p); if (_Parrot) [_Parrot puts:p]; va_end(ap); } static char * get(id P, char *s, int n) { [P gets:s:n]; if (*s && Verbose) printf("> %s",s); return *s? s : (char *)0; } char * pgets(char *s, int n) { [_Parrot gets:s:n]; return *s? s : (char *)0; } char * Flush(char *s) { static char t[1024]; if (_Parrot) return (char *)0; while (get(_Parrot,t,sizeof t)) if (localstrindex(t,s)) return t; sleep(1); while (get(_Parrot,t,sizeof t)) if (localstrindex(t,s)) return t; return (char *)0; } - enable:(BOOL)b { [attachB setIcon:b? "plug" : "unplug"]; return self; } - initMatrix { // from the nib file, we have the help text; keep a pointer to it. _text = helpText = [scrollView docView]; [_text setDelegate:self]; [_text setMarginLeft:6.0 right:6.0 top:0.0 bottom:0.0]; [_text notifyAncestorWhenFrameChanged:YES]; return self; } - setScrollView:anObject { _scroll = scrollView = anObject; [self initMatrix]; return self; } - textWillConvert:textObject fromFont:from toFont:to { if (canconvert && strcmp(DefaultFont,[from name])==0 && atof(DefaultFontSize) == [from pointSize]){ strcpy(DefaultFont,[to name]); sprintf(DefaultFontSize,"%f",[to pointSize]); fid = to; writeDefaults(); } return to; } void setText(char *s) { static NXPoint origin = {0.0,0.0}; id w = [_scroll window]; if (!fid){ fid = [Font newFont:DefaultFont size:atof(DefaultFontSize)]; } canconvert=0; [w disableFlushWindow]; [_text setText:s]; [_text setSel:0:999999]; [_text setSelGray:0.0]; [_text setSelFont:fid]; [_text selectNull]; [_text scrollPoint:&origin]; [_scroll display]; [[w reenableFlushWindow] flushWindow]; NXPing(); canconvert=1; } void openFile(char *s){ /* open 's' in workspace */ int ok = 0; id p = [NXApp appSpeaker]; char t[512]; sprintf(t,"\nThe file\n %s\nwill open in the workspace.",s); setText(t); [p setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)]; [p openFile:s ok:&ok]; if (!ok) sprintf(t,"\nCouldn't open: %s",s), setText(t); } static int isRTF(char *s) { int f = open(s,0); if (f > 0){ char t[128]; int n = read(f,t,sizeof(t)); close(f); if (n <= 0) return 0; return strncmp(t,"{\\rtf",5)==0; } else return 0; } void setFile(char *s) { char *p = path(s); NXStream *f = NXMapFile(p,NX_READONLY); static NXPoint origin = {0.0,0.0}; id w = [_scroll window]; canconvert=0; if (!f) return ; [w disableFlushWindow]; if (isRTF(p)){ [_text setMonoFont:NO]; [_text readRichText:f]; } else { [_text readText:f]; [_text setSel:0:999999]; [_text setSelGray:0.0]; if (!fid) fid = [Font newFont:DefaultFont size:atof(DefaultFontSize)]; [_text setSelFont:fid]; [_text selectNull]; canconvert=1; } NXCloseMemory(f,NX_FREEBUFFER); [_text scrollPoint:&origin]; [_scroll display]; [[w reenableFlushWindow] flushWindow]; } - showHelp:sender { setFile("info"); return self; } #define Case break; case static void squishRtn(char *s){ char *p = s; while (*p = *s++) if (*p != '\r') ++p; } static char * getLine(char *s, char *t){ /* read ...\n from s into t; return new s */ char *p = t; *t = '\0'; squishRtn(s); while (*s && *s != '\n') *p++ = *s++; if (*s == '\n') *p++ = *s++; *p++ = '\0'; if (*t == '\0') return (char *)0; if (Verbose) printf("- %s",t); return s; } - processOutput:(char *)s { static char prev[8192]=""; char t[1024], *p=prev; strcat(prev,s); s = t; while ((p=getLine(p,s)) && (index(s,'\n') || strcmp(s+strlen(s)-2,": ")==0 || strcmp(s+strlen(s)-1,":")==0)) execState(0,s); strcpy(prev,localblank(s)?s:""); return self; } void Command(char *s) { if (!_Parrot) { substr(s,"$Site",Site); _Parrot = [Process new:s delegate:me]; } } - click:sender { id c = [[browser matrixInColumn:[browser lastColumn]] selectedCell]; if ([c isLeaf]) [c click:self]; return self; } - click2:sender { return self; } - ensurelogin { //if (!_Parrot) [self login:self]; return self; } int ensurelogin(void){ [me ensurelogin]; return _Parrot? 1 : 0; } - login:sender { if (_Parrot) [_Parrot free]; P = _Parrot = (id)0; _status = status; [self setFetch]; ReadState(path("menus")); [browser setDelegate:self]; [browser setCellPrototype:[[MyMenuCell alloc] init]]; [browser loadColumnZero]; [browser setAction:@selector(click:)]; [browser setDoubleAction:@selector(click2:)]; [browser setTarget:self]; [attachB setIcon:"plug"]; runState(""); return self; } - logout:sender { if (P && _Parrot) setState("Detach"), runState(""); if (P) [P terminate:self]; _Parrot = P = (id)0; [self enable:NO]; [attachB setIcon:"unplug"]; message("not connected."); return self; } void logout(void){ [me logout:me]; } - attach:sender { if (eq((char *)[sender icon],"unplug")){ [self login:sender]; } else { [self logout:sender]; } return self; } /* * the buttons and commands to run at startup time. */ id Fetch[NumFetch]; int FetchSelected = -1; - setFetch { int i; Fetch[0] = fetch1; Fetch[1] = fetch2; Fetch[2] = fetch3; for (i=0;i<NumFetch;i++) [self setFetchText:i:FetchText[i]]; return self; } - setFetchText:(int)i:(char *)s { [Fetch[i] setStringValue:s]; strcpy(FetchText[i],s); [Fetch[i] display]; return self; } - setFetchText:(char *)s { if (FetchSelected >= 0) [self setFetchText:FetchSelected:s]; return self; } void setFetchText(char *s) { [me setFetchText:s]; } - setFetch:(int)i:(int)state { [Fetch[i] setBackgroundGray:state?1.0:.666]; if (state) [self setFetchText:i:""]; else [Fetch[i] display]; return self; } - hitRadio:sender { int i; int n = [sender selectedRow], state = [[sender selectedCell] state]; [self setFetch:n:state]; FetchSelected = state? n : -1; for (i=0; i<NumFetch; i++){ if (i != n || !state){ [[sender cellAt:i:0] setState:0]; [self setFetch:i:0]; } } [sender display]; return self; } void fetchReports(void ) { int i; char buf[80000], *p = buf; while (pgets(buf,1024) && !localstrindex(buf,curMenuLast())) ; *buf = '\0'; for (i=0;i<NumFetch;i++){ if (!localblank(FetchText[i])){ message("%s. . .",FetchText[i]); fetchReport(FetchText[i],p); if (p[0]){ p += strlen(p); if (i < (NumFetch-1)) strcpy(p,"\n===============================\n"); p += strlen(p); } } } squishRtn(buf); squishwhite(buf); if (*buf) setText(buf); message("connected!"); } - setSite:thing { openDefaults(); site = thing; [site setTitle:Site]; return self; } - hitSite:sender { char *s = (char *)[[sender selectedCell] title]; strcpy(Site,s); writeDefaults(); return self; } /* * telnet: */ - copyString:(char *)s { id p = [Pasteboard new]; [p declareTypes:&NXAsciiPboard num:1 owner:self]; [p writeType:NXAsciiPboard data:s length:strlen(s)]; return self; } - launchTerminal:(char *)program { id p = [NXApp appSpeaker]; port_t t = NXPortFromName("Terminal",NULL); int ok; if (t==PORT_NULL) return self; [p setSendPort:t]; [self copyString:program]; (void)[p msgPaste:&ok]; return self; } - telnet:sender { char p[1024]; sprintf(p,"telnet %s 3000\n",Site); [self launchTerminal:p]; return self; } - sendComments:sender { return self; } - print:sender { static int p = 0; if (!p){ p++; [[NXApp printInfo] setScalingFactor:.9]; } return [_text printPSCode:sender]; } - pageLayout:sender { return [NXApp runPageLayout:sender]; } + new { me = self = [[Storm alloc] init]; return self; } - free { [self logout:self]; return [super free]; } - appDidInit:sender { openDefaults(); if (FirstUse()) [license show:self]; [attachB performClick:sender]; return self; } - appWillTerminate:sender { [self logout:self]; System("/bin/rm -rf /tmp/W_maps /tmp/W_scratch &"); writeDefaults(); return self; } - (int)browser:sender fillMatrix:matrix inColumn:(int)column { char *s = "Main"; if (column>0){ id c; c = [[browser matrixInColumn:[browser lastColumn]] selectedCell]; s = [c get]; } setMenu(s); return numItem(s); } - browser:sender loadCell:c atRow:(int)row inColumn:(int)column { [c setStringValueNoCopy:(void *)curMenuItem(row)]; return self; } - browserDidScroll:sender { static int pc = -1; int c = [browser firstVisibleColumn]; ensurelogin(); if (pc == c) return self; pc = c; if (c == 0) Put("m\n"), Flush("Change scroll"), setMenu("Main"); else [[[browser matrixInColumn:0] selectedCell] click:self]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.