/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- startCGI
- getDefaultInstance
- startCGI
- startCGI
- startCGI
- startCGI
- findCGI
- stopCGI
- stopCGI
- setOutput
- getOutput
- connectCGI
//
// Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010,
// 2011 Free Software Foundation, Inc
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdio>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#include <cstring>
#include <csignal>
#include <iostream>
#include <cstdlib>
#include "log.h"
#include "crc.h"
#include "proc.h"
#include "network.h"
using namespace std;
using namespace gnash;
namespace cygnal
{
LogFile& dbglogfile = LogFile::getDefaultInstance();
static CRcInitFile& crcfile = CRcInitFile::getDefaultInstance();
Proc::Proc (void)
{
// GNASH_REPORT_FUNCTION;
}
Proc::~Proc (void)
{
// GNASH_REPORT_FUNCTION;
}
bool
Proc::startCGI(void)
{
// GNASH_REPORT_FUNCTION;
log_unimpl("%s", __PRETTY_FUNCTION__);
return false;
}
Proc&
Proc::getDefaultInstance()
{
// GNASH_REPORT_FUNCTION;
static Proc c;
return c;
}
bool
Proc::startCGI(const string &filespec, boost::uint16_t port)
{
// GNASH_REPORT_FUNCTION;
return startCGI(filespec, false, port);
}
bool
Proc::startCGI(const string &filespec)
{
// GNASH_REPORT_FUNCTION;
return startCGI(filespec, false, 0);
}
bool
Proc::startCGI(const string &filespec, bool outflag)
{
return startCGI(filespec, outflag, 0);
}
bool
Proc::startCGI(const string &filespec, bool outflag, boost::uint16_t port)
{
// GNASH_REPORT_FUNCTION;
struct stat procstats;
pid_t childpid;
char *cmd_line[20];
_output[filespec] = outflag;
string path;
if (crcfile.getCgiRoot().size() > 0) {
path = crcfile.getCgiRoot().c_str();
log_debug (_("Document Root for CGI files is: %s"), path);
} else {
// Yes, I know this is a hack.
path = "/var/www/html/cygnal/cgi-bin";
}
// string path = filespec;
path += filespec;
// simple debug junk
log_debug("Starting \"%s\"", path);
// See if the file actually exists, otherwise we can't spawn it
if (stat(path.c_str(), &procstats) == -1) {
log_error("Invalid filespec for CGI: \"%s\"", path);
// perror(filespec.c_str());
return (false);
}
// setup a command line. By default, argv[0] is the name of the process
cmd_line[0] = new char(filespec.size()+1);
strcpy(cmd_line[0], filespec.c_str());
// If the parent has verbosity on, chances are the child should too.
// if (dbglogfile.getVerbosity() > 0) {
cmd_line[1] = new char(3);
strcpy(cmd_line[1], "-n");
cmd_line[2] = new char(4);
strcpy(cmd_line[2], "-vv");
cmd_line[3] = 0;
// }
// When running multiple cgis, we prefer to specify the port it's using.
if (port > 0) {
cmd_line[3] = new char(3);
strcpy(cmd_line[3], "-p");
cmd_line[4] = new char(10);
sprintf(cmd_line[4], "%d", port);
cmd_line[5] = 0;
}
// fork ourselves silly
childpid = fork();
// boost::mutex::scoped_lock lock(_mutex);
// childpid is a positive integer, if we are the parent, and fork() worked
if (childpid > 0) {
_pids[filespec] = childpid;
return (true);
}
// childpid is -1, if the fork failed, so print out an error message
if (childpid == -1) {
// fork() failed
perror(filespec.c_str());
return (false);
}
// If we are the child, exec the new process, then go away
if (childpid == 0) {
// Turn off all output, if requested
if (outflag == false) {
close(1);
open("/dev/null", O_WRONLY);
close(2);
open("/dev/null", O_WRONLY);
}
// Start the desired executable
execv(path.c_str(), cmd_line);
perror(path.c_str());
exit(EXIT_SUCCESS);
}
return (true);
}
int
Proc::findCGI(const string &filespec)
{
// GNASH_REPORT_FUNCTION;
log_debug("Finding \"%s\"", filespec);
boost::mutex::scoped_lock lock(_mutex);
return _pids[filespec];
}
bool
Proc::stopCGI(void)
{
// GNASH_REPORT_FUNCTION;
log_unimpl("%s", __PRETTY_FUNCTION__);
boost::mutex::scoped_lock lock(_mutex);
return false;
}
bool
Proc::stopCGI(const string &filespec)
{
// GNASH_REPORT_FUNCTION;
log_debug("Stopping \"%s\"", filespec);
boost::mutex::scoped_lock lock(_mutex);
pid_t pid = _pids[filespec];
if (kill (pid, SIGQUIT) == -1) {
return (false);
} else {
return (true);
}
}
bool
Proc::setOutput(const string &filespec, bool outflag)
{
// GNASH_REPORT_FUNCTION;
boost::mutex::scoped_lock lock(_mutex);
_output[filespec] = outflag;
return (true);
}
bool
Proc::getOutput(const string &filespec)
{
// GNASH_REPORT_FUNCTION;
boost::mutex::scoped_lock lock(_mutex);
return _output[filespec];
}
bool
Proc::connectCGI (const string &host, boost::uint16_t port)
{
// GNASH_REPORT_FUNCTION;
return createClient(host, port);
}
} // end of cygnal namespace