1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
|
{
This file is part of the Free Pascal run time library.
Copyright (c) 2003 by the Free Pascal development team
Console and system log version of debug server.
See the file COPYING.FPC, included in this distribution,
for details about the copyright.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************}
{$mode objfpc}
{$h+}
program debugserver;
Uses
msgintf,debugserverintf,baseunix,classes,sysutils,getopts,systemlog;
resourcestring
SUnknownOption = 'Unknown option : %s';
SMessageFrom = '%s [%s] : %s ';
Var
UseSyslog : Boolean;
Const
LogLevel : Integer = log_debug;
Procedure LogEvent(Const Event: TDebugEvent);
Var
S : String;
begin
With Event do
begin
S:=DateTimeToStr(TimeStamp)+' : '+Format(SMessageFrom,[MsgTypes[LogCode],Client.Peer,Event]);
If UseSysLog then
Syslog(LogLevel,Pchar(S),[])
else
Writeln(S);
end;
end;
Function GetFDS(Var AFDS : tfdset) : Integer;
Var
I : Integer;
begin
Result:=0;
fpfd_zero(AFDS);
For I:=0 to FClients.Count-1 do
With TClient(FClients[i]) do
begin
If Handle>Result then
Result:=Handle;
fpfd_set(Handle,AFDS);
end;
Inc(Result);
end;
Procedure StartReading;
Var
ReadFDS : tfdset;
I,maxfds : Integer;
TimeOut : TTimeVal;
begin
Repeat
maxfds:=GetFDS(ReadFDS);
TimeOut.tv_sec:=0;
TimeOut.tv_usec:=10000;
Maxfds:=fpSelect(maxfds,@ReadFDS,Nil,Nil,@TimeOut);
If MaxFds>0 then
begin
For I:=FClients.Count-1 downto 0 do
If fpFD_IsSet(TClient(FClients[i]).Handle,ReadFDS)<>0 then
ReadMessage(TClient(FClients[i]).Handle);
end;
// Check for new connection.
CheckNewConnection;
Until (FClients.Count=0);
end;
procedure Wait;
Var
TV,TR : TimeSpec;
begin
tv.tv_sec:=1;
tv.tv_nsec:=0;
fpnanosleep(@tv,@tr);
end;
Procedure HandleConnections;
begin
Repeat
If CheckNewConnection<>Nil then
StartReading
else
Wait;
Until quit;
end;
Var
OldHUPHandler,
OldINTHandler,
OldQUITHandler,
OldTERMHandler : SigActionRec;
Procedure HandleSig(Sig : Longint); Cdecl;
Var
OH : Signalhandler;
begin
Quit:=True;
Case Sig of
SIGHUP : OH:=signalhandler(OldHUPHandler.sa_handler);
SIGTERM : OH:=signalhandler(OldTERMHandler.sa_handler);
SIGQUIT : OH:=signalhandler(OldQUITHandler.sa_handler);
SIGINT : OH:=signalhandler(OldINTHandler.sa_handler);
else
OH:=Nil;
end;
If (OH<>SignalHandler(SIG_DFL)) then
OH(Sig);
end;
Procedure SetupSignals;
Procedure SetupSig (Sig : Longint; Var OH : SigactionRec);
Var
Act : SigActionRec;
begin
signalhandler(Act.sa_handler):=@HandleSig;
fpsigemptyset(act.sa_mask);
Act.SA_FLAGS:=0;
{$ifdef linux} // ???
Act.Sa_restorer:=Nil;
{$endif}
if fpSigAction(Sig,@Act,@OH)=-1 then
begin
Writeln(stderr,SErrFailedToSetSignalHandler);
Halt(1)
end;
end;
begin
SetupSig(SIGTERM,OldTERMHandler);
SetupSig(SIGQUIT,OldQUITHandler);
SetupSig(SIGINT,OldINTHandler);
SetupSig(SIGHUP,OldHUPHandler);
end;
Procedure Usage;
begin
Writeln('Usage : debugserver [options]');
Writeln('where options is one of');
Writeln(' -h this help');
Writeln(' -s socket use unix socket');
Writeln(' -l uses syslog instead of standard output');
Halt(1);
end;
Procedure ProcessOptions;
Var
C : Char;
I : Integer;
begin
UseSyslog:=False;
Repeat
C:=getopt('hl::s:');
case c of
'h' : Usage;
's' : DebugSocket:=OptArg;
'l' : begin
UseSysLog:=True;
LogLevel:=StrToIntdef(OptArg,LogLevel);
end;
'?' : begin
Writeln(Format(SUnknownOption,[OptOpt]));
Usage;
end;
end;
Until (C=EndOfOptions);
if OptInd<=ParamCount then
begin
For I:=OptInd to ParamCount do
Writeln(Format(SUnknownOption,[Paramstr(i)]));
Usage;
end;
end;
Procedure SetupSysLog;
Var
Prefix : String;
begin
prefix:=format('DebugServer[%d] ',[fpGetPID]);
OpenLog(pchar(prefix),LOG_NOWAIT,LOG_DEBUG);
end;
Procedure CloseSyslog;
begin
CloseLog;
end;
begin
ProcessOptions;
SetupSignals;
If UseSysLog then
SetupSyslog;
OpenDebugServer;
DebugLogCallback:=@LogEvent;
Try
HandleConnections;
Finally
CloseDebugServer;
If UseSyslog then
CloseSyslog;
end;
end.
|