{
- Copyright (C) 2010-2014 MegaBrutal
+ Copyright (C) 2010-2018 MegaBrutal
This unit is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
TArgumentParser = class
- constructor Create(RawArguments: TStringArray; AllowedPrefixes: TStringArray = []);
+ constructor Create(RawArguments: array of string; AllowedPrefixes: array of string);
destructor Destroy; override;
private
Arguments: array of TArgument;
- procedure ParseArgument(Arg: string; const AllowedPrefixes: TStringArray);
+ procedure ParseArgument(Arg: string; const AllowedPrefixes: array of string);
public
function GetArgument(ID: integer): TArgument;
function IsPresent(ArgumentName: string): boolean;
function GetValue(ArgumentName: string; DefValue: string = ''): string;
- function ValidateArguments(ValidArguments: TStringArray): integer;
+ function ValidateArguments(ValidArguments: array of string): integer;
end;
{FTimeCorrection: integer;}
FTimeOffset: integer;
FTimeOffsetStr: string;
- FListenPorts: TStrings;
+ FListenAddresses: TStrings;
+ FBindAddress: string;
public
function GetVersionStr: string;
- property ListenPorts: TStrings read FListenPorts;
+ property ListenAddresses: TStrings read FListenAddresses;
+ property BindAddress: string read FBindAddress;
property Databytes: longint read FDatabytes;
{property TimeCorrection: integer read FTimeCorrection;}
property TimeOffset: integer read FTimeOffset;
procedure AddRecipient(Recipient: TRecipient); overload;
procedure SetReturnPath(Address: string);
procedure SetRecipientData(Index, Data: integer; RMsg: string = '');
+ procedure SetAllRecipientData(Data: integer; RMsg: string = '');
procedure SetRelayHost(HostName: string);
property ReturnPath: string read FReturnPath write SetReturnPath;
property RelayHost: string read FRelayHost write SetRelayHost;
function EMailTimeStamp(DateTime: TDateTime): string;
function EMailTimeStampCorrected(DateTime: TDateTime): string;
function StatusToStr(Status: integer): string;
- procedure AssignDeliveryStatusToSMTPCodes(Envelope: TEnvelope);
+ procedure AssignDeliveryStatusToSMTPCodes(Envelope: TEnvelope; TransactionComplete: boolean);
function CleanEOLN(S: string): string;
function GenerateRandomString(Length: integer): string;
const
{ MgSMTP version: }
- VERSION_STR = '0.9s';
+ VERSION_STR = '0.9t';
{ Architecture: }
{$IFDEF CPU64}
{ Unit-private functions/prodecures: }
+function InStringArray(const S: string; const SA: array of string): boolean;
+var i: integer;
+begin
+ i:= 0;
+ while (i < Length(SA)) and (SA[i] <> S) do Inc(i);
+ Result:= i < Length(SA);
+end;
+
function MakeTimeOffsetStr(TimeOffset: integer): string;
var CorrS: string; CorrI: integer;
begin
+ '+' + IntToStr(Status and DS_SMTPREPLYMASK);
end;
-procedure AssignDeliveryStatusToSMTPCodes(Envelope: TEnvelope);
+procedure AssignDeliveryStatusToSMTPCodes(Envelope: TEnvelope; TransactionComplete: boolean);
var i, code, cond, status: integer; Recipient: TRecipient;
begin
for i:= 0 to Envelope.GetNumberOfRecipients - 1 do begin
cond:= code div 100;
case cond of
0: status:= DS_DELAYED or DS_UNEXPECTEDFAIL;
- 2: status:= DS_DELIVERED;
+ 2: if TransactionComplete then status:= DS_DELIVERED
+ else status:= DS_DELAYED or DS_UNEXPECTEDFAIL;
4: status:= DS_DELAYED;
5: status:= DS_PERMANENT;
else status:= DS_PERMANENT or DS_UNEXPECTEDFAIL;
end;
end;
+function CmdlineToStringArray: TStringArray;
+var i: integer;
+begin
+ SetLength(Result, ParamCount);
+ for i:= 1 to ParamCount do
+ Result[i-1]:= ParamStr(i);
+end;
+
function UnixTimeStamp(DateTime: TDateTime): TUnixTimeStamp;
begin
{Result:= Trunc((DateTime - EncodeDate(1970, 1 ,1)) * 24 * 60 * 60);}
{ Object constructors/destructors: }
-constructor TArgumentParser.Create(RawArguments: TStringArray; AllowedPrefixes: TStringArray = []);
+constructor TArgumentParser.Create(RawArguments: array of string; AllowedPrefixes: array of string);
var i: integer;
begin
for i:= 0 to Length(RawArguments) - 1 do
end;
constructor TMainServerConfig.Create(Config: TINIFile);
+var i: integer; rawaddresslist: string; portlist: TStringList;
begin
inherited Create(Config.ReadString('Server', 'Name', ''), Config, 'Server');
- FListenPorts:= TStringList.Create;
- FListenPorts.Delimiter:= ',';
- FListenPorts.DelimitedText:= Config.ReadString('Server', 'ListenPort', '25');
+ FListenAddresses:= TStringList.Create;
+ FListenAddresses.Delimiter:= ',';
+
+ rawaddresslist:= Config.ReadString('Server', 'ListenAddress', '');
+ if rawaddresslist <> '' then
+ FListenAddresses.DelimitedText:= rawaddresslist
+ else begin
+ portlist:= TStringList.Create;
+ portlist.Delimiter:= ',';
+ portlist.DelimitedText:= Config.ReadString('Server', 'ListenPort', '25');
+ for i:= 0 to portlist.Count - 1 do
+ FListenAddresses.Add('0.0.0.0:' + portlist.Strings[i]);
+ portlist.Free;
+ end;
+
+ FBindAddress:= Config.ReadString('Server', 'BindAddress', '0.0.0.0');
FDatabytes:= Config.ReadInteger('Server', 'Databytes', 1024 * 1024 * 1024);
- {FTimeCorrection:= Config.ReadInteger('Server', 'TimeCorrection', 0);}
FTimeOffset:= Config.ReadInteger('Server', 'TimeOffset', Config.ReadInteger('Server', 'TimeCorrection', 0) * 100);
FTimeOffsetStr:= MakeTimeOffsetStr(FTimeOffset);
{ Object methods: }
-procedure TArgumentParser.ParseArgument(Arg: string; const AllowedPrefixes: TStringArray);
+procedure TArgumentParser.ParseArgument(Arg: string; const AllowedPrefixes: array of string);
var i, n: integer; found: boolean;
begin
{ Strip prefix if present. }
Result:= DefValue;
end;
-function TArgumentParser.ValidateArguments(ValidArguments: TStringArray): integer;
+function TArgumentParser.ValidateArguments(ValidArguments: array of string): integer;
{ Returns -1 if all arguments are valid. Otherwise, returns the ID of the first
invalid parameter. }
var i: integer;
begin
i:= 0;
- while (i < Length(Arguments)) and (Arguments[i] in ValidArguments) do
+ while (i < Length(Arguments)) and InStringArray(Arguments[i].Option, ValidArguments) do
Inc(i);
- if i < Length(Arguments) then
+ if i >= Length(Arguments) then
Result:= -1
else
Result:= i;
FRecipients[Index].Data:= Data;
end;
+procedure TEnvelope.SetAllRecipientData(Data: integer; RMsg: string = '');
+var i: integer;
+begin
+ for i:= 0 to Length(FRecipients) - 1 do
+ SetRecipientData(i, Data, RMsg);
+end;
+
procedure TEnvelope.SetReturnPath(Address: string);
begin
FReturnPath:= Address;