1 | // copyright (C) 2002, 2003 graydon hoare <graydon@pobox.com>␊ |
2 | // all rights reserved.␊ |
3 | // licensed to the public under the terms of the GNU GPL (>= 2)␊ |
4 | // see the file COPYING for details␊ |
5 | ␊ |
6 | #include "transforms.hh"␊ |
7 | #include "network.hh"␊ |
8 | #include "smtp_tasks.hh"␊ |
9 | #include "proto_machine.hh"␊ |
10 | #include "sanity.hh"␊ |
11 | #include "ui.hh"␊ |
12 | ␊ |
13 | #include <time.h>␊ |
14 | ␊ |
15 | // this file contains a simple function which builds up an SMTP state␊ |
16 | // machine and runs it using the infrastructure in proto_machine.{cc,hh}␊ |
17 | ␊ |
18 | using namespace std;␊ |
19 | ␊ |
20 | string curr_date_822()␊ |
21 | {␊ |
22 | size_t const sz = 1024;␊ |
23 | char buf[sz];␊ |
24 | time_t now;␊ |
25 | struct tm local;␊ |
26 | ␊ |
27 | I(time(&now) != ((time_t)-1));␊ |
28 | I(localtime_r (&now, &local) != NULL);␊ |
29 | I(strftime(buf, sz, "%a, %d %b %Y %H:%M:%S %z", &local) != 0);␊ |
30 | ␊ |
31 | string result(buf);␊ |
32 | return result;␊ |
33 | }␊ |
34 | ␊ |
35 | struct smtp_postlines_state : public proto_state␊ |
36 | {␊ |
37 | string const & to;␊ |
38 | string const & from;␊ |
39 | string const & subject;␊ |
40 | string const & body;␊ |
41 | explicit smtp_postlines_state(string const & t,␊ |
42 | ␉␉␉␉string const & frm, ␊ |
43 | ␉␉␉␉string const & subj,␊ |
44 | ␉␉␉␉string const & bod)␊ |
45 | : to(t), from(frm), subject(subj), body(bod)␊ |
46 | {}␊ |
47 | virtual ~smtp_postlines_state() {}␊ |
48 | virtual proto_edge drive(iostream & net, proto_edge const & e)␊ |
49 | {␊ |
50 | vector<string> lines, split;␊ |
51 | lines.push_back("Date: " + curr_date_822());␊ |
52 | lines.push_back("From: " + from);␊ |
53 | lines.push_back("Subject: " + subject);␊ |
54 | lines.push_back("To: " + to);␊ |
55 | lines.push_back("");␊ |
56 | split_into_lines(body, split);␊ |
57 | copy(split.begin(), split.end(), back_inserter(lines));␊ |
58 | return proto_state::step_lines(net, lines);␊ |
59 | } ␊ |
60 | };␊ |
61 | ␊ |
62 | bool post_smtp_article(string const & envelope_host,␊ |
63 | ␉␉ string const & envelope_sender,␊ |
64 | ␉␉ string const & envelope_recipient,␊ |
65 | ␉␉ string const & from,␊ |
66 | ␉␉ string const & to,␊ |
67 | ␉␉ string const & subject,␊ |
68 | ␉␉ string const & article,␊ |
69 | ␉␉ std::iostream & stream)␊ |
70 | {␊ |
71 | // build state machine nodes␊ |
72 | cmd_state helo("HELO", envelope_host);␊ |
73 | cmd_state mail("MAIL", "FROM:<" + envelope_sender + ">");␊ |
74 | cmd_state rcpt("RCPT", "TO:<" + envelope_recipient + ">");␊ |
75 | cmd_state data("DATA");␊ |
76 | smtp_postlines_state post(to, from, subject, article);␊ |
77 | cmd_state quit("QUIT");␊ |
78 | ␊ |
79 | helo.add_edge(250, &mail);␊ |
80 | mail.add_edge(250, &rcpt);␊ |
81 | rcpt.add_edge(250, &data);␊ |
82 | data.add_edge(354, &post);␊ |
83 | post.add_edge(250, &quit);␊ |
84 | ␊ |
85 | run_proto_state_machine(&helo, stream); ␊ |
86 | return (post.get_res_code() == 250);␊ |
87 | }␊ |