Lokaler SMTP Server - Thread Unterstützung
Verfasst: 20.01.2009 17:28
Hallo zusammen,
ich habe mir einen kleinen dummy smtp server geschrieben.
Dieser empfängt nur die Emails welche von jeglichen mail clients
zum dummy server gesendet wird und speichert diese lokal ab.
Offene Fragen:
- Thread Unterstützung
Zur Zeit wird jedes Email nacheinander abgearbeitet. Ich würde
jedoch fast gleichzeitig unmengen an emails empfangen.
Hier weiß ich jedoch nicht wie ich die Thread Unterstützung mit einbinden
kann/soll.
- Manueller Server Zugriff über "telnet"
Wenn ich den dummy server über "telnet localhost <port>"
aufrufe und danach manuell Kommandos eingeben möchte
wie z.B.
Mail From: ....
Nimmt der dummy server sich jeden Zeichen einzelnd vor.
Somit kann ich über die DOS Zeile den server zur Zeit nicht nutzen.
Hätte jemand einen Vorschlag, wie ich das im PB code lösen
könnte?
Anbei auch der Code:
Erstellt mit PB 4.3 Win x86.
Danke + Gruß,
Daniel
ich habe mir einen kleinen dummy smtp server geschrieben.
Dieser empfängt nur die Emails welche von jeglichen mail clients
zum dummy server gesendet wird und speichert diese lokal ab.
Offene Fragen:
- Thread Unterstützung
Zur Zeit wird jedes Email nacheinander abgearbeitet. Ich würde
jedoch fast gleichzeitig unmengen an emails empfangen.
Hier weiß ich jedoch nicht wie ich die Thread Unterstützung mit einbinden
kann/soll.
- Manueller Server Zugriff über "telnet"
Wenn ich den dummy server über "telnet localhost <port>"
aufrufe und danach manuell Kommandos eingeben möchte
wie z.B.
Mail From: ....
Nimmt der dummy server sich jeden Zeichen einzelnd vor.
Somit kann ich über die DOS Zeile den server zur Zeit nicht nutzen.
Hätte jemand einen Vorschlag, wie ich das im PB code lösen
könnte?
Anbei auch der Code:
Code: Alles auswählen
;
;
;
;--- Console Mode
OpenConsole()
;--- Constants
#TITLE = "SMTP Dummy Server, v0.1"
;--- Global Parameters
Global Dim Cli.s(2)
Global Quit.l = 0, flag.l = 0
Global ServerEvent.l, clientID.l
Global result.s = "", fileName.s = ""
;--- Procedures
Procedure SetCli()
; SMTP Port
Cli(0) = "25"
; Save Incoming Mails
Cli(1) = "spool"
; Reserve Address Area
Cli(2) = "512"
EndProcedure
Procedure GetHelp()
PrintN("SMTP Dummy Server - 0.1 - Command Line Interface")
PrintN("")
PrintN("Usage: smtpds.exe OPTIONS")
PrintN("")
PrintN("Options: ")
PrintN(LSet(" ", 10) + "-h Prints this help message.")
PrintN(LSet(" ", 10) + "-p port Port number for connection.")
PrintN(LSet(" ", 20) + "(default: 25)")
PrintN(LSet(" ", 10) + "-s spool directory where incoming mails are saved.")
PrintN(LSet(" ", 20) + "(default: .\spool)")
PrintN(LSet(" ", 10) + "-m kb Avalaible memory in KB for the cache.")
PrintN(LSet(" ", 20) + "(default: 512)")
PrintN("")
End
EndProcedure
Procedure GetCli()
Protected count.l, i.l, cli.s
count = CountProgramParameters()
For i = 0 To count - 1
cli = ProgramParameter(i)
Select LCase(cli)
Case "-h"
GetHelp()
Case "-p"
Cli(0) = ProgramParameter(i+1)
Case "-s"
Cli(1) = ProgramParameter(i+1)
Case "-m"
Cli(2) = ProgramParameter(i+1)
EndSelect
Next
EndProcedure
Procedure ValidateSpoolDirectory()
Protected newPath.s = "", count.l
If Right(Left(Cli(1), 3), 2) <> ":\"
Cli(1) = GetCurrentDirectory() + Cli(1)
EndIf
If FileSize(Cli(1)) = -1
count.l = CountString(Cli(1), "\")
For i = 1 To count + 1
newPath = newPath + StringField(Cli(1), i, "\") + "\"
If FileSize(newPath) = -1
CreateDirectory(newPath)
EndIf
Next
EndIf
If Right(Cli(1), 1) <> "\"
Cli(1) = Cli(1) + "\"
EndIf
EndProcedure
Procedure DisplayCli()
PrintN(LSet("-", 40, "-"))
PrintN(" Spool Directory: " + Cli(1))
PrintN(" Reserved Memory: " + Cli(2) + "Kb")
PrintN(" Server Address: <localhost> : " + Cli(0))
PrintN("")
PrintN(" Note: Press keyboard key " + Chr(39) + "q" + Chr(39))
PrintN(" to shutdown the server.")
PrintN(LSet("-", 40, "-"))
EndProcedure
Procedure.s GetRandomNumber()
Protected number.s, tmpChar.s, result.s
number.s = "0000" + Str(Random(1000))
tmpChar.s = Chr(65 + Random(25)) + Chr(97 + Random(25)) + Chr(65 + Random(25)) + Chr(97 + Random(25))
result.s = FormatDate("%yyyy%mm%dd%hh%ii%ss", Date()) + "-" + Right(result, 4) + tmpChar
ProcedureReturn result
EndProcedure
Procedure.l InitNet()
Protected result.l
If InitNetwork() = 0
result = #False
Else
result = #True
EndIf
ProcedureReturn result
EndProcedure
Procedure.l CloseNet()
CloseNetworkConnection(clientID)
EndProcedure
Procedure ShutdownSmtpServer()
Protected key.s
key = Inkey()
If key = "q"
Quit = 1
PrintN("SMTP Dummy Server is stopped ...")
Delay(500)
EndIf
EndProcedure
Procedure SendNetData(Cmd.s)
SendNetworkString(clientID, Cmd + Chr(13) + Chr(10))
EndProcedure
Procedure.s ReceiveNetData()
Protected *buffer
Protected bufferData.s
Delay(100)
*buffer = AllocateMemory(Val(Cli(2)))
ReceiveNetworkData(clientID, *buffer, Val(Cli(2)))
bufferData = PeekS(*buffer, Val(Cli(2)))
FreeMemory(*buffer)
ProcedureReturn bufferData
EndProcedure
Procedure SpoolIncomingMail(mailContent.s)
If OpenFile(0, fileName)
FileSeek(0, Lof(0))
WriteString(0, mailContent)
CloseFile(0)
EndIf
EndProcedure
;--- Main Program
SetCli()
GetCli()
; Validate TCP/IP Stack
If InitNet() = #False
PrintN("Error: 0x0001 - No TCP/IP stack available on the system.")
End
EndIf
; Start Server
If CreateNetworkServer(#PB_Any, Val(Cli(0)), #PB_Network_TCP)
; Set Windows/1st Line Title
ConsoleTitle(#TITLE)
PrintN(#TITLE)
; Validate if spool directory exists,otherwise createit
ValidateSpoolDirectory()
; Display configuration information
DisplayCli()
; Loop
Repeat
ShutdownSmtpServer()
ServerEvent = NetworkServerEvent()
If ServerEvent
clientID = EventClient()
Select ServerEvent
Case #PB_NetworkEvent_Connect
SendNetData("220 SMTP Dummy Server is available")
PrintN("Client session opens: " + Str(clientID))
Case #PB_NetworkEvent_Disconnect
PrintN("Client session closed: " + Str(clientID))
Case #PB_NetworkEvent_Data
result = ReceiveNetData()
If Left(Trim(LCase(result)), 4) = "data"
flag = 1
fileName = Cli(1) + GetRandomNumber() + ".txt"
SendNetData("354 Add your data information.")
Repeat
result = ReceiveNetData()
If FindString(Right(result, 20), "QUIT", 1)
flag = 0
;PrintN(Left(result, Len(result) - 11))
SpoolIncomingMail(Left(result, Len(result) - 11))
SendNetData("221 Bye.")
CloseNet()
PrintN(" [" + Str(clientID) + "] Spooled: " + fileName)
PrintN("Client session closed: " + Str(clientID))
ElseIf FindString(Right(result, 20), "RSET", 1)
flag = 0
;PrintN(Left(result, Len(result) - 11))
SpoolIncomingMail(Left(result, Len(result) - 11))
PrintN(" [" + Str(clientID) + "] Spooled: " + fileName)
ElseIf FindString(Right(result, 20), "." + Chr(13), 1)
flag = 0
;PrintN(Left(result, Len(result) - 5))
SpoolIncomingMail(Left(result, Len(result) - 5))
PrintN(" [" + Str(clientID) + "] Spooled: " + fileName)
SendNetData("250 Mail has been queued successfully.")
Else
;PrintN(result)
SpoolIncomingMail(result)
EndIf
Until flag = 0
ElseIf result = "."
SendNetData("250 Mail has been queued successfully.")
ElseIf Left(Trim(LCase(result)), 4) = "quit"
SendNetData("221 Bye.")
CloseNet()
PrintN("Client session closed: " + Str(clientID))
ElseIf Right(result, 2) = Chr(13)+ Chr(10)
SendNetData("250 OK")
EndIf
EndSelect
EndIf
Delay(20)
Until Quit = 1
CloseNetworkServer(0)
Else
PrintN("Cannot start server.Port is already busy.")
End
EndIf
End
Danke + Gruß,
Daniel