function mysplit (inputstr, sep) if sep == nil then sep = "%s" end local t={} for str in string.gmatch(inputstr, "([^"..sep.."]+)") do table.insert(t, str) end return t end function table.slice(tbl, first, last, step) local sliced = {} for i = first or 1, last or #tbl, step or 1 do sliced[#sliced+1] = tbl[i] end return sliced end function validate(data,from,to) headers = {} begindata = false i = 1 while true do line = mysplit(data,"\n")[i] if line == nil then break end if begindata == false then line = mysplit(line, ":") if line[1] == nil then begindata = true else headers[line[1]] = line[2] end else headers["body"] = (headers["body"] or "") .. line .. "\n" end i = i + 1 end if not headers["From"] or not headers["From"]:find(from) then return false end if not to:find("@doesnm.cc") then return false end return headers end function string.starts(String,Start) return string.sub(String,1,string.len(Start))==Start end from = nil to = nil dir = nil data = false dataBuf = "" boxes = table.slice(arg,1)[1] print("220 doesnm.cc Simple Mail Transfer Service Ready") while true do line = io.read("*line") line = mysplit(line) if line[1] == "NOOP" and data == false then print("250 OK") elseif line[1] == "HELO" then if #line < 2 then print("251 Command requires argument") else print("250 Hello " .. line[2]) end elseif line[1] == "EHLO" then if #line < 2 then print("251 Command requires argument") else print("250-Hello " .. line[2]) print("250 SIZE 1000000") end elseif line[1] == "VRFY" and data == false then print("252 Cannot VRFY user, but will accept message") elseif line[1] == "QUIT" and data == false then print("221 Bye!") os.exit() elseif line[1] == "MAIL" and data == false then if #line < 2 then print("501 Incorrent number of arguments") else if string.starts(line[2],"FROM:") then from = table.concat(table.slice(mysplit(table.concat(line," "),":"),2)) print("250 OK") else print("501 Incorrect number of arguments") end end elseif line[1] == "RCPT" and data == false then if #line < 2 then print("501 Incorrent number of arguments") else if string.starts(line[2],"TO:") then to = table.concat(table.slice(mysplit(table.concat(line," "),":"),2)) boxes = table.slice(arg,1) for i=1,#boxes do boxes[i] = mysplit(boxes[i],":") if to:find(boxes[i][1]) then dir = boxes[i][2] break end end if dir == nil then print("550 mail adress not found and server don't support forwarding") else print("250 OK") end else print("502 Unrecognized command") end end elseif line[1] == "DATA" and from ~= nil and to ~= nil then data = true print("354 Send message content; End with .") elseif line[1] == "." and data == true then if not validate(dataBuf,from,to) then print("250 NOTOK") data = false else name = os.time() .. "." .. _G["posix.unistd"].getpid() .. "." .. io.popen("hostname"):read("line") ptf = dir .. "/tmp/" .. name out = io.open(ptf,"w") out:write("From " .. from .." ".. os.date("%a %b %d %H:%M:%S %Y") .. "\n") out:write(dataBuf) out:close() os.rename(ptf,dir .. "/new/" .. name) print("250 OK") data = false end else if data == true then dataBuf = dataBuf .. table.concat(line, " ") .. "\n" else print("502 Unrecognized command") end end end