Release 11
git-svn-id: https://svn.code.sf.net/p/synalist/code/trunk@25 7c85be65-684b-0410-a082-b2ed4fbef004
This commit is contained in:
parent
fb0759c8f2
commit
cae3686c68
146
asn1util.pas
146
asn1util.pas
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.000.000 |
|
||||
| Project : Delphree - Synapse | 001.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: support for ASN.1 coding and decoding |
|
||||
|==============================================================================|
|
||||
@ -43,83 +43,107 @@ const
|
||||
ASN1_GAUGE = $42;
|
||||
ASN1_TIMETICKS = $43;
|
||||
|
||||
function ASNEncOIDitem(Value: integer): string;
|
||||
function ASNDecOIDitem(var Start: integer; Buffer: string): integer;
|
||||
function ASNEncLen(Len: integer): string;
|
||||
function ASNDecLen(var Start: integer; Buffer: string): integer;
|
||||
function ASNEncInt(Len: integer): string;
|
||||
function ASNEncInt(Value: integer): string;
|
||||
function ASNObject(Data: string; ASNType: integer): string;
|
||||
function ASNItem(var Start: integer; Buffer: string): string;
|
||||
function ASNItem(var Start: integer; Buffer: string; var ValueType:integer): string;
|
||||
|
||||
implementation
|
||||
|
||||
function ASNEncOIDitem(Value: integer): string;
|
||||
var
|
||||
x,xm:integer;
|
||||
b:boolean;
|
||||
begin
|
||||
x:=value;
|
||||
b:=false;
|
||||
result:='';
|
||||
repeat
|
||||
xm:=x mod 128;
|
||||
x:=x div 128;
|
||||
if b then
|
||||
xm:=xm or $80;
|
||||
if x>0
|
||||
then b:=true;
|
||||
result:=char(xm)+result;
|
||||
until x=0;
|
||||
end;
|
||||
|
||||
function ASNDecOIDitem(var Start: integer; Buffer: string): integer;
|
||||
var
|
||||
x:integer;
|
||||
b:boolean;
|
||||
begin
|
||||
result:=0;
|
||||
repeat
|
||||
result:=result*128;
|
||||
x := Ord(Buffer[Start]);
|
||||
inc(start);
|
||||
b:=x>$7f;
|
||||
x:=x and $7f;
|
||||
result:=result+x;
|
||||
if not b
|
||||
then break;
|
||||
until false
|
||||
end;
|
||||
|
||||
function ASNEncLen(Len: integer): string;
|
||||
var
|
||||
x, y: integer;
|
||||
begin
|
||||
if (Len < $80) then
|
||||
Result := Char(Len)
|
||||
else
|
||||
if (Len < $FF) then
|
||||
Result := Char($81) + Char(Len)
|
||||
if (len<$80)
|
||||
then result:=char(len)
|
||||
else
|
||||
begin
|
||||
x := Len div $FF;
|
||||
y := Len mod $FF;
|
||||
Result := Char($82) + Char(x) + Char(y);
|
||||
end;
|
||||
begin
|
||||
x:=len;
|
||||
result:='';
|
||||
repeat
|
||||
y:=x mod 256;
|
||||
x:=x div 256;
|
||||
result:=char(y)+result;
|
||||
until x=0;
|
||||
y:=length(result);
|
||||
y:=y or $80;
|
||||
result:=char(y)+result;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ASNDecLen(var Start: integer; Buffer: string): integer;
|
||||
var
|
||||
x: integer;
|
||||
x,n: integer;
|
||||
begin
|
||||
x := Ord(Buffer[Start]);
|
||||
if (x < $80) then
|
||||
begin
|
||||
Inc(Start);
|
||||
Result := x;
|
||||
end
|
||||
else
|
||||
if (x = $81) then
|
||||
begin
|
||||
Inc(Start);
|
||||
Result := Ord(Buffer[Start]);
|
||||
Inc(Start);
|
||||
end
|
||||
x:=Ord(Buffer[Start]);
|
||||
Inc(Start);
|
||||
if (x<$80)
|
||||
then Result:=x
|
||||
else
|
||||
begin
|
||||
Inc(Start);
|
||||
x := Ord(Buffer[Start]);
|
||||
Inc(Start);
|
||||
Result := x * $FF + Ord(Buffer[Start]);
|
||||
Inc(Start);
|
||||
end;
|
||||
begin
|
||||
result:=0;
|
||||
x:=x and $7f;
|
||||
for n:=1 to x do
|
||||
begin
|
||||
result:=result*256;
|
||||
x:=Ord(Buffer[Start]);
|
||||
Inc(Start);
|
||||
result:=result+x;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ASNEncInt(Len: integer): string;
|
||||
function ASNEncInt(Value: integer): string;
|
||||
var
|
||||
j, y: integer;
|
||||
x,y:integer;
|
||||
begin
|
||||
Result := '';
|
||||
j := 0;
|
||||
y := Len div $FFFFFF;
|
||||
Len := Len - (y * $FFFFFF);
|
||||
if ((y > 0) or (j = 1)) then
|
||||
begin
|
||||
j := 1;
|
||||
Result := Result + Char(y);
|
||||
end;
|
||||
y := Len div $FFFF;
|
||||
Len := Len - (y * $FFFF);
|
||||
if ((y > 0) or (j = 1)) then
|
||||
begin
|
||||
j := 1;
|
||||
Result := Result + Char(y);
|
||||
end;
|
||||
y := Len div $FF;
|
||||
Len := Len - (y * $FF);
|
||||
if ((y > 0) or (j = 1)) then
|
||||
Result := Result + Char(y);
|
||||
Result := Result + Char(Len);
|
||||
x:=Value;
|
||||
result:='';
|
||||
repeat
|
||||
y:=x mod 256;
|
||||
x:=x div 256;
|
||||
result:=char(y)+result;
|
||||
until x=0;
|
||||
end;
|
||||
|
||||
function ASNObject(Data: string; ASNType: integer): string;
|
||||
@ -127,7 +151,7 @@ begin
|
||||
Result := Char(ASNType) + ASNEncLen(Length(Data)) + Data;
|
||||
end;
|
||||
|
||||
function ASNItem(var Start: integer; Buffer: string): string;
|
||||
function ASNItem(var Start: integer; Buffer: string; var ValueType:integer): string;
|
||||
var
|
||||
ASNType: integer;
|
||||
ASNSize: integer;
|
||||
@ -136,6 +160,7 @@ var
|
||||
c: char;
|
||||
begin
|
||||
ASNType := Ord(Buffer[Start]);
|
||||
Valuetype:=ASNType;
|
||||
Inc(start);
|
||||
ASNSize := ASNDecLen(Start, Buffer);
|
||||
Result := '';
|
||||
@ -197,5 +222,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
exit;
|
||||
asm
|
||||
db 'Synapse ASN.1 library by Lukas Gebauer',0
|
||||
end;
|
||||
end.
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.000.000 |
|
||||
| Project : Delphree - Synapse | 001.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: Library base for RAW sockets |
|
||||
|==============================================================================|
|
||||
@ -116,7 +116,7 @@ begin
|
||||
Result:=False;
|
||||
r1:=False;
|
||||
r2:=False;
|
||||
Value:=Timeout*1000;
|
||||
Value:=Timeout;
|
||||
len:=SizeOf(Value);
|
||||
Res:=Winsock.setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,@Value,len);
|
||||
r1:=res<>SOCKET_ERROR;
|
||||
|
78
blcksock.pas
78
blcksock.pas
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.001.001 |
|
||||
| Project : Delphree - Synapse | 002.000.000 |
|
||||
|==============================================================================|
|
||||
| Content: Library base |
|
||||
|==============================================================================|
|
||||
@ -32,6 +32,12 @@ uses
|
||||
|
||||
type
|
||||
|
||||
ESynapseError = class (Exception)
|
||||
Public
|
||||
ErrorCode:integer;
|
||||
ErrorMessage:string;
|
||||
end;
|
||||
|
||||
{TBlockSocket}
|
||||
TBlockSocket = class (TObject)
|
||||
Protected
|
||||
@ -41,6 +47,7 @@ Protected
|
||||
FLastError:integer;
|
||||
FProtocol:integer;
|
||||
FBuffer:string;
|
||||
FRaiseExcept:boolean;
|
||||
|
||||
procedure SetSin (var sin:TSockAddrIn;ip,port:string);
|
||||
function GetSinIP (sin:TSockAddrIn):string;
|
||||
@ -55,7 +62,7 @@ public
|
||||
Procedure CloseSocket;
|
||||
procedure Bind(ip,port:string);
|
||||
procedure Connect(ip,port:string);
|
||||
procedure SendBuffer(buffer:pointer;length:integer); virtual;
|
||||
function SendBuffer(buffer:pointer;length:integer):integer; virtual;
|
||||
procedure SendByte(data:byte); virtual;
|
||||
procedure SendString(data:string); virtual;
|
||||
function RecvBuffer(buffer:pointer;length:integer):integer; virtual;
|
||||
@ -67,6 +74,7 @@ public
|
||||
procedure SetLinger(enable:boolean;Linger:integer);
|
||||
procedure GetSins;
|
||||
function SockCheck(SockResult:integer):integer;
|
||||
procedure ExceptCheck;
|
||||
function LocalName:string;
|
||||
function GetLocalSinIP:string;
|
||||
function GetRemoteSinIP:string;
|
||||
@ -74,7 +82,7 @@ public
|
||||
function GetRemoteSinPort:integer;
|
||||
function CanRead(Timeout:integer):boolean;
|
||||
function CanWrite(Timeout:integer):boolean;
|
||||
procedure SendBufferTo(buffer:pointer;length:integer);
|
||||
function SendBufferTo(buffer:pointer;length:integer):integer;
|
||||
function RecvBufferFrom(buffer:pointer;length:integer):integer;
|
||||
|
||||
published
|
||||
@ -83,6 +91,7 @@ published
|
||||
property RemoteSin:TSockAddrIn read FRemoteSin;
|
||||
property LastError:integer read FLastError;
|
||||
property Protocol:integer read FProtocol;
|
||||
property RaiseExcept:boolean read FRaiseExcept write FRaiseExcept;
|
||||
end;
|
||||
|
||||
{TUDPBlockSocket}
|
||||
@ -108,9 +117,11 @@ implementation
|
||||
constructor TBlockSocket.Create;
|
||||
begin
|
||||
inherited create;
|
||||
FRaiseExcept:=false;
|
||||
FSocket:=INVALID_SOCKET;
|
||||
FProtocol:=IPPROTO_IP;
|
||||
SockCheck(winsock.WSAStartup($101, FWsaData));
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.Destroy}
|
||||
@ -172,6 +183,7 @@ Procedure TBlockSocket.CreateSocket;
|
||||
begin
|
||||
if FSocket=INVALID_SOCKET then FLastError:=winsock.WSAGetLastError
|
||||
else FLastError:=0;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
|
||||
@ -191,6 +203,7 @@ begin
|
||||
SockCheck(winsock.bind(FSocket,sin,sizeof(sin)));
|
||||
len:=sizeof(FLocalSin);
|
||||
Winsock.GetSockName(FSocket,FLocalSin,Len);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.Connect}
|
||||
@ -201,6 +214,7 @@ begin
|
||||
SetSin(sin,ip,port);
|
||||
SockCheck(winsock.connect(FSocket,sin,sizeof(sin)));
|
||||
GetSins;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.GetSins}
|
||||
@ -215,21 +229,25 @@ begin
|
||||
end;
|
||||
|
||||
{TBlockSocket.SendBuffer}
|
||||
procedure TBlockSocket.SendBuffer(buffer:pointer;length:integer);
|
||||
function TBlockSocket.SendBuffer(buffer:pointer;length:integer):integer;
|
||||
begin
|
||||
sockcheck(winsock.send(FSocket,buffer^,length,0));
|
||||
result:=winsock.send(FSocket,buffer^,length,0);
|
||||
sockcheck(result);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.SendByte}
|
||||
procedure TBlockSocket.SendByte(data:byte);
|
||||
begin
|
||||
sockcheck(winsock.send(FSocket,data,1,0));
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.SendString}
|
||||
procedure TBlockSocket.SendString(data:string);
|
||||
begin
|
||||
sockcheck(winsock.send(FSocket,pchar(data)^,length(data),0));
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.RecvBuffer}
|
||||
@ -239,6 +257,7 @@ begin
|
||||
if result=0
|
||||
then FLastError:=WSAENOTCONN
|
||||
else sockcheck(result);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.RecvByte}
|
||||
@ -257,6 +276,7 @@ begin
|
||||
result:=data;
|
||||
end
|
||||
else FLastError:=WSAETIMEDOUT;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.Recvstring}
|
||||
@ -313,6 +333,7 @@ begin
|
||||
result:=s;
|
||||
end
|
||||
else result:='';
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.PeekBuffer}
|
||||
@ -320,6 +341,7 @@ function TBlockSocket.PeekBuffer(buffer:pointer;length:integer):integer;
|
||||
begin
|
||||
result:=winsock.recv(FSocket,buffer^,length,MSG_PEEK);
|
||||
sockcheck(result);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.PeekByte}
|
||||
@ -338,6 +360,7 @@ begin
|
||||
result:=data;
|
||||
end
|
||||
else FLastError:=WSAETIMEDOUT;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.SockCheck}
|
||||
@ -348,6 +371,22 @@ begin
|
||||
FLastError:=result;
|
||||
end;
|
||||
|
||||
{TBlockSocket.ExceptCheck}
|
||||
procedure TBlockSocket.ExceptCheck;
|
||||
var
|
||||
e:ESynapseError;
|
||||
s:string;
|
||||
begin
|
||||
if FRaiseExcept and (LastError<>0) then
|
||||
begin
|
||||
s:=GetErrorDesc(LastError);
|
||||
e:=ESynapseError.CreateFmt('TCP/IP socket error %d: %s',[LastError,s]);
|
||||
e.ErrorCode:=LastError;
|
||||
e.ErrorMessage:=s;
|
||||
raise e;
|
||||
end;
|
||||
end;
|
||||
|
||||
{TBlockSocket.WaitingData}
|
||||
function TBlockSocket.WaitingData:integer;
|
||||
var
|
||||
@ -363,8 +402,9 @@ var
|
||||
li:TLinger;
|
||||
begin
|
||||
li.l_onoff := ord(enable);
|
||||
li.l_linger := Linger;
|
||||
li.l_linger := Linger div 1000;
|
||||
SockCheck(winsock.SetSockOpt(FSocket, SOL_SOCKET, SO_LINGER, @li, SizeOf(li)));
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.LocalName}
|
||||
@ -418,8 +458,8 @@ var
|
||||
TimeV:tTimeval;
|
||||
x:integer;
|
||||
begin
|
||||
Timev.tv_usec:=0;
|
||||
Timev.tv_sec:=Timeout;
|
||||
Timev.tv_usec:=(Timeout mod 1000)*1000;
|
||||
Timev.tv_sec:=Timeout div 1000;
|
||||
TimeVal:=@TimeV;
|
||||
if timeout = -1 then Timeval:=nil;
|
||||
Winsock.FD_Zero(FDSet);
|
||||
@ -428,6 +468,7 @@ begin
|
||||
SockCheck(x);
|
||||
If FLastError<>0 then x:=0;
|
||||
result:=x>0;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.CanWrite}
|
||||
@ -438,8 +479,8 @@ var
|
||||
TimeV:tTimeval;
|
||||
x:integer;
|
||||
begin
|
||||
Timev.tv_usec:=0;
|
||||
Timev.tv_sec:=Timeout;
|
||||
Timev.tv_usec:=(Timeout mod 1000)*1000;
|
||||
Timev.tv_sec:=Timeout div 1000;
|
||||
TimeVal:=@TimeV;
|
||||
if timeout = -1 then Timeval:=nil;
|
||||
Winsock.FD_Zero(FDSet);
|
||||
@ -448,15 +489,18 @@ begin
|
||||
SockCheck(x);
|
||||
If FLastError<>0 then x:=0;
|
||||
result:=x>0;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.SendBufferTo}
|
||||
procedure TBlockSocket.SendBufferTo(buffer:pointer;length:integer);
|
||||
function TBlockSocket.SendBufferTo(buffer:pointer;length:integer):integer;
|
||||
var
|
||||
len:integer;
|
||||
begin
|
||||
len:=sizeof(FRemoteSin);
|
||||
sockcheck(winsock.sendto(FSocket,buffer^,length,0,FRemoteSin,len));
|
||||
result:=winsock.sendto(FSocket,buffer^,length,0,FRemoteSin,len);
|
||||
sockcheck(result);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TBlockSocket.RecvBufferFrom}
|
||||
@ -467,6 +511,7 @@ begin
|
||||
len:=sizeof(FRemoteSin);
|
||||
result:=winsock.recvfrom(FSocket,buffer^,length,0,FRemoteSin,len);
|
||||
sockcheck(result);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
|
||||
@ -491,6 +536,7 @@ begin
|
||||
Res:=winsock.SetSockOpt(FSocket, SOL_SOCKET, SO_BROADCAST, @opt, SizeOf(opt));
|
||||
SockCheck(Res);
|
||||
Result:=res=0;
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
|
||||
@ -508,6 +554,7 @@ end;
|
||||
procedure TTCPBlockSocket.Listen;
|
||||
begin
|
||||
SockCheck(winsock.listen(FSocket,SOMAXCONN));
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
{TTCPBlockSocket.Accept}
|
||||
@ -522,6 +569,7 @@ begin
|
||||
result:=winsock.accept(FSocket,@FRemoteSin,@len);
|
||||
{$ENDIF}
|
||||
SockCheck(result);
|
||||
ExceptCheck;
|
||||
end;
|
||||
|
||||
|
||||
@ -587,5 +635,9 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
exit;
|
||||
asm
|
||||
db 'Synapse TCP/IP library by Lukas Gebauer',0
|
||||
end;
|
||||
end.
|
||||
|
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.000.000 |
|
||||
| Project : Delphree - Synapse | 001.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: DNS client |
|
||||
|==============================================================================|
|
||||
@ -102,7 +102,7 @@ begin
|
||||
inherited Create;
|
||||
sock:=TUDPBlockSocket.create;
|
||||
sock.CreateSocket;
|
||||
timeout:=5;
|
||||
timeout:=5000;
|
||||
DNShost:='localhost';
|
||||
end;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.000.000 |
|
||||
| Project : Delphree - Synapse | 001.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: HTTP client |
|
||||
|==============================================================================|
|
||||
@ -55,7 +55,7 @@ begin
|
||||
inherited Create;
|
||||
sock:=TTCPBlockSocket.create;
|
||||
sock.CreateSocket;
|
||||
timeout:=300;
|
||||
timeout:=300000;
|
||||
HTTPhost:='localhost';
|
||||
HTTPPort:=80;
|
||||
end;
|
||||
|
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.000.000 |
|
||||
| Project : Delphree - Synapse | 001.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: PING sender |
|
||||
|==============================================================================|
|
||||
@ -94,7 +94,7 @@ begin
|
||||
inherited Create;
|
||||
sock:=TICMPBlockSocket.create;
|
||||
sock.CreateSocket;
|
||||
timeout:=5;
|
||||
timeout:=5000;
|
||||
packetsize:=32;
|
||||
seq:=0;
|
||||
end;
|
||||
|
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.001.001 |
|
||||
| Project : Delphree - Synapse | 001.002.000 |
|
||||
|==============================================================================|
|
||||
| Content: SMTP client |
|
||||
|==============================================================================|
|
||||
@ -63,7 +63,7 @@ begin
|
||||
inherited Create;
|
||||
sock:=TTCPBlockSocket.create;
|
||||
sock.CreateSocket;
|
||||
timeout:=300;
|
||||
timeout:=300000;
|
||||
SMTPhost:='localhost';
|
||||
end;
|
||||
|
||||
@ -187,6 +187,7 @@ begin
|
||||
try
|
||||
t.assign(Maildata);
|
||||
t.Insert(0,'');
|
||||
t.Insert(0,'x-mailer: Synapse - Delphi TCP/IP library by Lukas Gebauer');
|
||||
t.Insert(0,'subject: '+subject);
|
||||
t.Insert(0,'date: '+Rfc822DateTime(now));
|
||||
t.Insert(0,'to: '+mailto);
|
||||
|
105
snmpsend.pas
105
snmpsend.pas
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 002.000.000 |
|
||||
| Project : Delphree - Synapse | 002.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: SNMP client |
|
||||
|==============================================================================|
|
||||
@ -50,16 +50,6 @@ EGenErr=5;
|
||||
|
||||
type
|
||||
|
||||
TSNMPMibValueType = (smvtInteger,
|
||||
smvtOctetString,
|
||||
smvtNull,
|
||||
smvtObjectId,
|
||||
smvtSequence,
|
||||
smvtIpAddress,
|
||||
smvtCounter,
|
||||
smvtGauge,
|
||||
smvtTimeTicks);
|
||||
|
||||
TSNMPMib = class
|
||||
OID: string;
|
||||
Value: string;
|
||||
@ -80,10 +70,9 @@ TSNMPRec=class(TObject)
|
||||
procedure DecodeBuf(Buffer:string);
|
||||
function EncodeBuf:string;
|
||||
procedure Clear;
|
||||
procedure MIBAdd(MIB,Value:string; ValueType:TSNMPMibValueType);
|
||||
procedure MIBAdd(MIB,Value:string; ValueType:integer);
|
||||
procedure MIBdelete(Index:integer);
|
||||
function MIBGet(MIB:string):string;
|
||||
function ConvertValueType(ValueType: TSNMPMibValueType): integer;
|
||||
end;
|
||||
|
||||
TSNMPSend=class(TObject)
|
||||
@ -101,7 +90,7 @@ TSNMPSend=class(TObject)
|
||||
end;
|
||||
|
||||
function SNMPget (Oid, Community, SNMPHost:string; var Value:string):Boolean;
|
||||
function SNMPSet (Oid, Community, SNMPHost, Value: string; ValueType: TSNMPMibValueType): boolean;
|
||||
function SNMPSet (Oid, Community, SNMPHost, Value: string; ValueType: integer): boolean;
|
||||
|
||||
implementation
|
||||
|
||||
@ -127,23 +116,22 @@ var
|
||||
Pos:integer;
|
||||
endpos:integer;
|
||||
sm,sv:string;
|
||||
svt: TSNMPMibValueType;
|
||||
svt: integer;
|
||||
begin
|
||||
Pos:=2;
|
||||
Endpos:=ASNDecLen(Pos,buffer);
|
||||
Self.version:=StrToIntDef(ASNItem(Pos,buffer),0);
|
||||
Self.community:=ASNItem(Pos,buffer);
|
||||
Self.PDUType:=StrToIntDef(ASNItem(Pos,buffer),0);
|
||||
Self.ID:=StrToIntDef(ASNItem(Pos,buffer),0);
|
||||
Self.ErrorStatus:=StrToIntDef(ASNItem(Pos,buffer),0);
|
||||
Self.ErrorIndex:=StrToIntDef(ASNItem(Pos,buffer),0);
|
||||
ASNItem(Pos,buffer);
|
||||
Self.version:=StrToIntDef(ASNItem(Pos,buffer,svt),0);
|
||||
Self.community:=ASNItem(Pos,buffer,svt);
|
||||
Self.PDUType:=StrToIntDef(ASNItem(Pos,buffer,svt),0);
|
||||
Self.ID:=StrToIntDef(ASNItem(Pos,buffer,svt),0);
|
||||
Self.ErrorStatus:=StrToIntDef(ASNItem(Pos,buffer,svt),0);
|
||||
Self.ErrorIndex:=StrToIntDef(ASNItem(Pos,buffer,svt),0);
|
||||
ASNItem(Pos,buffer,svt);
|
||||
while Pos<Endpos do
|
||||
begin
|
||||
ASNItem(Pos,buffer);
|
||||
Sm:=ASNItem(Pos,buffer);
|
||||
Sv:=ASNItem(Pos,buffer);
|
||||
Svt:=smvtNull;
|
||||
ASNItem(Pos,buffer,svt);
|
||||
Sm:=ASNItem(Pos,buffer,svt);
|
||||
Sv:=ASNItem(Pos,buffer,svt);
|
||||
Self.MIBadd(sm,sv, svt);
|
||||
end;
|
||||
end;
|
||||
@ -151,7 +139,7 @@ end;
|
||||
{TSNMPRec.EncodeBuf}
|
||||
function TSNMPRec.EncodeBuf:string;
|
||||
var
|
||||
data,s,t:string;
|
||||
data,s:string;
|
||||
SNMPMib: TSNMPMib;
|
||||
n:integer;
|
||||
begin
|
||||
@ -162,24 +150,35 @@ begin
|
||||
case (SNMPMib.ValueType) of
|
||||
ASN1_INT, ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
|
||||
begin
|
||||
t := chr(strToInt('$'+copy(inttohex(strToInt(SNMPMib.Value),4),1,2)));
|
||||
t := t+chr(strToInt('$'+copy(inttohex(strToInt(SNMPMib.Value),4),3,2)));
|
||||
s := ASNObject(MibToID(SNMPMib.OID),6) + ASNObject(t,SNMPMib.ValueType);
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID)
|
||||
+ASNObject(ASNEncInt(strToIntDef(SNMPMib.Value,0)),SNMPMib.ValueType);
|
||||
end;
|
||||
else
|
||||
s := ASNObject(MibToID(SNMPMib.OID),6) + ASNObject(SNMPMib.Value,SNMPMib.ValueType);
|
||||
ASN1_OBJID:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject(MibToID(SNMPMib.Value),SNMPMib.ValueType);
|
||||
end;
|
||||
ASN1_IPADDR:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject(IPToID(SNMPMib.Value),SNMPMib.ValueType);
|
||||
end;
|
||||
ASN1_NULL:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject('',ASN1_NULL);
|
||||
end;
|
||||
else
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject(SNMPMib.Value,SNMPMib.ValueType);
|
||||
end;
|
||||
data := data + ASNObject(s, $30);
|
||||
data := data + ASNObject(s, ASN1_SEQ);
|
||||
end;
|
||||
data:=ASNObject(data,$30);
|
||||
data:=ASNObject(char(Self.ID),2)
|
||||
+ASNObject(char(Self.ErrorStatus),2)
|
||||
+ASNObject(char(Self.ErrorIndex),2)
|
||||
data:=ASNObject(data,ASN1_SEQ);
|
||||
data:=ASNObject(char(Self.ID),ASN1_INT)
|
||||
+ASNObject(char(Self.ErrorStatus),ASN1_INT)
|
||||
+ASNObject(char(Self.ErrorIndex),ASN1_INT)
|
||||
+data;
|
||||
data:=ASNObject(char(Self.Version),2)
|
||||
+ASNObject(Self.community,4)
|
||||
data:=ASNObject(char(Self.Version),ASN1_INT)
|
||||
+ASNObject(Self.community,ASN1_OCTSTR)
|
||||
+ASNObject(data,Self.PDUType);
|
||||
data:=ASNObject(data,$30);
|
||||
data:=ASNObject(data,ASN1_SEQ);
|
||||
Result:=data;
|
||||
end;
|
||||
|
||||
@ -200,14 +199,14 @@ begin
|
||||
end;
|
||||
|
||||
{TSNMPRec.MIBAdd}
|
||||
procedure TSNMPRec.MIBAdd(MIB,Value:string; ValueType:TSNMPMibValueType);
|
||||
procedure TSNMPRec.MIBAdd(MIB,Value:string; ValueType:integer);
|
||||
var
|
||||
SNMPMib: TSNMPMib;
|
||||
begin
|
||||
SNMPMib := TSNMPMib.Create;
|
||||
SNMPMib.OID := MIB;
|
||||
SNMPMib.Value := Value;
|
||||
SNMPMib.ValueType := ConvertValueType(ValueType);
|
||||
SNMPMib.ValueType := ValueType;
|
||||
SNMPMibList.Add(SNMPMib);
|
||||
end;
|
||||
|
||||
@ -237,21 +236,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{TSNMPRec.GetValueType}
|
||||
function TSNMPRec.ConvertValueType(ValueType: TSNMPMibValueType): integer;
|
||||
begin
|
||||
result := ASN1_NULL;
|
||||
if (ValueType = smvtInteger) then result := ASN1_INT;
|
||||
if (ValueType = smvtOctetString) then result := ASN1_OCTSTR;
|
||||
if (ValueType = smvtNull) then result := ASN1_NULL;
|
||||
if (ValueType = smvtObjectId) then result := ASN1_OBJID;
|
||||
if (ValueType = smvtSequence) then result := ASN1_SEQ;
|
||||
if (ValueType = smvtIpAddress) then result := ASN1_IPADDR;
|
||||
if (ValueType = smvtCounter) then result := ASN1_COUNTER;
|
||||
if (ValueType = smvtGauge) then result := ASN1_GAUGE;
|
||||
if (ValueType = smvtTimeTicks) then result := ASN1_TIMETICKS;
|
||||
end;
|
||||
|
||||
|
||||
{==============================================================================}
|
||||
|
||||
@ -265,7 +249,7 @@ begin
|
||||
Reply.Clear;
|
||||
sock:=TUDPBlockSocket.create;
|
||||
sock.createsocket;
|
||||
timeout:=5;
|
||||
timeout:=5000;
|
||||
host:='localhost';
|
||||
end;
|
||||
|
||||
@ -308,12 +292,11 @@ function SNMPget (Oid, Community, SNMPHost:string; var Value:string):Boolean;
|
||||
var
|
||||
SNMP:TSNMPSend;
|
||||
begin
|
||||
Result:=False;
|
||||
SNMP:=TSNMPSend.Create;
|
||||
try
|
||||
Snmp.Query.community:=Community;
|
||||
Snmp.Query.PDUType:=PDUGetRequest;
|
||||
Snmp.Query.MIBAdd(Oid,'',smvtNull);
|
||||
Snmp.Query.MIBAdd(Oid,'',ASN1_NULL);
|
||||
Snmp.host:=SNMPHost;
|
||||
Result:=Snmp.DoIt;
|
||||
if Result then
|
||||
@ -323,7 +306,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function SNMPSet(Oid, Community, SNMPHost, Value: string; ValueType: TSNMPMibValueType): boolean;
|
||||
function SNMPSet(Oid, Community, SNMPHost, Value: string; ValueType: integer): boolean;
|
||||
var
|
||||
SNMPSend: TSNMPSend;
|
||||
begin
|
||||
|
127
snmptrap.pas
127
snmptrap.pas
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.002.001 |
|
||||
| Project : Delphree - Synapse | 002.000.000 |
|
||||
|==============================================================================|
|
||||
| Content: SNMP traps |
|
||||
|==============================================================================|
|
||||
@ -29,7 +29,7 @@ unit SNMPTrap;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, BlckSock, SynaUtil, ASN1Util;
|
||||
Classes, SysUtils, BlckSock, SynaUtil, ASN1Util, SNMPsend;
|
||||
|
||||
const
|
||||
TRAP_PORT = 162;
|
||||
@ -57,12 +57,11 @@ type
|
||||
GenTrap: integer;
|
||||
SpecTrap: integer;
|
||||
TimeTicks: integer;
|
||||
MIBOID: TStringList;
|
||||
MIBValue: TStringList;
|
||||
SNMPMibList: TList;
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Clear;
|
||||
procedure MIBAdd(MIB, Value: string);
|
||||
procedure MIBAdd(MIB, Value: string; ValueType:integer);
|
||||
procedure MIBDelete(Index: integer);
|
||||
function MIBGet(MIB: string): string;
|
||||
function EncodeTrap: integer;
|
||||
@ -83,7 +82,7 @@ type
|
||||
end;
|
||||
|
||||
function SendTrap(Dest, Source, Enterprise, Community: string;
|
||||
Generic, Specific, Seconds: integer; MIBName, MIBValue: TStringList): integer;
|
||||
Generic, Specific, Seconds: integer; MIBName, MIBValue: string; MIBtype:integer): integer;
|
||||
function RecvTrap(var Dest, Source, Enterprise, Community: string;
|
||||
var Generic, Specific, Seconds: integer; var MIBName, MIBValue: TStringList): integer;
|
||||
|
||||
@ -92,8 +91,7 @@ implementation
|
||||
constructor TTrapPDU.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
MIBOID := TStringList.Create;
|
||||
MIBValue := TStringList.Create;
|
||||
SNMPMibList := TList.create;
|
||||
TrapPort := TRAP_PORT;
|
||||
Version := SNMP_VERSION;
|
||||
PDUType := PDU_TRAP;
|
||||
@ -102,54 +100,89 @@ end;
|
||||
|
||||
destructor TTrapPDU.Destroy;
|
||||
begin
|
||||
MIBValue.Free;
|
||||
MIBOID.Free;
|
||||
SNMPMibList.free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TTrapPDU.Clear;
|
||||
var
|
||||
i:integer;
|
||||
begin
|
||||
MIBOID.Clear;
|
||||
MIBValue.Clear;
|
||||
for i := 0 to SNMPMibList.count - 1 do
|
||||
TSNMPMib(SNMPMibList[i]).Free;
|
||||
SNMPMibList.Clear;
|
||||
TrapPort := TRAP_PORT;
|
||||
Version := SNMP_VERSION;
|
||||
PDUType := PDU_TRAP;
|
||||
Community := 'public';
|
||||
end;
|
||||
|
||||
procedure TTrapPDU.MIBAdd(MIB, Value: string);
|
||||
procedure TTrapPDU.MIBAdd(MIB, Value: string; ValueType:integer);
|
||||
var
|
||||
SNMPMib: TSNMPMib;
|
||||
begin
|
||||
MIBOID.Add(MIB);
|
||||
MIBValue.Add(Value);
|
||||
SNMPMib := TSNMPMib.Create;
|
||||
SNMPMib.OID := MIB;
|
||||
SNMPMib.Value := Value;
|
||||
SNMPMib.ValueType := ValueType;
|
||||
SNMPMibList.Add(SNMPMib);
|
||||
end;
|
||||
|
||||
procedure TTrapPDU.MIBDelete(Index: integer);
|
||||
begin
|
||||
MIBOID.Delete(Index);
|
||||
MIBValue.Delete(Index);
|
||||
if (Index >= 0) and (Index < SNMPMibList.count) then
|
||||
begin
|
||||
TSNMPMib(SNMPMibList[Index]).Free;
|
||||
SNMPMibList.Delete(Index);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TTrapPDU.MIBGet(MIB: string): string;
|
||||
var
|
||||
x: integer;
|
||||
i: integer;
|
||||
begin
|
||||
x := MIBOID.IndexOf(MIB);
|
||||
if (x < 0) then
|
||||
Result := ''
|
||||
else
|
||||
Result := MIBValue[x];
|
||||
Result := '';
|
||||
for i := 0 to SNMPMibList.count - 1 do
|
||||
begin
|
||||
if ((TSNMPMib(SNMPMibList[i])).OID = MIB) then
|
||||
begin
|
||||
Result := (TSNMPMib(SNMPMibList[i])).Value;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TTrapPDU.EncodeTrap: integer;
|
||||
var
|
||||
s: string;
|
||||
n: integer;
|
||||
SNMPMib: TSNMPMib;
|
||||
begin
|
||||
Buffer := '';
|
||||
for n:=0 to MIBOID.Count-1 do
|
||||
for n:=0 to SNMPMibList.Count-1 do
|
||||
begin
|
||||
s := ASNObject(MibToID(MIBOID[n]), ASN1_OBJID)
|
||||
+ ASNObject(MIBValue[n], ASN1_OCTSTR);
|
||||
SNMPMib := SNMPMibList[n];
|
||||
case (SNMPMib.ValueType) of
|
||||
ASN1_INT, ASN1_COUNTER, ASN1_GAUGE, ASN1_TIMETICKS:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID)
|
||||
+ASNObject(ASNEncInt(strToIntDef(SNMPMib.Value,0)),SNMPMib.ValueType);
|
||||
end;
|
||||
ASN1_OBJID:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject(MibToID(SNMPMib.Value),SNMPMib.ValueType);
|
||||
end;
|
||||
ASN1_IPADDR:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject(IPToID(SNMPMib.Value),SNMPMib.ValueType);
|
||||
end;
|
||||
ASN1_NULL:
|
||||
begin
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject('',ASN1_NULL);
|
||||
end;
|
||||
else
|
||||
s := ASNObject(MibToID(SNMPMib.OID),ASN1_OBJID) + ASNObject(SNMPMib.Value,SNMPMib.ValueType);
|
||||
end;
|
||||
Buffer := Buffer + ASNObject(s, ASN1_SEQ);
|
||||
end;
|
||||
Buffer := ASNObject(Buffer, ASN1_SEQ);
|
||||
@ -171,24 +204,26 @@ function TTrapPDU.DecodeTrap: integer;
|
||||
var
|
||||
Pos, EndPos: integer;
|
||||
Sm, Sv: string;
|
||||
Svt:integer;
|
||||
begin
|
||||
clear;
|
||||
Pos := 2;
|
||||
EndPos := ASNDecLen(Pos, Buffer);
|
||||
Version := StrToIntDef(ASNItem(Pos, Buffer), 0);
|
||||
Community := ASNItem(Pos, Buffer);
|
||||
PDUType := StrToIntDef(ASNItem(Pos, Buffer), PDU_TRAP);
|
||||
Enterprise := IdToMIB(ASNItem(Pos, Buffer));
|
||||
TrapHost := ASNItem(Pos, Buffer);
|
||||
GenTrap := StrToIntDef(ASNItem(Pos, Buffer), 0);
|
||||
Spectrap := StrToIntDef(ASNItem(Pos, Buffer), 0);
|
||||
TimeTicks := StrToIntDef(ASNItem(Pos, Buffer), 0);
|
||||
ASNItem(Pos, Buffer);
|
||||
Version := StrToIntDef(ASNItem(Pos, Buffer,svt), 0);
|
||||
Community := ASNItem(Pos, Buffer,svt);
|
||||
PDUType := StrToIntDef(ASNItem(Pos, Buffer,svt), PDU_TRAP);
|
||||
Enterprise := IdToMIB(ASNItem(Pos, Buffer,svt));
|
||||
TrapHost := ASNItem(Pos, Buffer,svt);
|
||||
GenTrap := StrToIntDef(ASNItem(Pos, Buffer,svt), 0);
|
||||
Spectrap := StrToIntDef(ASNItem(Pos, Buffer,svt), 0);
|
||||
TimeTicks := StrToIntDef(ASNItem(Pos, Buffer,svt), 0);
|
||||
ASNItem(Pos, Buffer,svt);
|
||||
while (Pos < EndPos) do
|
||||
begin
|
||||
ASNItem(Pos, Buffer);
|
||||
Sm := ASNItem(Pos, Buffer);
|
||||
Sv := ASNItem(Pos, Buffer);
|
||||
MIBAdd(Sm, Sv);
|
||||
ASNItem(Pos, Buffer,svt);
|
||||
Sm := ASNItem(Pos, Buffer,svt);
|
||||
Sv := ASNItem(Pos, Buffer,svt);
|
||||
MIBAdd(Sm, Sv, svt);
|
||||
end;
|
||||
Result := 1;
|
||||
end;
|
||||
@ -198,7 +233,7 @@ begin
|
||||
inherited Create;
|
||||
Sock := TUDPBlockSocket.Create;
|
||||
Trap := TTrapPDU.Create;
|
||||
Timeout := 5;
|
||||
Timeout := 5000;
|
||||
SNMPHost := '127.0.0.1';
|
||||
Sock.CreateSocket;
|
||||
end;
|
||||
@ -238,10 +273,9 @@ begin
|
||||
end;
|
||||
|
||||
function SendTrap(Dest, Source, Enterprise, Community: string;
|
||||
Generic, Specific, Seconds: integer; MIBName, MIBValue: TStringList): integer;
|
||||
Generic, Specific, Seconds: integer; MIBName, MIBValue: string; MIBtype:integer): integer;
|
||||
var
|
||||
SNMP: TTrapSNMP;
|
||||
i: integer;
|
||||
begin
|
||||
SNMP := TTrapSNMP.Create;
|
||||
try
|
||||
@ -252,8 +286,7 @@ begin
|
||||
SNMP.Trap.GenTrap := Generic;
|
||||
SNMP.Trap.SpecTrap := Specific;
|
||||
SNMP.Trap.TimeTicks := Seconds;
|
||||
for i:=0 to (MIBName.Count - 1) do
|
||||
SNMP.Trap.MIBAdd(MIBName[i], MIBValue[i]);
|
||||
SNMP.Trap.MIBAdd(MIBName,MIBValue,MIBType);
|
||||
Result := SNMP.Send;
|
||||
finally
|
||||
SNMP.Free;
|
||||
@ -282,10 +315,10 @@ begin
|
||||
Seconds := SNMP.Trap.TimeTicks;
|
||||
MIBName.Clear;
|
||||
MIBValue.Clear;
|
||||
for i:=0 to (SNMP.Trap.MIBOID.Count - 1) do
|
||||
for i:=0 to (SNMP.Trap.SNMPMibList.count - 1) do
|
||||
begin
|
||||
MIBName.Add(SNMP.Trap.MIBOID[i]);
|
||||
MIBValue.Add(SNMP.Trap.MIBValue[i]);
|
||||
MIBName.Add(TSNMPMib(SNMP.Trap.SNMPMibList[i]).OID);
|
||||
MIBValue.Add(TSNMPMib(SNMP.Trap.SNMPMibList[i]).Value);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
|
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.000.000 |
|
||||
| Project : Delphree - Synapse | 001.001.000 |
|
||||
|==============================================================================|
|
||||
| Content: SNTP client |
|
||||
|==============================================================================|
|
||||
@ -73,7 +73,7 @@ begin
|
||||
inherited Create;
|
||||
sock:=TUDPBlockSocket.create;
|
||||
sock.CreateSocket;
|
||||
timeout:=5;
|
||||
timeout:=5000;
|
||||
sntphost:='localhost';
|
||||
end;
|
||||
|
||||
|
24
synautil.pas
24
synautil.pas
@ -1,5 +1,5 @@
|
||||
{==============================================================================|
|
||||
| Project : Delphree - Synapse | 001.002.000 |
|
||||
| Project : Delphree - Synapse | 001.002.001 |
|
||||
|==============================================================================|
|
||||
| Content: support procedures and functions |
|
||||
|==============================================================================|
|
||||
@ -46,6 +46,9 @@ function IPToID(Host: string): string;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
ASN1util;
|
||||
|
||||
{==============================================================================}
|
||||
{timezone}
|
||||
function timezone:string;
|
||||
@ -54,8 +57,12 @@ var
|
||||
bias:integer;
|
||||
h,m:integer;
|
||||
begin
|
||||
GetTimeZoneInformation(Zoneinfo);
|
||||
bias:=zoneinfo.bias;
|
||||
case GetTimeZoneInformation(Zoneinfo) of
|
||||
2: bias:=zoneinfo.bias+zoneinfo.DaylightBias;
|
||||
1: bias:=zoneinfo.bias+zoneinfo.StandardBias;
|
||||
else
|
||||
bias:=zoneinfo.bias;
|
||||
end;
|
||||
if bias<=0 then result:='+'
|
||||
else result:='-';
|
||||
bias:=abs(bias);
|
||||
@ -215,11 +222,11 @@ begin
|
||||
result:='';
|
||||
x:=walkint(mib);
|
||||
x:=x*40+walkint(mib);
|
||||
result:=char(x);
|
||||
result:=ASNEncOIDItem(x);
|
||||
while mib<>'' do
|
||||
begin
|
||||
x:=walkint(mib);
|
||||
result:=result+char(x);
|
||||
result:=result+ASNEncOIDItem(x);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -231,10 +238,11 @@ var
|
||||
x,y,n:integer;
|
||||
begin
|
||||
result:='';
|
||||
For n:=1 to length(id) do
|
||||
n:=1;
|
||||
while length(id)+1>n do
|
||||
begin
|
||||
x:=ord(id[n]);
|
||||
if n=1 then
|
||||
x:=ASNDecOIDItem(n,id);
|
||||
if (n-1)=1 then
|
||||
begin
|
||||
y:=x div 40;
|
||||
x:=x mod 40;
|
||||
|
Loading…
x
Reference in New Issue
Block a user