/*******************************************************************************
* Copyright (c) 2007, Perforce Software, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE
* SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*******************************************************************************/
#ifndef SERVER_H
# define SERVER_H
enum
{
CHECK_STOPPED,
CHECK_STARTED,
CHECK_DENIED,
CHECK_DENIED_ROOT,
CHECK_FAILED,
CHECK_GRANTED,
};
enum
{
SERVER_NONE = 0,
SERVER_P4D = 0x0001,
SERVER_P4P = 0x0002,
SERVER_P4WEB = 0x0004,
SERVER_P4FTP = 0x0008,
SERVER_P4BROKER = 0x0010,
SERVER_P4DTG = 0x0020,
SERVER_OTHER = 0x0080,
SERVER_ALL = 0x00BF,
SERVER_LISTENS = 0x0013,
};
#ifdef __cplusplus
class Config;
class VarList;
class Server
{
public:
Server( const char *name, int type,
VarList *settings, VarList *env,
const Config *config );
virtual ~Server();
//
// Get the server's name
//
const StrPtr & Name() { return name; }
//
// Get the owner's uid
//
uid_t OwnerUid() { return owner_uid; }
//
// Get the Owner's name
//
StrPtr * Owner() { return &owner; }
//
// Get the name for servers of this type
//
StrPtr & Label() { return label; }
//
// Get the type id for this server
//
int Type() { return type; }
//
// Check if this server is of a given type
//
int KindOf( int t ) { return t & type; }
//
// Check the server's configuration
//
virtual int IsValid( Error *e, int full=1 );
//
// Merge a VarList of settings into this server's config,
// without overriding any local settings
//
void MergeSettings( VarList *s );
//
// Check that the current user has the right to work with
// this server
//
int CheckAccess( Error *e );
//
// Exec the binary to start the server. Returns non-zero if the
// server is started
//
virtual int Start( StrPtr extraArgs, Error *e );
//
// Shut down the running server. Returns non-zero on error
//
virtual int Stop( Error *e );
//
// Check whether or not the server is running. Returns non-zero
// if the server is alive.
//
virtual int Running( Error *e );
//
// Extra text to show in listings for this server type
//
virtual void ExtraText( StrBuf &extra ) {};
//
// Returns true if the server is enabled
//
int Enabled() { return enabled; }
//
// Test if this server uses SSL
//
virtual int SSLEnabled() { return 0; }
//
// Direct access to the server's environment. Returns
// NULL if var is not defined.
//
StrPtr * GetVar( StrPtr &var );
//
// Debugging
//
virtual void Dump();
protected:
//
// Compute the pid file for this server
//
void PidFile( StrBuf &buf );
//
// Write pid file
//
void SavePid( pid_t pid, Error *e );
//
// Load pid from file
//
pid_t LoadPid( Error *e );
//
// Remove pid file
//
void CleanPid();
//
// Load the user's data from the passwd file
//
void LoadUserData( Error *e );
//
// Create a child process running as the server's owner, optionally
// making the child a daemon by detaching from the controlling terminal
// etc. Returns 0 to the child, -1 on fork() failure, and the pid of
// the child to the parent. The child process's environment is set
// up using the global variables and the server-specific variables.
//
pid_t CreateChild( int daemon, int quiet, Error *e );
//
// Run a command in a subprocess optionally waiting for it
// to complete.
//
int RunCommand( const char *cmd, CmdLine *args, pid_t &pid,
int daemon, int silent, Error *e );
//
// Run a Perforce command using our API
//
int RunP4Command( const char *cmd, CmdLine &args, Error *e);
//
// Set the process name for the server
//
virtual void SetProcessName( StrBuf &procName ) = 0;
//
// Extract command line args for a server
//
void ExtractArgs( CmdLine &cmdline );
//
// Check that a path exists and is a directory
//
int CheckDirectory( StrPtr *d, Error *e );
//
// Check that a service owner exists
//
int CheckOwner( StrPtr &o, Error *e );
//
// Update internal config from settings
//
virtual void UpdateFromSettings();
//
// Debug level
//
int Debug();
protected:
StrBuf name;
StrBuf label;
StrBuf binary;
StrBuf args;
StrBuf owner;
StrBuf owner_home;
StrBuf owner_shell;
uid_t owner_uid;
uid_t owner_gid;
VarList * env;
VarList * settings;
int umask;
int type;
int enabled;
const Config * global_config;
VarArray * childEnv;
};
//
// Subclass for things that are specific to P4D servers
//
class P4D : public Server
{
public:
P4D( const char *name, VarList *settings, VarList *env, const Config *config );
virtual int IsValid( Error *e, int full=1 );
virtual int Stop( Error *e );
virtual int Running( Error *e );
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
virtual int SSLEnabled();
void Checkpoint( int compress, Error *e );
void RotateJournal( int compress, Error *e );
protected:
virtual void UpdateFromSettings();
private:
void RunP4Info( Error *e );
void RunP4AdminStop( Error *e );
StrBuf prefix;
};
//
// Subclass for things that are specific to Proxy servers
//
class P4P : public Server
{
public:
P4P( const char *name, VarList *settings, VarList *env, const Config *config )
: Server( name, SERVER_P4P, settings, env, config )
{
label = "p4p";
}
virtual int IsValid( Error *e, int full=1 );
virtual int Running( Error *e );
virtual int SSLEnabled();
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
};
//
// Subclass for things that are specific to P4Web Servers
//
class P4Web : public Server
{
public:
P4Web( const char *name, VarList *settings, VarList *env, const Config *config )
: Server( name, SERVER_P4WEB, settings, env, config )
{
label = "p4web";
}
virtual int IsValid( Error *e, int full=1 );
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
};
//
// Subclass for things that are specific to P4FTP Servers
//
class P4Ftp : public Server
{
public:
P4Ftp( const char *name, VarList *settings, VarList *env, const Config *config )
: Server( name, SERVER_P4FTP, settings, env, config )
{
label = "p4ftpd";
}
virtual int Start( StrPtr extraArgs, Error *e );
virtual int IsValid( Error *e, int full=1 );
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
};
//
// Subclass for things that are specific to Brokers
//
class P4Broker : public Server
{
public:
P4Broker( const char *name, VarList *settings, VarList *env, const Config *config )
: Server( name, SERVER_P4BROKER, settings, env, config )
{
label = "p4broker";
}
virtual int IsValid( Error *e, int full=1 );
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
};
//
// Subclass for things that are specific to the P4DTG
//
class P4Dtg : public Server
{
public:
P4Dtg( const char *name, VarList *settings, VarList *env, const Config *config )
: Server( name, SERVER_P4DTG, settings, env, config )
{
label = "p4dtg";
}
virtual int Start( StrPtr extraArgs, Error *e );
virtual int Stop( Error *e );
virtual int IsValid( Error *e, int full=1 );
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
};
//
// Subclass for starting arbitrary processes within our framework
//
class OtherServer : public Server
{
public:
OtherServer( const char *name, VarList *settings, VarList *env, const Config *config );
virtual int IsValid( Error *e, int full=1 );
virtual void SetProcessName( StrBuf &procName );
virtual void ExtraText( StrBuf &extra );
protected:
virtual void UpdateFromSettings();
private:
StrBuf port;
};
#endif /* __cplusplus */
#endif