home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-24 | 6.3 KB | 242 lines | [TEXT/PJMM] |
- {$I-}
- program Fingerd;
-
- { This code is part of the Finger/Fingerd source code, written in THINK Pascal 4 }
- { Copyright 1991-1992 Peter N Lewis }
- { If you use this code, you must give me credit in your about box and documentation }
-
- uses
- AppleTalk, PPCToolbox, Processes, EPPC, Notification, AppleEvents, {}
- TCPTypes, TCPStuff, FingerDaemon, PrefsGlobals, Folders, MyUtilities, MyPreferences;
-
- const
- strh_id = 128;
- prefname_index = 1;
- pref_launch_str = 2;
- quitnow_index = 3;
- lf = 10;
- daemons_max = 10;
-
- var
- quitNow: boolean;
-
- function GotRequiredParams (theAppleEvent: AppleEvent): OSErr; { <aevt> }
- var
- typeCode: DescType;
- actualSize: Size;
- err: OSErr;
- begin
- err := AEGetAttributePtr(theAppleEvent, keyMissedKeywordAttr, typeWildCard, typeCode, nil, 0, actualSize); { nil ok: need only function result }
- if err = errAEDescNotFound then { we got all the required params: all is ok }
- GotRequiredParams := noErr
- else if err = noErr then
- GotRequiredParams := errAEEventNotHandled
- else
- GotRequiredParams := err;
- end; { GotRequiredParams }
-
- function HandleQUIT (theAppleEvent, reply: AppleEvent; quitp: ptr): OSErr; { <aevt> }
- var
- oe: OSErr;
- errStr: Str255;
- willQuit: Boolean; { did the user allow the quit or cancel }
- begin
- { We don't expect any params at all, but check in case the client requires any }
- oe := GotRequiredParams(theAppleEvent);
- quitNow := true;
- if reply.dataHandle <> nil then { a reply is sought }
- begin
- if oe = noErr then
- errStr := 'OK'
- else
- errStr := 'user cancelled quit';
- oe := AEPutParamPtr(reply, 'errs', 'TEXT', Ptr(@errStr[1]), length(errStr));
- end;
- HandleQUIT := oe;
- end;
-
- function OpenPrefFile (name: str63): integer;
- var
- vrn: integer;
- dirID: longint;
- oe: OSErr;
- gv: longInt;
- fil: integer;
- begin
- oe := Gestalt(gestaltFindFolderAttr, gv);
- if (oe = noErr) & (BTST(gv, gestaltFindFolderPresent)) & (FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, vrn, dirID) = NoErr) then
- fil := HOpenResFile(vrn, dirID, name, fsRdPerm)
- else begin
- fil := OpenResFile(concat(':Preferences:', name));
- if fil <> -1 then
- fil := OpenResFile(name);
- end;
- OpenPrefFile := fil;
- end;
-
- procedure HandleEvents (speed: integer);
- var
- dummy: boolean;
- er: eventRecord;
- oe: OSErr;
- begin
- dummy := WaitNextEvent(everyEvent, er, speed, nil);
- if er.what = kHighLevelEvent then
- if has_AppleEvents then
- oe := AEProcessAppleEvent(er);
- end;
-
- function StackPtr: longInt;
- inline
- $2E8F;
-
- var
- tcpc: array[1..daemons_max] of TCPConnectionPtr;
- t: TCPStateType;
- buffer: str255;
- temp: longInt;
- finger_port: integer;
- readPos: longInt;
- f: longInt;
- gotlf: boolean;
- i: integer;
- oe: OSErr;
- appllimitP: ^longInt;
- remoteIP: longInt;
- quitNowStr: str15;
- pref_name: str63;
- defrefnum: integer;
- gv: longInt;
- max_daemons, this_daemon: integer;
- finished: boolean;
- prefs_fs: FSSpec;
- prefs_rn: integer;
- begin
- applLimitP := POINTER($130);
- applLimitP^ := StackPtr - 5000;
- { SetApplLimit(ptr(StackPtr - 5000));}
- MaxApplZone;
- MoreMasters;
- GetIndString(buffer, strh_id, quitnow_index);
- quitNowStr := buffer;
- GetIndString(buffer, strh_id, prefname_index);
- pref_name := buffer;
- GetIndString(buffer, fingerd_strh, fingerd_port_index);
- StringToNum(buffer, temp);
- {$PUSH}
- {$R-}
- finger_port := temp;
- {$R-}
- quitNow := false;
- oe := Gestalt(gestaltAppleEventsAttr, gv);
- has_AppleEvents := (oe = noErr) and (gv = 1);
- if has_AppleEvents then
- oe := AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, @HandleQUIT, 0, false);
- for i := 1 to 5 do
- HandleEvents(5);
- oe := TCPInit;
- if oe = noErr then begin
- oe := Gestalt('mtcp', gv);
- if (oe = noErr) and (gv >= 1) then begin
- GetIndString(buffer, fingerd_strh, daemons_max_index);
- StringToNum(buffer, gv);
- if gv > daemons_max then
- max_daemons := daemons_max
- else if gv < 1 then
- max_daemons := 1
- else
- max_daemons := gv;
- end
- else
- max_daemons := 1;
- InitDaemon;
- for i := 1 to max_daemons do
- tcpc[i] := nil;
- for i := 1 to max_daemons do begin
- oe := TCPPassiveOpen(tcpc[i], finger_port, 0, 0, nil);
- if oe <> noErr then begin
- quitNow := true;
- tcpc[i] := nil;
- leave;
- end;
- end;
- while not quitNow do begin
- IdleFingers;
- this_daemon := -1;
- while (this_daemon < 0) and not quitNow do begin
- HandleEvents(15);
- IdleFingers;
- for i := 1 to max_daemons do
- if TCPState(tcpc[i]) <> T_Listening then
- this_daemon := i;
- end;
- if not quitNow then begin
- f := TickCount;
- readPos := 0;
- repeat
- HandleEvents(5);
- IdleFingers;
- {$PUSH}
- {$R-}
- oe := TCPReceiveUpTo(tcpc[this_daemon], lf, 1, @buffer[1], 255, readPos, gotlf);
- {$POP}
- until (oe <> noErr) or (readPos = 255) or gotlf or (TickCount > f + 60 * 60) or quitNow;
- if gotlf then begin
- {$PUSH}
- {$R-}
- buffer[0] := chr(readPos - 2);
- {$POP}
- quitNow := (quitNowStr <> '') and (quitNowStr = buffer);
- IdleFingers;
- oe := SysEnvirons(1, sysenv);
- oe := SetVol(nil, sysenv.sysVRefNum);
- GetPrefsFSSpec(prefs_fs);
- prefs_rn := OpenPrefsFile(prefs_fs);
- GetPrefs(prefs);
- if prefs.plan_dirID <> -1 then
- SendPlan(tcpc[this_daemon], prefs.plan_vrn, prefs.plan_dirID, prefs.plan_name, buffer)
- else
- SendPlan(tcpc[this_daemon], 0, 0, 'Plan', buffer);
- if prefs_rn <> -1 then
- CloseResFile(prefs_rn);
- end;
- oe := TCPFlush(tcpc[this_daemon]);
- oe := TCPClose(tcpc[this_daemon], nil);
- t := TCPState(tcpc[this_daemon]);
- f := TickCount;
- while (t <> T_Closed) and (TickCount < f + 60 * 60) do begin
- IdleFingers;
- HandleEvents(5);
- t := TCPState(tcpc[this_daemon]);
- end;
- oe := TCPRelease(tcpc[this_daemon]);
- if not quitNow then begin
- oe := TCPPassiveOpen(tcpc[this_daemon], finger_port, 0, 0, nil);
- if oe <> noErr then
- leave;
- end
- else
- tcpc[this_daemon] := nil;
- end;
- end;
- for i := 1 to max_daemons do
- if tcpc[i] <> nil then
- oe := TCPClose(tcpc[i], nil);
- f := TickCount;
- finished := false;
- while not finished and (TickCount < f + 60 * 60) do begin
- HandleEvents(5);
- finished := true;
- for i := 1 to max_daemons do
- if tcpc[i] <> nil then
- if TCPState(tcpc[i]) <> T_Closed then
- finished := false
- else begin
- oe := TCPRelease(tcpc[i]);
- tcpc[i] := nil;
- end;
- end;
- FinishDaemon;
- TCPFinish;
- end;
- end.