├── .gitignore ├── README.md └── main.go /.gitignore: -------------------------------------------------------------------------------- 1 | jungle_smtp 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jungle_smtp 2 | 3 | golang smtp server that just writes every incoming email to a text file 4 | 5 | 6 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "net" 4 | import "fmt" 5 | import "bufio" 6 | import "time" 7 | import "os" 8 | import "io" 9 | 10 | type Client struct { 11 | conn net.Conn 12 | address string 13 | time int64 14 | bufin *bufio.Reader 15 | bufout *bufio.Writer 16 | } 17 | 18 | func (c *Client) w(s string) { 19 | c.bufout.WriteString(s + "\r\n") 20 | c.bufout.Flush() 21 | } 22 | func (c *Client) r() string { 23 | reply, err := c.bufin.ReadString('\n') 24 | if err != nil { 25 | fmt.Println("e ", err) 26 | } 27 | return reply 28 | } 29 | 30 | func appendToFile(text string) { 31 | of, _ := os.OpenFile("incoming_emails.txt", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660) 32 | defer of.Close() 33 | of.Seek(0, os.SEEK_END) 34 | io.WriteString(of, text+"\n") 35 | } 36 | 37 | func handleClient(c *Client) { 38 | fmt.Println("here") 39 | c.w("220 Welcome to the Jungle") 40 | text := c.r() 41 | appendToFile(text) 42 | c.w("250 No one says helo anymore") 43 | text = c.r() 44 | appendToFile(text) 45 | c.w("250 Sender") 46 | text = c.r() 47 | appendToFile(text) 48 | c.w("250 Recipient") 49 | text = c.r() 50 | appendToFile(text) 51 | c.w("354 Ok Send data ending with .") 52 | for { 53 | text = c.r() 54 | bytes := []byte(text) 55 | appendToFile(text) 56 | // 46 13 10 57 | if bytes[0] == 46 && bytes[1] == 13 && bytes[2] == 10 { 58 | break 59 | } 60 | } 61 | c.w("250 server has transmitted the message") 62 | c.conn.Close() 63 | } 64 | 65 | func main() { 66 | listener, err := net.Listen("tcp", "0.0.0.0:25") 67 | if err != nil { 68 | fmt.Println("run as root") 69 | return 70 | } 71 | 72 | for { 73 | fmt.Println("waiting...") 74 | conn, err := listener.Accept() 75 | if err != nil { 76 | continue 77 | } 78 | go handleClient(&Client{ 79 | conn: conn, 80 | address: conn.RemoteAddr().String(), 81 | time: time.Now().Unix(), 82 | bufin: bufio.NewReader(conn), 83 | bufout: bufio.NewWriter(conn), 84 | }) 85 | } 86 | } 87 | --------------------------------------------------------------------------------