ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/pxys2-2.0.0/pxyscand/src/PXCore.cc
Revision: 3252
Committed: Wed Apr 2 20:41:43 2014 UTC (9 years, 11 months ago) by michael
Content type: text/x-c++src
File size: 5046 byte(s)
Log Message:
- Imported pxys2-2.0.0

File Contents

# Content
1 // Copyright (C) 2003 Stephane Thiell
2 //
3 // This file is part of pxyscand (from pxys)
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 #define RCSID "$Id: PXCore.cc,v 1.2 2004/01/02 03:08:16 mbuna Exp $"
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "PXCore.h"
26 #include "PXConfig.h"
27 #include "PXConfigLoader.h"
28 #include "PXScanManager.h"
29 #include "PXServer.h"
30 #include <fstream>
31 #include <iostream>
32 #include <cstdlib>
33 #ifdef HAVE_SIGNAL_H
34 #include <signal.h>
35 #endif
36
37 using std::clog;
38 using std::endl;
39
40 enum {
41 OPT_FORK = 1 << 0,
42 OPT_CHKCFG = 1 << 1,
43 OPT_DLMAX = 1 << 2
44 };
45
46 PXCore::PXCore(int argc, char *argv[])
47 {
48 this->ParseArguments(argc, argv);
49
50 // Pre fork
51 if ((mOptions & OPT_FORK) && fork())
52 exit(0);
53
54 mBirthTime = time(0);
55 srand((unsigned int)mBirthTime ^ getpid());
56
57 try
58 {
59 PXConfigLoader *cfgLoader = new PXConfigLoader(mConfigFile);
60 mConfig = cfgLoader->Load();
61 }
62 catch (PXXMLException &e)
63 {
64 clog << "Failed to load configuration file \"" << mConfigFile
65 << "\":" << endl;
66 clog << e.GetErrorString() << " - hint: " << e.GetHint() << endl;
67 exit(EXIT_FAILURE);
68 }
69
70 this->SetMaxFDs();
71 }
72
73 PXCore::~PXCore()
74 {
75 free(mConfigFile);
76 }
77
78 void
79 PXCore::ParseArguments(int argc, char *argv[])
80 {
81 extern char *optarg;
82 int c, options = OPT_FORK; /* default */
83
84 while ((c = getopt(argc, argv, "cdf:tv")) != -1)
85 {
86 switch (c)
87 {
88 case 'c':
89 options = (options | OPT_CHKCFG) & ~OPT_FORK;
90 break;
91 case 'd':
92 options |= OPT_DLMAX;
93 break;
94 case 'f':
95 mConfigFile = strdup(optarg);
96 break;
97 case 't':
98 options &= ~OPT_FORK;
99 break;
100 case 'v':
101 DisplayVersion();
102 break;
103 case '?':
104 default:
105 DisplayUsage();
106 break;
107 }
108 }
109
110 if (!mConfigFile)
111 DisplayUsage();
112
113 mOptions = options;
114 }
115
116 void
117 PXCore::SetMaxFDs()
118 {
119 int val = mConfig->scanner.maxscans + MAX_SESSIONS;
120 if (peak_task_set_info(peak_task_self(), PEAK_TASK_FLAVOR_MAXFDS, &val) != 0)
121 {
122 clog << "PXCore::SetMaxFDs: failed to set PEAK_TASK_FLAVOR_MAXFDS" << endl;
123 clog << "Maybe reduce <maxscans> ?" << endl;
124 exit(1);
125 }
126 }
127
128 int
129 PXCore::Start()
130 {
131 if (mOptions & OPT_CHKCFG)
132 {
133 PXConfigLoader::Dump(mConfig);
134 return EXIT_SUCCESS;
135 }
136
137 this->InitializeSignals();
138 this->LogPID();
139
140 mScanManager = new PXScanManager(mConfig);
141
142 mServer = new PXServer(mConfig, mScanManager, this);
143 if (mServer->Start() != 0)
144 return EXIT_FAILURE;
145
146 // Finish daemonize
147 if (mOptions & OPT_FORK)
148 {
149 close(STDOUT_FILENO);
150 close(STDIN_FILENO);
151 close(STDERR_FILENO);
152 setsid();
153 }
154
155 // And run !
156 peak_task_run(peak_task_self());
157 return 0;
158 }
159
160 void
161 PXCore::Stop()
162 {
163 mServer->Rehash(); // Save caches
164 peak_task_break(peak_task_self());
165 }
166
167 void
168 PXCore::InitializeSignals()
169 {
170 int sn[3] = { SIGHUP, SIGINT, SIGTERM };
171
172 for (int i = 0; i < 3; i++)
173 peak_signal_schedule(peak_signal_create(sn[i], SignalsCallback, this),
174 peak_task_self());
175
176 peak_signal_ignore(SIGPIPE);
177 }
178
179 void
180 PXCore::SignalsCallback(peak_signal s, int sig, void *context)
181 {
182 PXCore *core = (PXCore *)context;
183
184 peak_task_exclusivity();
185
186 switch (sig)
187 {
188 case SIGHUP:
189 core->mServer->Rehash(); // Save caches
190 // TODO: reload conf
191 break;
192 case SIGINT:
193 if (core->mOptions & OPT_FORK)
194 {
195 clog << "Received SIGINT. Use SIGTERM to terminate pxyscand." << endl;
196 break;
197 }
198 case SIGTERM:
199 core->Stop();
200 break;
201 }
202 }
203
204 void
205 PXCore::DisplayUsage() const
206 {
207 clog << "*** Usage: pxyscand [-ctv] -f <config_file>" << endl;
208 clog << "*** -c check configuration file" << endl;
209 clog << "*** -t run in foreground" << endl;
210 clog << "*** -v show version and exit" << endl;
211 exit(EXIT_FAILURE);
212 }
213
214 void
215 PXCore::DisplayVersion() const
216 {
217 clog << "*** pxyscand " << VERSION << endl; // TODO
218 clog << "*** Part of pxys v.2 software suite" << endl;
219 clog << "*** " << RCSID << endl;
220 exit(EXIT_SUCCESS);
221 }
222
223 void
224 PXCore::LogPID() const
225 {
226 std::ofstream f("pxyscand.pid");
227 if (f)
228 f << (int)getpid() << endl;
229 else
230 clog << "PXCore::LogPID: pid file open failure" << endl;
231 }