]> git.stg.codes - ssmd.git/blob - src/main.cpp
1b1d74b8fb5faff3cdc6eb84c811b273811b4bf6
[ssmd.git] / src / main.cpp
1 #include <unistd.h> // daemon
2
3 #include <cerrno> // errno
4 #include <cstring> // strerror
5 #include <csignal>
6 #include <iostream>
7 #include <exception>
8
9 #include "snmp_pp/snmp_pp.h"
10
11 #include "syncer.h"
12 #include "version.h"
13 #include "settings.h"
14 #include "pidfile.h"
15 #include "logger.h"
16
17 SSMD::Logger logger;
18 static bool running = true;
19 static bool reload = false;
20
21 void setSignalHandlers();
22
23 int main(int argc, char * argv[])
24 {
25     SSMD::SettingsParser sParser;
26
27     // Set filter for logging
28     DefaultLog::log()->set_filter(ERROR_LOG, 7);
29     DefaultLog::log()->set_filter(WARNING_LOG, 7);
30     DefaultLog::log()->set_filter(EVENT_LOG, 0);
31     DefaultLog::log()->set_filter(INFO_LOG, 0);
32     DefaultLog::log()->set_filter(DEBUG_LOG, 0);
33
34     try {
35         sParser.init(argc, argv);
36     }
37     catch (const std::exception & ex) {
38         logger << ex.what() << std::endl;
39         return -1;
40     }
41
42     if (sParser.settings().isHelp()) {
43         sParser.printHelp();
44         return 0;
45     }
46
47     if (sParser.settings().isVersion()) {
48         std::cout << "SNMP Switch Management Daemon " << SSMD::version << " (revision: " << SSMD::revision << ")" << std::endl;
49         return 0;
50     }
51
52     if (sParser.settings().isDebug()) {
53         std::cout << "Settings dump:\n"
54                   << "\t- help: " << (sParser.settings().isHelp() ? "yes" : "no") << "\n"
55                   << "\t- version: " << (sParser.settings().isVersion() ? "yes" : "no") << "\n"
56                   << "\t- debug: " << (sParser.settings().isDebug() ? "yes" : "no") << "\n"
57                   << "\t- daemon: " << (sParser.settings().isDaemon() ? "yes" : "no") << "\n"
58                   << "\t- config file: " << sParser.settings().configFile() << "\n"
59                   << "\t- log file: " << sParser.settings().logFile() << "\n"
60                   << "\t- PID file: " << sParser.settings().PIDFile() << "\n"
61                   << "\t- switch sync interval: " << sParser.settings().switchSyncInterval() << "\n"
62                   << "\t- info sync interval: " << sParser.settings().infoSyncInterval() << "\n"
63                   << "\t- switch's upload profile id: " << sParser.settings().upProfileId() << "\n"
64                   << "\t- switch's download profile id: " << sParser.settings().downProfileId() << "\n"
65                   << "\t- max ACL's per PDU: " << sParser.settings().maxACLPerPDU() << "\n"
66                   << "\t- data URL: " << sParser.settings().dataURL() << std::endl;
67     }
68
69     if (sParser.settings().isDaemon()) {
70         if (daemon(0, sParser.settings().isDebug())) {
71             logger << "Failed to daemonize: " << strerror(errno) << std::endl;
72             return -1;
73         }
74     }
75     logger.setLogFile(sParser.settings().logFile());
76
77     try {
78         int status = 0;
79         Snmp snmp(status);
80
81         if (status) {
82             logger << "Failed to initialize SNMP" << std::endl;
83             return -1;
84         }
85
86         SSMD::PIDFile pf(sParser.settings().PIDFile());
87         SSMD::Syncer syncer(sParser, snmp);
88
89         logger << "Starting ssmd main thread..." << std::endl;
90
91         setSignalHandlers();
92
93         // Start main thread
94         syncer.run(running, reload);
95
96         logger << "Main thread stopped." << std::endl;
97     }
98     catch (std::exception & ex) {
99         logger << "Exception: " << ex.what() << std::endl;
100         return -1;
101     }
102
103     return 0;
104 }
105
106 void catchTERM(int)
107 {
108     running = false;
109
110     struct sigaction newsa, oldsa;
111     sigset_t sigmask;
112
113     sigemptyset(&sigmask);
114     sigaddset(&sigmask, SIGTERM);
115     newsa.sa_handler = SIG_IGN;
116     newsa.sa_mask = sigmask;
117     newsa.sa_flags = 0;
118     sigaction(SIGTERM, &newsa, &oldsa);
119
120     sigemptyset(&sigmask);
121     sigaddset(&sigmask, SIGINT);
122     newsa.sa_handler = SIG_IGN;
123     newsa.sa_mask = sigmask;
124     newsa.sa_flags = 0;
125     sigaction(SIGINT, &newsa, &oldsa);
126 }
127
128 void catchHUP(int)
129 {
130     reload = true;
131 }
132
133 void setSignalHandlers()
134 {
135     struct sigaction newsa, oldsa;
136     sigset_t sigmask;
137
138     sigemptyset(&sigmask);
139     sigaddset(&sigmask, SIGTERM);
140     newsa.sa_handler = catchTERM;
141     newsa.sa_mask = sigmask;
142     newsa.sa_flags = 0;
143     sigaction(SIGTERM, &newsa, &oldsa);
144
145     sigemptyset(&sigmask);
146     sigaddset(&sigmask, SIGINT);
147     newsa.sa_handler = catchTERM;
148     newsa.sa_mask = sigmask;
149     newsa.sa_flags = 0;
150     sigaction(SIGINT, &newsa, &oldsa);
151
152     sigemptyset(&sigmask);
153     sigaddset(&sigmask, SIGPIPE);
154     newsa.sa_handler = SIG_IGN;
155     newsa.sa_mask = sigmask;
156     newsa.sa_flags = 0;
157     sigaction(SIGPIPE, &newsa, &oldsa);
158
159     sigemptyset(&sigmask);
160     sigaddset(&sigmask, SIGHUP);
161     newsa.sa_handler = catchHUP;
162     newsa.sa_mask = sigmask;
163     newsa.sa_flags = 0;
164     sigaction(SIGHUP, &newsa, &oldsa);
165 }