X-Git-Url: http://git.megabrutal.com/?p=mgsmtp.git;a=blobdiff_plain;f=MgSMTP.pas;h=19dc9685e13a0960decb1bff1401374d051f8885;hp=cecfdc9ff054846e81f3ed3afd6b7581b40ad850;hb=HEAD;hpb=4806fe76baf12d97f1afe2f9b29ea384d37aa839 diff --git a/MgSMTP.pas b/MgSMTP.pas index cecfdc9..19dc968 100644 --- a/MgSMTP.pas +++ b/MgSMTP.pas @@ -1,6 +1,6 @@ { MegaBrutal's SMTP Server (MgSMTP) - Copyright (C) 2010-2014 MegaBrutal + Copyright (C) 2010-2018 MegaBrutal This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by @@ -42,19 +42,24 @@ const ) ); + ArgumentPrefixes: array[0..2] of string = ('/', '--', '-'); + ValidArguments: array[0..4] of string = ('?', 'HELP', 'INSTALL', 'UNINSTALL', 'USERMODE'); + { For development test builds, you can add a developer comment here to document what bugfix/feature are you testing with the actual build. This will be logged to help you differentiate outputs of subsequent builds in your logs. If left empty, it won't be added to the logs. } - DEVCOMMENT = 'Testing new parameters'; + DEVCOMMENT = 'BindAddress'; var + Cmdline: TArgumentParser; Config: TINIFile; hSCManager, hService: THandle; hSvcStatusHandle: THandle; SvcStatus: TServiceStatus; ServiceMode, Stopping: boolean; + WrongArgument: integer; procedure AddDevComment(Log: TStreamLogger); @@ -125,6 +130,16 @@ begin end; end; +function ConsoleCtrlHandler(Signal: dword): longbool; stdcall; +{ Handle CTRL-C event in user mode. } +begin + if Signal = CTRL_C_EVENT then begin + Out.writeln('Caught CTRL-C signal.'); + Stopping:= true; + end; + Result:= true; +end; + procedure Service(Argc: dword; Argv: pointer); stdcall; var ProposedExitCode: integer; begin @@ -164,13 +179,18 @@ begin SpoolManager:= TSpoolManager.Create(Config); PolicyManager:= TPolicyManager.Create(Config); + AddDevComment(Logger); + + if (Config.ReadString('Server', 'ListenAddress', '') = '') + and (Config.ReadString('Server', 'ListenPort', '') <> '') then + Logger.AddStdLine('WARNING! Server\ListenPort is deprecated. Use ListenAddress instead!'); + if Config.ReadBool('Spool', 'KeepProcessedEnvelopes', false) or Config.ReadBool('Spool', 'KeepProcessedEMails', false) then if not DirectoryExists('processed') then CreateDir('processed'); Config.Free; - AddDevComment(Logger); Logger.AddStdLine('Primary server name: ' + MainServerConfig.Name); Logger.AddStdLine('FCrDNS policy: ' + FCrDNSPolicyToStr(PolicyManager.FCrDNSPolicy)); if MailboxManager.DomainSpecific then @@ -216,7 +236,7 @@ begin end else begin Config.Free; - Out.writeln('Error: Server/Name is a mandatory configuration entry.'#13#10 + Out.writeln('Error: Server\Name is a mandatory configuration entry.'#13#10 + 'Please configure the application properly, refer to the manual.'); ReportSvcStatus(SERVICE_STOPPED, 2, 0); end; @@ -231,22 +251,19 @@ end; begin Out.writeln('MegaBrutal''s SMTP Server, version ' + VERSION_STR + ', ' + IntToStr(PLATFORM_BITS) + ' bits'); - Out.writeln('Copyright (C) 2010-2014 MegaBrutal'); + Out.writeln('Copyright (C) 2010-2018 MegaBrutal'); AddDevComment(Out); Out.writeln; { TODO: Process arguments here. } + Cmdline:= TArgumentParser.Create(CmdlineToStringArray, ArgumentPrefixes); + WrongArgument:= Cmdline.ValidateArguments(ValidArguments); - ServiceMode:= false; + if WrongArgument = -1 then begin - if ParamCount > 0 then begin + ServiceMode:= false; - if UpperCase(ParamStr(1)) = '/USERMODE' then begin - Out.writeln('Starting MgSMTP in user mode...'); - Service(0, nil); - end - - else if ParamStr(1) = '/?' then begin + if Cmdline.IsPresent('?') or Cmdline.IsPresent('HELP') then begin Out.writeln('Supported arguments:'); Out.writeln('/INSTALL - registers the actual MgSMTP binary'); Out.writeln(' as a Windows service.'); @@ -265,11 +282,11 @@ begin Out.writeln('https://sourceforge.net/projects/mgsmtp/'); end - else if (UpperCase(ParamStr(1)) = '/INSTALL') or (UpperCase(ParamStr(1)) = '/UNINSTALL') then begin + else if (Cmdline.IsPresent('INSTALL') or Cmdline.IsPresent('UNINSTALL')) then begin { Register / unregister service. } hSCManager:= OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if hSCManager <> 0 then begin - if UpperCase(ParamStr(1)) = '/INSTALL' then begin + if Cmdline.IsPresent('INSTALL') then begin if CreateService(hSCManager, 'MgSMTP', 'MegaBrutal''s SMTP Server (MgSMTP)', SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, @@ -283,7 +300,7 @@ begin else Out.writeln('CreateService failed!'); end - else if UpperCase(ParamStr(1)) = '/UNINSTALL' then begin + else if Cmdline.IsPresent('UNINSTALL') then begin hService:= OpenService(hSCManager, 'MgSMTP', SC_MANAGER_ALL_ACCESS); if hService <> 0 then begin if DeleteService(hService) then @@ -292,25 +309,40 @@ begin Out.writeln('DeleteService failed!'); end else Out.writeln('OpenService failed!'); - end - else Out.writeln('Unknown parameter.'); + end; end else Out.writeln('OpenSCManager failed!'); end - else Out.writeln('Unknown parameter specified!'); + + else begin + if Cmdline.IsPresent('USERMODE') then begin + Out.writeln('Starting MgSMTP in user mode...'); + SetConsoleCtrlHandler(ConsoleCtrlHandler, true); + Service(0, nil); + end + else begin + Out.writeln('Trying to contact Service Control Manager...'); + Out.writeln('(If you see this message on console, you tried to'); + Out.writeln('start up the program incorrectly. Your current'); + Out.writeln('attempt will fail, or it may hang under Wine.)'); + Out.writeln; + ServiceMode:= true; + if not StartServiceCtrlDispatcher(ServiceTable) then begin + ServiceMode:= false; + Out.writeln('Failed!'); + Out.writeln; + Out.writeln('You need to start MgSMTP as a service,'); + Out.writeln('or supply proper arguments!'); + Out.writeln('Issue with /? for more information.'); + end; + end; + end + end + else begin - Out.writeln('Trying to contact Service Control Manager...'); - ServiceMode:= true; - if not StartServiceCtrlDispatcher(ServiceTable) then begin - ServiceMode:= false; - Out.writeln('Failed!'); - Out.writeln; - Out.writeln('You need to start MgSMTP as a service,'); - Out.writeln('or supply proper arguments!'); - Out.writeln('Issue with /? for more information.'); - end; + Out.writeln('Invalid argument: ' + Cmdline.GetArgument(WrongArgument).Option + '!'); end; end.