client.h #1

  • //
  • guest/
  • perforce_software/
  • p4/
  • 2014.2/
  • client/
  • client.h
  • View
  • Commits
  • Open Download .zip Download (11 KB)
/*
 * Copyright 1995, 1996 Perforce Software.  All rights reserved.
 *
 * This file is part of Perforce - the FAST SCM System.
 */

/*
 * Client - the Perforce client, implemented as an RPC service
 *
 * Basic flow:
 *
 *	ClientUser ui;
 *	Client client;
 *
 *	client.SetProtocol( "gui", "1" ); // optional
 *	client.Dispatcher( &dispatchTable ); // optional
 *
 *	// SetPort() must happen _before_ the Init().
 *
 *	client.SetPort( somefunctionof( client.GetPort() ) ); //optional
 *
 *	client.Init( e );
 *
 *	// GetClient() must happen _after_ the Init().
 *
 *	client.SetClient( somefunctionof( client.GetClient() ) ); //optional
 *	client.SetCwd( somefunctionof( client.GetCwd() ) ); //optional
 *	client.SetUser( somefunctionof( client.GetUser() ) ); //optional
 *
 *	while( !client.Dropped() )
 *	{
 *	    client.SetArgv( argc, argv )
 *	    client.Run( func, &ui )
 *	}
 *
 *	return client.Final( e );
 *
 * Public methods:
 *
 *	Client::Init() - establish connection and prepare to run commands.
 *
 *	Client::Run() - run a single command, assuming arguments have
 *		already been set up.
 *
 *	Client::RunTag() - run a single command (potentially) asynchronously.
 *
 *	Client::WaitTag() - wait for a RunTag()/all RunTag()s to complete.
 *
 *	Client::Final() - clean up end of connection, returning error count.
 *
 *	Client::Dispatcher() - just a shortcut to the service dispatcher.
 *
 *	Client::SetProtocol() - just a shortcut to the service SetProtocol.
 *
 *	Client::SetCharset()
 *	Client::SetClient()
 *	Client::SetCwd()
 *	Client::SetHost()
 *	Client::SetLanguage()
 *	Client::SetPassword()
 *	Client::SetPort()
 *	Client::SetUser() - set current directory, client, host, port, or 
 *		user, overridding all defaults.  SetPort() must be called 
 *		before Init() in order to take effect.  The others must be 
 *		set before Run() to take effect.
 *
 *		SetCwd() additionally searches for a new P4CONFIG file.
 *
 *	Client::DefineCharset()
 *	Client::DefineClient()
 *	Client::DefineHost()
 *	Client::DefineLanguage()
 *	Client::DefinePassword()
 *	Client::DefinePort()
 *	Client::DefineUser() - sets client, port, or user in the registry
 *		and (so as to take permanent effect) then calls SetClient(),
 *		etc. to take immediate effect.
 *
 *	Client::GetBuild()
 *	Client::GetCharset()
 *	Client::GetClient()
 *	Client::GetCwd()
 *	Client::GetHost()
 *	Client::GetLanague()
 *	Client::GetOs()
 *	Client::GetPassword()
 *	Client::GetPort()
 *	Client::GetUser() - get current directory, client, OS, port or user,
 *		as determined by defaults or by corresponding set value.
 *		GetClient()/GetHost() are not valid until after Init() 
 *		establishes the connection, because the hostname of the 
 *		local endpoint may serve as the default client name.
 *
 *	Client::GetConfig() - get the filename pointed to by P4CONFIG, as
 *		determined by enviro::Config().
 *
 *	Client::GetEnv() - set the cwd/client/host/os/user variables (using
 *		Rpc::SetVar() call).  These variables are needed by just
 *		about all calls (via Rpc::Invoke()) to the server.
 *
 *	Client::Confirm() - copy all recv vars to send vars, excluding 
 *		'data' and 'func', and Invoke() the named func.
 *
 *	Client::SetError() - bumps an error counter, whose value is 
 *		returned by GetErrors().  Used by OutputError() to
 *		track any errors returned by the server.
 *
 *	Client::GetErrors() - returns error count of times OutputError()
 *		has been called, so that the client's main routine can
 *		exit non-zero if errors occurred.
 *
 *	Client::OutputError() - a gentle way of reporting an error, rather
 *		than having to blurted out by Rpc::Dispatch().
 */

const int ClientTags = 4; // max pending RunTags()

class ClientUser;
class CharSetCvt;
class Ignore;
class Enviro;

enum EnvVarType
{
	VAR_P4USER =	0x0001,   // P4USER
	VAR_P4CLIENT =	0x0002,   // P4CLIENT
	VAR_P4PORT =	0x0004,   // P4PORT
	VAR_P4PASSWD =	0x0008    // P4PASSWD
} ;

class Client : public Rpc {

    public:
	// caller's main interface

			Client();
			~Client();

	void		SetTrans( int output, int content = -2,
				int fnames = -2, int dialog = -2 );
	int		GuessCharset();
	int		ContentCharset();

	void		Init( Error *e );
	void		Run( const char *func, ClientUser *ui );
	int		Final( Error *e );

	// alternative async Run() interface

	void		RunTag( const char *func, ClientUser *ui );
	void		WaitTag( ClientUser *ui = 0 );

	void		SetArgv(int ac, char * const * av);

    public:
	// for fine tuning caller's use

	void		SetCharset( const StrPtr *c ) { charset.Set( c ); }
	void		SetClient( const StrPtr *c ) { client.Set( c ); }
	void		SetClientPath( const StrPtr *c )
	                { clientPath.Set( c ); }
	void		SetCwd( const StrPtr *c );
	void		SetCwdNoReload( const StrPtr *c ) { cwd.Set( c ); }
	void		SetHost( const StrPtr *c ) { host.Set( c ); }
	void		SetIgnoreFile( const StrPtr *c ) { ignorefile.Set( c ); }
	void		SetLanguage( const StrPtr *c ) { language.Set( c ); }
	void		SetPort( const StrPtr *c ) { port.Set( c ); }
	void		SetProg( const StrPtr *c );
	void		SetVersion( const StrPtr *c );

	void		SetPassword( const StrPtr *c )
	    { password.Set( c ); ticketKey.Clear(); authenticated = 0; }

	void		SetUser( const StrPtr *c ) 
			{ user.Set( c ); authenticated = 0; }

	void		SetTicketFile( const StrPtr *c )
			{ ticketfile.Set( c ); }

	void		SetTrustFile( const StrPtr *c ) { trustfile.Set( c ); }
	void		SetEnviroFile( const StrPtr *c )
	    { if( c ) SetEnviroFile( c->Text() ); }

	void		SetCharset( const char *c ) { charset.Set( c ); }
	void		SetClient( const char *c ) { client.Set( c ); }
	void		SetCwd( const char *c );
	void		SetCwdNoReload( const char *c ) { cwd.Set( c ); }
	void		SetHost( const char *c ) { host.Set( c ); }
	void		SetIgnoreFile( const char *c ) { ignorefile.Set( c ); }
	void		SetLanguage( const char *c ) { language.Set( c ); }
	void		SetPort( const char *c ) { port.Set( c ); }
	void		SetProg( const char *c );
	void		SetVersion( const char *c );
	void		SetExecutable( const char *c ) { exeName.Set( c ); }

	void		SetPassword( const char *c ) 
	    { password.Set( c ); ticketKey.Clear(); authenticated = 0; }

	void		SetUser( const char *c ) 
			{ user.Set( c ); authenticated = 0; }

	void		SetTicketFile( const char *c )
			{ ticketfile.Set( c ); }

	void		SetTrustFile( const char *c ) { trustfile.Set( c ); }

	void		SetEnviroFile( const char *c );

	void		SetServerID( const char *c )
	                { serverID.Set( c ); }

	void		DefineCharset( const char *c, Error *e );
	void		DefineClient( const char *c, Error *e );
	void		DefineHost( const char *c, Error *e );
	void		DefineIgnoreFile( const char *c, Error *e );
	void		DefineLanguage( const char *c, Error *e );
	void		DefinePassword( const char *c, Error *e );
	void		DefinePort( const char *c, Error *e );
	void		DefineUser( const char *c, Error *e );

	const StrPtr	&GetCharset();
	const StrPtr	&GetClient();
	const StrPtr	&GetClientNoHost();
	const StrPtr	&GetClientPath();
	const StrPtr	&GetCwd();
	const StrPtr	&GetHost();
	const StrPtr	&GetLanguage();
	const StrPtr	&GetOs();
	const StrPtr	&GetPassword();
	const StrPtr	&GetPassword2();
	const StrPtr	&GetPort();
	const StrPtr	&GetUser();
	const StrPtr	&GetTicketFile();
	const StrPtr	&GetTrustFile();
	const StrPtr	&GetConfig();
	const StrPtr	&GetLoginSSO();
	const StrPtr	&GetSyncTrigger();
	const StrPtr	&GetIgnoreFile();
	const StrPtr	&GetBuild() { return buildInfo; }
	const StrPtr	&GetExecutable() { return exeName; }

	void		SetIgnorePassword() 
			{ ignoreList |= VAR_P4PASSWD; }

	int		IsIgnorePassword()
			{ return ( ignoreList & VAR_P4PASSWD ); }

	void		SetProtocol( const char *p, const char *v )
			{ service.SetProtocol( p, v ); }

	void		SetProtocol( const char *p )
			{ service.SetProtocol( p ); }

	void		SetProtocolV( const char *arg )
			{ service.SetProtocolV( arg ); }

	void		Dispatcher( RpcDispatch *d )
			{ service.Dispatcher( d ); }

    public:
	// for use by the client service implementation

	void		GetEnv();
	Enviro*		GetEnviro() { return enviro; }
	const StrPtr *	GetEnviroFile();
	Ignore*		GetIgnore() { return ignore; }
	void		Confirm( const StrPtr *confirm );
	ClientUser *	GetUi() { return tags[ lowerTag ]; }

	void		SetError() { errors++; }
	int		GetErrors() { return errors; }
	void		SetFatal() { fatals++; }
	int		GetFatals() { return fatals; }
	
	void		OutputError( Error *e );

	Handlers	handles;

	void		NewHandler();
	CharSetCvt	*fromTransDialog, *toTransDialog;
        StrDict		*translated, *transfname;
	int		unknownUnicode;
	int		content_charset; // file content charset
	int		output_charset;  // result output charset
 
	void		VSetVar( const StrPtr &var, const StrPtr &val );

	int		protocolXfiles;	// 'xfiles' protocol
	int		protocolNocase;	// 'nocase' protocol
	int		protocolSecurity;  // server 'security' protocol
	int		protocolUnicode;	// server 'unicode' protocol

        StrPtr *	GetProtocol( const StrPtr &var );

	void		SetSecretKey( StrPtr &s ) { secretKey.Set( s ); }
	void		ClearSecretKey() { secretKey.Clear(); }
	StrPtr *	GetSecretKey() { return( &secretKey ); }
	void		SetPBuf( StrPtr &s ) { pBuf.Set( s ); }
	void		ClearPBuf() { pBuf.Clear(); }
	StrPtr *	GetPBuf() { return( &pBuf ); }

	void		SetTicketKey( const StrPtr *s ) { ticketKey.Set( *s ); }

        int             IsUnicode() { return is_unicode; }

    public:
	// Old closure stuff, only used by scc api and to be retired

	void		*GetClosure() { return closure; }
	void		SetClosure( void *v ) { closure = v; }
	void		*closure;

    protected:
	virtual RpcType	GetRpcType()
	{
	    return RPC_CLIENT;
	}

    private:
	ClientUser	*tags[ClientTags];
	int		lowerTag;
	int		upperTag;
	int		authenticated;
	int		pubKeyChecked;

	RpcService	service;
	int		errors;
	int		fatals;

	StrBuf		charset;	// character set
	StrBuf		client;		// client's name
	StrBuf		clientPath;	// Authorized areas of the filesystem
	StrBuf		cwd;		// current directory
	StrBuf		host;		// client host name
	StrBuf		os;		// client's OS
	StrBuf		programName;	// (optionally) set by SetProg()
	StrBuf		port;		// server address (P4PORT)
	StrBuf		serverID;	// server address (ID from server)
	StrBuf		user;		// user's name
	StrBuf		password;	// user's password
	StrBuf		password2;	// user's password (password is ticket)
	StrBuf		ticketKey;	// key used to look up ticket
	StrBuf		language;	// language for err messages
	StrBuf		ticketfile;	// alternate location for ticketfile
	StrBuf		trustfile;	// trusted finger print file
	StrBuf		secretKey;	// for salting password key
	StrBuf		pBuf;		// for salting password key
	StrBuf		loginSSO;	// single signon binary
	StrBuf		syncTrigger;	// sync trigger binary
	StrBuf		ignorefile;	// ignore filename
	StrBuf		exeName;
	StrBuf		charsetVar;
	StrRef		buildInfo;

	Enviro		*enviro;	// environment vars
	Ignore		*ignore;	// naughty list
	int      	ignoreList;	// environment vars to ignore
	int		is_unicode;	// talking in unicode mode
	int		hostprotoset;

	StrNum		protocolBuf;	// for our GetProtocol

	void		CleanupTrans();	// free translators
	void		SetupUnicode( Error * );
	void		LearnUnicode( Error * );
	void		LateUnicodeSetup( const char *, Error * );
} ;
# Change User Description Committed
#2 15901 Matt Attaway Clean up code to fit modern Workshop naming standards
#1 12189 Matt Attaway Initial (and much belated) drop of 2014.2 p4 source code