root/inject-email.cc

Revision 8a3d4da0d509fbebda6afc08d3cd9e6d03a7df4f, 5.0 KB (checked in by Antti-Juhani Kaijanaho <ajk@…>, 20 months ago)

inject-email: Put the result message to stderr, not stdout

Signed-off-by: Antti-Juhani Kaijanaho <ajk@…>

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2010 Antti-Juhani Kaijanaho
4
5    Alue is free software: you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9
10    Alue is distributed in the hope that it will be useful, but
11    WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with Alue.  If not, see <http://www.gnu.org/licenses/>.
17
18 */
19
20#include "config.hh"
21
22#include <boost/assert.hpp>
23#include <boost/asio.hpp>
24#include <cerrno>
25#include <execinfo.h>
26#include <iostream>
27#include <sysexits.h>
28
29namespace boost
30{
31        void assertion_failed(char const *expr,
32                              char const *function,
33                              char const *file,
34                              long line)
35        {
36                std::cerr << "ASSERTION FAILED at "
37                          << file << ":"
38                          << line
39                          << " [" << function << "]: "
40                          << expr
41                          << "\n";
42
43                static void *array[250];
44                size_t size;
45                size = backtrace(array, sizeof array / sizeof *array);
46                char **bt = backtrace_symbols(array, size);
47
48                std::cerr << "BACKTRACE FOLLOWS:\n";
49                for (size_t i = 0; i < size; i++)
50                {
51                        std::cerr << "\t" << bt[i] << "\n";
52                }
53
54                std::free(bt);
55
56                throw std::logic_error("internal error");
57        }
58}
59
60int main(int argc, char *argv[])
61{
62        rlimit rlim;
63        configure(argc, argv, rlim);
64
65        std::string homedir = config["home"].as<std::string>();
66
67        if (chdir(homedir.c_str()) == -1)
68        {
69                std::cerr << "chdir failed: " << std::strerror(errno)
70                          << std::endl;
71                return EX_CONFIG;
72        }
73
74        char *recip = ::getenv("ORIGINAL_RECIPIENT");
75        if (recip == 0) recip = ::getenv("RECIPIENT");
76               
77        char *sender = ::getenv("SENDER");
78        if (recip == 0 || sender == 0)
79        {
80                std::cerr << "invalid environment\n";
81                return EX_CONFIG;
82        }
83
84        std::string group = recip;
85        int at = group.find('@');
86        if (at != std::string::npos) group = group.substr(0, at);
87
88        typedef boost::asio::local::stream_protocol sp;
89
90        boost::asio::io_service ios;
91        sp::endpoint ep(config["unix-socket"].as<std::string>());
92        try
93        {
94                sp::socket so(ios);
95                so.connect(ep);
96
97                std::ostringstream msg;
98
99                msg << "ACTION: POST\r\n"
100                    << "GROUP: " << group << "\r\n"
101                    << "SENDER: " << sender << "\r\n"
102                    << "\r\n";
103
104                bool cr = false;
105                bool sol = true;
106                while (true)
107                {
108                        int c = std::cin.get();
109                        if (c == -1) break;
110                        switch (c)
111                        {
112                        case '\r':
113                                sol = true;
114                                if (cr) msg << "\n"; else cr = true;
115                                break;
116                        case '\n':
117                                sol = true;
118                                if (!cr) msg << "\r";
119                                cr = false;
120                                break;
121                        default:
122                                cr = false;
123                                sol = false;
124                        }
125                        msg << (unsigned char)c;
126                }
127                if (!sol)
128                {
129                        if (cr) msg << "\n"; else msg << "\r\n";
130                }
131
132                std::string msgb = msg.str();
133
134                boost::asio::write(so, boost::asio::buffer(msgb.data(),
135                                                           msgb.length()));
136                so.shutdown(sp::socket::shutdown_send);
137
138                boost::asio::streambuf sb;
139                std::istream is(&sb);
140
141                try
142                {
143                        boost::asio::read(so, sb);
144                }
145                catch (boost::system::system_error &e)
146                {
147                        if (e.code() != boost::asio::error::eof) throw;
148                }
149
150                int ex;
151                is >> ex;
152                std::string tmp;
153                std::getline(is, tmp);
154
155                std::cerr << &sb;
156               
157                return ex;
158
159        }
160        catch (std::exception &e)
161        {
162                std::cout << e.what() << "\n";
163                return EX_TEMPFAIL;
164        }
165}
Note: See TracBrowser for help on using the browser.