root/alue_posix.cc

Revision 90836dc4f3981b6170b18cc3b4b5f23483704454, 6.8 KB (checked in by Antti-Juhani Kaijanaho <antti-juhani@…>, 2 years ago)

Move options procsesing to config

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

  • Property mode set to 100644
Line 
1/*  This file is part of Alue, the multiprotocol Internet discussion daemon
2
3    Copyright © 2009, 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#include "http/connection.hh"
22#include "logger/logline.hh"
23#include "nntp/connection.hh"
24#include "server.hh"
25#include "tls/init.hh"
26
27#include <boost/asio.hpp>
28#include <cerrno>
29#include <cstring>
30#include <stdio.h>
31#include <stdlib.h>
32#include <exception>
33#include <execinfo.h>
34#include <iostream>
35#include <grp.h>
36#include <pwd.h>
37#include <signal.h>
38#include <sys/resource.h>
39#include <unistd.h>
40
41namespace {
42        server *hup_server;
43        void hup_handler(int)
44        {
45                hup_server->hup();
46        }
47
48        void abort_handler(int)
49        {
50                static void *array[50];
51                size_t size;
52                size = backtrace(array, sizeof array / sizeof *array);
53                backtrace_symbols_fd(array, size, 2);
54                _exit(1);
55        }
56}
57
58int main(int argc, char *argv[])
59{
60
61        rlimit rlim;
62        configure(argc, argv, rlim);
63
64        if (config.count("operator-email") == 0)
65        {
66                std::cerr << "operator-email is mandatory" << std::endl;
67        }
68
69        passwd *pw = 0;
70        if (!config["user"].empty()) {
71                pw = getpwnam(config["user"].as<std::string>().c_str());
72                if (pw == 0) {
73                        std::cerr << "invalid user (" << strerror(errno)
74                                  << ")"
75                                  << std::endl;
76                        return 1;
77                }
78        }
79
80        if ((getuid() == 0 || geteuid() == 0) &&
81            config["user"].empty()) {
82                std::cerr << "started as root: --user is mandatory\n";
83                return 1;
84        }
85       
86        if (setrlimit(RLIMIT_AS, &rlim) == -1)
87        {
88                std::cerr << "setrlimit failed: " << strerror(errno)
89                          << std::endl;
90                return 1;
91        }
92
93        std::string homedir = config["home"].as<std::string>();
94
95        if (chdir(homedir.c_str()) == -1)
96        {
97                std::cerr << "chdir failed: " << std::strerror(errno)
98                          << std::endl;
99                return 1;
100        }
101
102        logger::logger.open(config["logfile"].as<std::string>());
103
104        if (config["daemon"].as<bool>())
105        {
106                switch (fork())
107                {
108                case 0:
109                        break;
110                default:
111                        _exit(0);
112                case -1:
113                        std::cerr << "fork failed: " 
114                                  << std::strerror(errno)
115                                  << std::endl;
116                        return 1;
117                }
118               
119                if (setsid() == (pid_t) -1)
120                {
121                        logger::logline ll;
122                        ll << "setsid failed: " << std::strerror(errno);
123                        return 1;
124                }
125               
126                switch (fork())
127                {
128                case 0:
129                        break;
130                default:
131                        _exit(0);
132                case -1:
133                        logger::logline ll;
134                        std::cerr << "fork failed: "  << std::strerror(errno);
135                        return 1;
136                }
137         
138                umask(0);
139        }
140
141        struct sigaction sact;
142        sact.sa_handler = abort_handler;
143        sigemptyset(&sact.sa_mask);
144        sact.sa_flags = 0;
145        sigaction(SIGABRT, &sact, 0);
146
147        try {
148                               
149                std::map<std::string,std::pair
150                        <boost::shared_ptr<server::connection_factory>, bool> >
151                        ports;
152
153                ports[config["nntp-port"].as<std::string>()].first.reset
154                        (new nntp::connection::factory(false));
155                ports[config["nntp-port"].as<std::string>()].second =
156                        config["log-nntp"].as<bool>();
157               
158                ports[config["nntps-port"].as<std::string>()].first.reset
159                        (new nntp::connection::factory(true));
160                ports[config["nntps-port"].as<std::string>()].second =
161                        config["log-nntp"].as<bool>();
162               
163                ports[config["https-port"].as<std::string>()].first.reset
164                        (new http::connection::factory(true));
165                ports[config["https-port"].as<std::string>()].second =
166                        config["log-http"].as<bool>();
167               
168                tls::init tls_init
169                        (config["cert-file"].as<std::string>().c_str(),
170                         config["key-file"].as<std::string>().c_str(),
171                         tls::init::pem);
172               
173                boost::asio::io_service ios;
174                server srv(ios, tls_init, ports);
175               
176                hup_server = &srv;
177                sact.sa_handler = hup_handler;
178                sigaction(SIGHUP, &sact, 0);
179               
180                if (getuid() == 0 || geteuid() == 0) {
181                        if (setgroups(0, 0) == -1) {
182                                logger::logline ll;
183                                ll << "setgroups failed: " << strerror(errno);
184                                return 1;
185                        }
186                        if (setgid(pw->pw_gid) == -1) {
187                                logger::logline ll;
188                                ll << "setgid failed: " << strerror(errno);
189                                return 1;
190                        }
191                        if (setuid(pw->pw_uid) == -1) {
192                                logger::logline ll;
193                                ll << "setuid failed: " << strerror(errno);
194                                return 1;
195                        }
196                }
197               
198                srv.run();
199        }
200        catch (std::exception &e)
201        {
202                logger::logline ll;
203                ll << "exiting due to exception "
204                   << typeid(e).name()
205                   << ": "
206                   << e.what();
207                ll.close();
208                logger::logger.flush();
209                return 1;
210        }
211}
Note: See TracBrowser for help on using the browser.