#include <QCoreApplication>
#include <getopt.h>
#include <stdlib.h>
#include "pvs.h"
#include "src/net/pvsLocalhostCommunicator.h"
#include "setup.h"
#include "src/net/pvsMsg.h"
#include "src/core/pvsChatClient.h"
PVS *mainClient = NULL;
QTextStream qout(stdout);
/// VERSION_STRING is defined in src/version.h
void printVersion(bool doExit)
{
QTextStream qout(stdout);
printf("Version:\t"VERSION_STRING"\n");
if (doExit)
exit(0);
}
/// outputs the full help text
void printHelp()
{
qout << "**************************************************************\n";
qout << "Pool Video Switch Client\n";
qout << "**************************************************************\n";
qout << QObject::tr("Version: ") << VERSION_STRING << "\n";
qout << "**************************************************************\n";
qout << QObject::tr("Usage:") << "\tpoolVSClient " << QObject::tr("<<option> <value>, ... >") << "\n\n";
qout << QObject::tr("Options:") << "\n\n";
qout << QObject::tr("-vncScriptFile <fullpath\\filename>") << "\n\t" << QObject::tr("Specifies a custom location for the vnc-start/stop-script.")<< "\n\t" << QObject::tr("If not specified, /usr/bin/pvs-vncsrv is expected.") << "\n\n";
qout << QObject::tr("-freq <seconds>") << "\n\t" << QObject::tr("Specifies how long to wait until a reconnection attempt is made.") << "\n\t" << QObject::tr("Default is 5.") << "\n\n";
qout << QObject::tr("-port <port>") << "\n\t" << QObject::tr("Specifies on which port to run.") << "\n\t" << QObject::tr("Default is ") << SERVER_PORT_INT << ".\n\n";
qout << QObject::tr("-h or --help") << "\n\t" << QObject::tr("Shows this help text and exits.") << "\n\n";
qout << QObject::tr("-v or --version") << "\n\t" << QObject::tr("Shows the current version and exits.") << "\n";
qout << QObject::tr("-d or --daemon") << "\n\t" << QObject::tr("Start as daemon.") << "\n";
qout << QObject::tr("-c <string command>:<string value>") << "\n\t" << QObject::tr("Sends the command and the optional value to a running PVS-Client.") << "\n\t" << QObject::tr("Command and value may not contain spaces or colons.") << "\n\t" << QObject::tr("The dividing colon is mandatory.") << "\n";
qout << "-commands: \n\t" << QObject::tr("Prints out available commands to use with -c.") << "\n";
qout << "**************************************************************\n";
qout.flush();
exit(0);
}
/// outputs a brief help text
void printNotice()
{
qout << QObject::tr("Use -h or --help to get a listing of all options.\n-v or --version gives you the current version.\n\n");
qout.flush();
}
void printCommands()
{
printf("**************************************************************\n");
printf("chat:<on/ off/ 1/ 2/ 3>\n ");
printf("on = turns that chat option on\n off = turns the chat option off\n 1 = bossmode\n 2 = community\n 3 = private\n");
printf("stop \n\t Stops the running PVS-Client.\n");
printf("**************************************************************\n");
exit(0);
}
///
int main(int argc, char** argv)
{
bool daemon = false;
int frequency = 5;
int port = -1;
QCoreApplication app(argc, argv);
app.setOrganizationName("openslx");
app.setOrganizationDomain("openslx.org");
app.setApplicationName("pvs");
// use system locale as language to translate gui
QTranslator translator;
translator.load(":pvs");
app.installTranslator(&translator);
QFileInfo script;
#ifdef __WIN32__
//TODO Win32
if (!script.exists())
script.setFile(getHomeDir() + "/.pvs/pvs-vncsrv_win32.bat");
#else
QSettings settings;
if (!QFile::exists(settings.fileName()))
{
QDir::root().mkpath(QFileInfo(settings.fileName()).path());
QFile::copy("/etc/openslx/pvs.conf", settings.fileName());
}
QString s = settings.value("VNC/script").toString();
script.setFile(s);
if (!script.exists())
script.setFile("/usr/bin/pvs-vncsrv");
if (!script.exists())
script.setFile("/usr/local/bin/pvs-vncsrv");
if (!script.exists())
script.setFile(getHomeDir() + "/.pvs/pvs-vncsrv");
#endif //__WIN32__
PVSLocalhostCommunicator com(getPolicyFilePath(QString(
".comfile")));
com.run();
if (!(com.running()))
{
printf("Error. UDS Communicator is not running. Exiting.\n");
exit(0);
}
int option_index = 0;
while (1)
{
static struct option long_options[] =
{
{ "help", no_argument, 0, 'h' },
{ "commands", no_argument, 0, 'o' },
{ "version", no_argument, 0, 'v' },
{ "daemon", no_argument, 0, 'd' },
{ "port", required_argument, 0, 'p' },
{ "freq", required_argument, 0, 'f' },
{ "client", required_argument, 0, 'e' },
{ "script", required_argument, 0, 's' },
{ 0, 0, 0, 0 },
};
/* getopt_long stores the option index here. */
int c = getopt_long(argc, argv, "hovdc:f:e:s:p:", long_options,
&option_index);
option_index++;
if (c == -1)
break;
switch (c)
{
case 'h':
printHelp();
break;
case 'o':
printCommands();
break;
case 'v':
printVersion(true);
break;
case 'd':
daemon = true;
break;
case 'c':
{
if (option_index + 1 < argc)
{
if (com.server())
{
// wont work, no daemon running
printf("Error. No running PVS-Client found. Exiting.\n");
com.stop();
}
else
{
printf("Will send i: %s, m: %s\n", argv[option_index + 1], "");
com.sendCommand(QString(argv[option_index + 1]), "");
QCoreApplication::processEvents(QEventLoop::AllEvents);
printf("Sent command. Exiting.\n");
}
}
else
{
printf("Error. No command issued. Exiting.\n");
}
exit(0); // and gone
}
case 'f':
{
if (option_index + 1 < argc)
{
frequency = atoi(argv[option_index + 1]);
if (frequency <= 0)
{
frequency = 5; // return to standard
ConsoleLog writeError(QString(
"malformed frequency, setting standard = 5"));
printNotice();
}
else
ConsoleLog writeLine(QString("Using frequency ").append(
int2String(frequency)));
option_index++;
continue;
}
break;
}
case 'p':
{
if (option_index + 1 < argc)
{
port = atoi(argv[option_index + 1]);
if (port <= 0)
{
ConsoleLog writeTerminal(QString("port maybe malformed"));
printNotice();
port = -1; // return to standard
}
else
ConsoleLog writeTerminal(QString("Using port ").append(
int2String(port)));
option_index++;
continue;
}
break;
}
case 'e':
{
if (option_index + 1 < argc)
{
printf("WARNING: -e is deprecated\n");
option_index++;
continue;
}
break;
}
case 's':
{
if (option_index + 1 < argc)
{
script.setFile(QString(argv[option_index + 1]));
option_index++;
continue;
}
break;
}
case '?':
{
ConsoleLog writeError(
QString("Unrecognized option/paramter: ").append(
argv[option_index]));
printNotice();
}
default:
abort();
}
//else
// printNotice();
}
if (!com.server())
{
printf("Error. PoolVSClient already running. Exiting\n");
com.stop();
exit(0);
}
ConsoleLog setLogName(QString("log.client"));
ConsoleLog writeLine(QString("PVS-Client started."));
if (daemon)
{
#ifndef __WIN32__
pid_t pid, sid; // our process ID and session ID
// fork off the parent process
pid = fork();
if (pid < 0)
exit(-1);
// if we got a good PID, then we can exit the parent process.
if (pid > 0)
exit(0);
// change the file mode mask
umask(0);
// create a new SID for the child process
sid = setsid();
if (sid < 0)
exit(-1);
// change the current working directory
if ((chdir("/")) < 0)
exit(-1);
// close out the standard file descriptors
close(STDIN_FILENO);
freopen ((QString(getHomeDir()).append(QString("/.pvs/dump"))).toUtf8()
.data(),"w",stdout);
//close(STDOUT_FILENO);
close(STDERR_FILENO);
#endif /*__WIN32__*/
}
mainClient = new PVS();
com.getDispatcher()->addListener("*", mainClient, &PVS::onDaemonCommand);
if (port <= 0)
port = SERVER_PORT_INT;
ConsoleLog writeLine(QString("TCP-Port: ").append(int2String(port)));
mainClient->setScriptPath(script.filePath());
ConsoleLog writeLine(QString("VNCScriptPath: ").append(script.filePath()));
createPolicyDir();
createPolicyFiles();
return app.exec();
}