2 Copyright 2004-2005 Chris Tallon
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include "mvpserver.h"
26 extern pthread_mutex_t threadClientMutex;
28 MVPServer::MVPServer()
30 // MH in case anbody has a better position :-)
31 pthread_mutex_init(&threadClientMutex, NULL);
34 MVPServer::~MVPServer()
41 if (threadIsActive()) threadCancel();
42 close(listeningSocket);
49 log.log("Main", Log::INFO, "Stopped main server thread");
57 int MVPServer::run(char* tconfigDir)
59 if (threadIsActive()) return 1;
61 configDir = tconfigDir;
65 #define dsyslog(x) std::cout << x << std::endl;
68 char configFileName[PATH_MAX];
69 snprintf(configFileName, PATH_MAX, "%s/vomp.conf", configDir);
71 if (config.init(configFileName))
73 dsyslog("VOMP: Config file found");
77 dsyslog("VOMP: Config file not found");
82 char* cfgLogFilename = config.getValueString("General", "Log file");
85 log.init(Log::DEBUG, cfgLogFilename);
86 delete[] cfgLogFilename;
87 log.log("Main", Log::INFO, "Logging started");
91 dsyslog("VOMP: Logging disabled");
94 // Work out a name for this server
98 // Try to get from vomp.conf
99 serverName = config.getValueString("General", "Server name");
100 if (!serverName) // If not, get the hostname
102 serverName = new char[1024];
103 if (gethostname(serverName, 1024)) // if not, just use "-"
105 strcpy(serverName, "-");
109 int udpSuccess = udpr.run(serverName);
115 log.log("Main", Log::CRIT, "Could not start UDP replier");
120 // Read config and start bootp and tftp as appropriate
123 int bootpEnabled = 0;
125 int mvprelayEnabled = 1;
127 configString = config.getValueString("General", "Bootp server enabled");
128 if (configString && (!strcasecmp(configString, "yes"))) bootpEnabled = 1;
129 if (configString) delete[] configString;
131 configString = config.getValueString("General", "TFTP server enabled");
132 if (configString && (!strcasecmp(configString, "yes"))) tftpEnabled = 1;
133 if (configString) delete[] configString;
135 configString = config.getValueString("General", "MVPRelay enabled");
136 if (configString && (strcasecmp(configString, "yes"))) mvprelayEnabled = 0;
137 if (configString) delete[] configString;
142 if (!bootpd.run(configDir))
144 log.log("Main", Log::CRIT, "Could not start Bootpd");
151 log.log("Main", Log::INFO, "Not starting Bootpd");
156 char tftpPath[PATH_MAX];
158 configString = config.getValueString("General", "TFTP directory");
161 snprintf(tftpPath, PATH_MAX, "%s", configString);
163 // this will never happen.. surely.
164 if ((strlen(tftpPath) + 2) >= PATH_MAX)
166 delete[] configString;
167 log.log("Main", Log::CRIT, "Could not understand TFTP directory from config");
172 // if there isn't a / at the end of the dir, add one
173 if (tftpPath[strlen(tftpPath) - 1] != '/') strcat(tftpPath, "/");
175 delete[] configString;
179 snprintf(tftpPath, PATH_MAX, "%s/", configDir);
182 log.log("Main", Log::INFO, "TFTP path '%s'", tftpPath);
184 if (!tftpd.run(tftpPath))
186 log.log("Main", Log::CRIT, "Could not start TFTPd");
193 log.log("Main", Log::INFO, "Not starting TFTPd");
196 // Start mvprelay thread
201 log.log("Main", Log::CRIT, "Could not start MVPRelay");
207 log.log("Main", Log::INFO, "MVPRelay started");
212 log.log("Main", Log::INFO, "Not starting MVPRelay");
218 log.log("Main", Log::CRIT, "Could not start MVPServer thread");
223 log.log("Main", Log::DEBUG, "MVPServer run success");
227 void MVPServer::threadMethod()
229 // I want to die as soon as I am cancelled because I'll be in accept()
230 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
231 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
233 struct sockaddr_in address;
234 address.sin_family = AF_INET;
235 address.sin_port = htons(3024);
236 address.sin_addr.s_addr = INADDR_ANY;
237 socklen_t length = sizeof(address);
239 listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
240 if (listeningSocket < 0)
242 log.log("MVPServer", Log::CRIT, "Could not get TCP socket in vompserver");
247 setsockopt(listeningSocket,SOL_SOCKET,SO_REUSEADDR,&value,sizeof(value));
249 if (bind(listeningSocket,(struct sockaddr *)&address,sizeof(address)) < 0)
251 log.log("MVPServer", Log::CRIT, "Could not bind to socket in vompserver");
252 close(listeningSocket);
256 listen(listeningSocket, 5);
262 clientSocket = accept(listeningSocket,(struct sockaddr *)&address, &length);
263 VompClient* m = new VompClient(&config, configDir, clientSocket);