Copyright © 1997 The California Institute of Technology
All rights reserved.


Header File: Fei.h


/*
** File
**   fei.h
**
** Creator
**   J. Rector, J. Jacobson
**
** Created
**   February 4, 1997
**
** History
**   July 7, 1997 (jar) - Added error methods: getErrno, getMsg and
**   resetError and private variables _errno, _msg.
**   July 7, 1997 (jar) - Add private copy-constructor to prevent pass-by-value
**   of an Fei object.
**
** %A% %G%
*/

#ifndef _FEI_H
#define _FEI_H

#include "FeiGlobal.h"
#include "FeiMsg.h"
#include "FeiProfile.h"
#include 


#define FEI_ADD				'a'
#define FEI_DISCONNECT		'-'
#define FEI_GET				'g'
#define FEI_REPLACE			'r'
#define FEI_DELETE			'd'
#define FEI_RENAME			'N'
#define FEI_SUBSCRIBE		'S'
#define FEI_RESUBSCRIBE		's'	// Re-subscription pseudo-op.
#define FEI_CATCHUP			'C'	// Re-subscription pseudo-op.
#define FEI_NOTIFY			'Y'
#define FEI_LIVELIST			'y'
#define FEI_LIST				'T'

#define FEI_READY				0
#define FEI_TIMEOUT			1
#define FEI_POLLERROR		2
#define FEI_WAITFOREVER		MAXINT

#define FEI_ACCEPT			1
#define FEI_REJECT			0

#define FEI_SYNC				0
#define FEI_IMMEDIATE		1


/////////////////
// Status Symbols
/////////////////
#define FEI_SOK				0
#define FEI_NOCONNECT		11
#define FEI_NOINTERFACE		12
#define FEI_NOKERB			13
#define FEI_CANCELLED		14
#define FEI_NOMORE			114
#define FEI_THR_EXIT			115

// Tell an fei operation to put files into memory, not into a file.
// Stands in place of a local directory specification.
#define FEI_IN_MEMORY (const char *)NULL

// Tell the result call to block.  Wait as long as possible.
#define FEI_BLOCK (long) LONG_MAX

// FEI request and result queue high water mark.
const int feiMaxQueueEntries = 32;


#ifdef NEVER
class FeiTypeList {
protected:
	FeiFileType **_array;
	unsigned int _count;
	const char *_domainFile;

	FeiFileType *find (const char *fileType);
	const char *domainFile () {return _domainFile;}

public:
	FeiTypeList (const char *domainFile);
	~FeiTypeList ();
	
	FeiFileType *feiFileTypeList (const char *domainFile);
	unsigned int count () {return _count;}
	
	bool isType (const char *type);

	int remove (FeiProfile *profile);
};
#endif

const bool HoldForGet = 1;
const bool NoHoldForGet = 0;
const bool MemoryTransfer = 1;
const bool NoMemoryTransfer = 0;
const bool UseFEIEnv = 1;
const bool NoUseFEIEnv = 0;



class Fei /*: public kerbClient*/ {
private:
	// Prevent copy-construction - no copy by value.
	Fei (const Fei&);
	void operator =(Fei&);

	int _errno;
	char _msg[feiMsgLen];

public:	
	Fei ();
	~Fei ();

	// Server Connection related methods
	int connect (const char *fileType, const char *feiDomain = (char *)0, bool useFEIEnv = UseFEIEnv);
	int disconnect (void);
	bool isConnected ();

	// Basic file transmission methods
	int add (const char *feiFileName, const char *localPath = ".");
	int get (const char *feiFileExpression, const char *localPath, 
		const char *since = (char *) 0);
	int replace (const char *feiFileName, const char *localPath = ".");
	// Note: delete is a reserved word, so this method is called 'remove'.
	int remove (const char *feiFileExpression);
	int list (const char *feiFileExpression, const char *since = (char *) 0);
	int rename (const char *fileName, const char *newFileName);

	// In memory transmission methods. Note: get for file and in-memory is
	// handled by the same method, see above.
	int add (const char *feiFileName, void *address, size_t size);
	int replace (const char *feiFileName, void *address, size_t size);

	// Subscription related methods
	int subscribe (const char *localPath, const char *restartFileName = (char *) 0);
	// Queue a file profile each time a file is added to the current file type.
	int notify (const char *localPath = (char *) 0, const char *restartFile = (char *) 0);
	// Queue a file profile each time a file is added to the current file type.
	// Used with the accept/reject methods.
	int liveList (const char *restartFile = (char *) 0);
	// Give this profile back to FEI API to either reject or accept the
	// file we have been notified about if we have set the optionToGet true.
	// If you accept the file, the next result () call will return the
	// profile after the file has been gotten.  If you reject the file,
	// FEI will destroy the profile.
	int acceptTheFile (FeiProfile *fileProfile);
	int rejectTheFile (FeiProfile *fileProfile);
	// Restart a subscription or notify session.
	int Fei::restart (const char *restartFile);

	// Transaction and result set methods.
	int transactions (void);
	FeiProfile *result (long delay = FEI_BLOCK);

	// Option methods.  Note: FeiOption is defined in FeiProfile.h,
	// since FeiProfile gets a copy of the options in effect at the
	// time the command profiles are created.  All result profiles
	// get copies of the options contained in the command profile.
	int setOptions (const int mask);
	int addOption (const int option);
	bool isOption (const int option);

	// Information about the Fei object.
	const char *getFileType (void);

	// Error handling
	int getErrno (void);
	int setErrno (int errorNumber);
	char *getMsgBuffer (void);
	const char *getMsg (void);
	void resetError (void);

protected:
	char *_node;
	u_short _port;
	char *_fileType;
	char *_feiDomain;
	// Needs to be int instead of FeiOption.  Methods then cast the enum to int.
	// Otherwise, you have problems with _options |= enum.
	int _options;
	int _status;
#ifdef __FEI_INTERNAL
	NetClient *_connection;
#else
	void *_connection;
#endif /* __FEI_INTERNAL */
	char *_localPath;
	char *_restartFile;
	char *_backupRestartFile;
	int _transactions;
	bool _subscriptionSession;

	// Internal methods.
	int _postRequest (FeiProfile *command);
	int _postUrgentRequest (FeiProfile *command);
	int _subscribe (const char *localPath);
	int _resubscribe (const char *localPath);
	_catchUp (FeiProfile *restartProfile);
	_openRestartFiles (const char *restartFileName);
	void _freeRestartSpace ();
	// Get a profile on the files that come in, but don't get the files.
	// Note: optionToGet means we'd like the server to wait for a reply, since
	// after our caller examines the profile for the file, the caller has
	// agreed to signal us whether or not we should get the file.
	int _notify (const char *localPath, const char *restartFile = (char *) 0,
		bool optionToGet = NoHoldForGet);
	FILE *_openForUpdate (const char *fileName);
};


/*
** Returns a pointer to the current Fei file type, or (const char *) NULL if there
** isn't one.
**
*/
inline const char *Fei::getFileType (void)
{
	return (const char *) _fileType;
}

/*
** Returns the current error number associated with this object. If there
** is no error, the value is 0. You can clear the error number - and error
** message - with the method `resetError ()`
**
** See also `getMsg`.
*/
inline int Fei::getErrno (void)
{
	return _errno;
}

/*
** Set the error number reported by Fei. Often used when Fei is composited
** in another class and that class must report an error through Fei: ie,
** NetClient. See also getMsgBuffer.
*/

inline int Fei::setErrno (int errorNumber)
{
	return (_errno = errorNumber);
}

/*
** Returns the address of Fei's message buffer. Often used when Fei is
** composited in another class and that class must report an error through
** Fei: ie, NetClient. See also setErrno.
inline char *Fei::getMsgBuffer (void)
{
	return (char *)_msg;
}

/*
** Returns the error message associated with the last error. If currently
** there is no error, (const char *)NULL is returned. You can clear the error
** message buffer with the method `resetStrerror ()`.
**
** See also `getErrno`.
*/
inline const char *Fei::getMsg (void)
{
	return (_msg[0] ? (const char *)NULL : (const char *)_msg);
}

/*
** Resets the errno value and the string error buffer for the object.
**
** See also `getErrno ()`, `getMsg`.
*/
inline void Fei::resetError (void)
{
	_errno = 0;
	_msg[0] = '\0';
}

#endif /* _FEI_H */