restemplate/indy/Protocols/IdIdent.pas

224 lines
5.5 KiB
Plaintext

{
$Project$
$Workfile$
$Revision$
$DateUTC$
$Id$
This file is part of the Indy (Internet Direct) project, and is offered
under the dual-licensing agreement described on the Indy website.
(http://www.indyproject.org/)
Copyright:
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
$Log$
}
{
Rev 1.6 2004.02.03 5:43:46 PM czhower
Name changes
Rev 1.5 1/21/2004 3:10:36 PM JPMugaas
InitComponent
Rev 1.4 3/27/2003 3:42:00 PM BGooijen
Changed because some properties are moved to IOHandler
Rev 1.3 2/24/2003 09:00:34 PM JPMugaas
Rev 1.2 12/8/2002 07:25:18 PM JPMugaas
Added published host and port properties.
Rev 1.1 12/6/2002 05:30:00 PM JPMugaas
Now decend from TIdTCPClientCustom instead of TIdTCPClient.
Rev 1.0 11/13/2002 07:54:40 AM JPMugaas
2001 - Feb 12 - J. Peter Mugaas
started this client
}
unit IdIdent;
{
This is the Ident client which is based on RFC 1413.
}
interface
{$i IdCompilerDefines.inc}
uses
IdAssignedNumbers, IdException, IdTCPClient;
const
IdIdentQryTimeout = 60000;
type
TIdIdent = class(TIdTCPClientCustom)
protected
FQueryTimeOut : Integer;
FReplyString : String;
function GetReplyCharset: String;
function GetReplyOS: String;
function GetReplyOther: String;
function GetReplyUserName: String;
function FetchUserReply : String;
function FetchOS : String;
procedure ParseError;
procedure InitComponent; override;
public
procedure Query(APortOnServer, APortOnClient : Word);
property Reply : String read FReplyString;
property ReplyCharset : String read GetReplyCharset;
property ReplyOS : String read GetReplyOS;
property ReplyOther : String read GetReplyOther;
property ReplyUserName : String read GetReplyUserName;
published
property QueryTimeOut : Integer read FQueryTimeOut write FQueryTimeOut default IdIdentQryTimeout;
property Port default IdPORT_AUTH;
property Host;
end;
EIdIdentException = class(EIdException);
EIdIdentReply = class(EIdIdentException);
EIdIdentInvalidPort = class(EIdIdentReply);
EIdIdentNoUser = class(EIdIdentReply);
EIdIdentHiddenUser = class(EIdIdentReply);
EIdIdentUnknownError = class(EIdIdentReply);
EIdIdentQueryTimeOut = class(EIdIdentReply);
implementation
uses
IdGlobal,
IdGlobalProtocols,
IdResourceStringsProtocols,
SysUtils;
const
IdentErrorText : Array[0..3] of string = (
'INVALID-PORT', 'NO-USER', 'HIDDEN-USER', 'UNKNOWN-ERROR' {Do not Localize}
);
{ TIdIdent }
procedure TIdIdent.InitComponent;
begin
inherited InitComponent;
FQueryTimeOut := IdIdentQryTimeout;
Port := IdPORT_AUTH;
end;
function TIdIdent.FetchOS: String;
var
Buf : String;
begin
Buf := FetchUserReply;
Result := Trim(Fetch(Buf,':')); {Do not Localize}
end;
function TIdIdent.FetchUserReply: String;
var
Buf : String;
begin
Result := ''; {Do not Localize}
Buf := FReplyString;
Fetch(Buf,':'); {Do not Localize}
if TextIsSame(Trim(Fetch(Buf,':')), 'USERID') then begin {Do not Localize}
Result := TrimLeft(Buf);
end;
end;
function TIdIdent.GetReplyCharset: String;
var
Buf : String;
begin
Buf := FetchOS;
if (Length(Buf) > 0) and (Pos(',', Buf) > 0) then begin {Do not Localize}
Result := Trim(Fetch(Buf,',')); {Do not Localize}
end else begin
Result := 'US-ASCII'; {Do not Localize}
end;
end;
function TIdIdent.GetReplyOS: String;
var
Buf : String;
begin
Buf := FetchOS;
if Length(Buf) > 0 then begin
Result := Trim(Fetch(Buf,',')); {Do not Localize}
end else begin
Result := ''; {Do not Localize}
end;
end;
function TIdIdent.GetReplyOther: String;
var
Buf : String;
begin
if FetchOS = 'OTHER' then begin {Do not Localize}
Buf := FetchUserReply;
Fetch(Buf,':'); {Do not Localize}
Result := TrimLeft(Buf);
end;
end;
function TIdIdent.GetReplyUserName: String;
var
Buf : String;
begin
if FetchOS <> 'OTHER' then begin {Do not Localize}
Buf := FetchUserReply;
{OS ID}
Fetch(Buf, ':'); {Do not Localize}
Result := TrimLeft(Buf);
end;
end;
procedure TIdIdent.ParseError;
var
Buf : String;
begin
Buf := FReplyString;
Fetch(Buf, ':'); {Do not Localize}
if Trim(Fetch(Buf, ':')) = 'ERROR' then begin {Do not Localize}
case PosInStrArray(Trim(Buf), IdentErrorText, False) of
{Invalid Port}
0 : Raise EIdIdentInvalidPort.Create(RSIdentInvalidPort);
{No user}
1 : Raise EIdIdentNoUser.Create(RSIdentNoUser);
{Hidden User}
2 : Raise EIdIdentHiddenUser.Create(RSIdentHiddenUser)
else
{Unknown or other error}
raise EIdIdentUnknownError.Create(RSIdentUnknownError);
end;
end;
end;
procedure TIdIdent.Query(APortOnServer, APortOnClient: Word);
var
RTO : Boolean;
begin
FReplyString := ''; {Do not Localize}
Connect;
try
WriteLn(IntToStr(APortOnServer) + ', ' + IntToStr(APortOnClient)); {Do not Localize}
FReplyString := IOHandler.ReadLn('', FQueryTimeOut); {Do not Localize}
{We check here and not return an exception at the moment so we can close our
connection before raising our exception if the read timed out}
RTO := IOHandler.ReadLnTimedOut;
finally
Disconnect;
end;
if RTO then begin
raise EIdIdentQueryTimeOut.Create(RSIdentReplyTimeout);
end;
ParseError;
end;
end.