/**
 * @file libcomprex/fsnode.h Filesystem node structures
 * 
 * $Id: fsnode.h,v 1.8 2003/01/01 06:22:36 chipx86 Exp $
 *
 * @Copyright (C) 2001-2003 The GNUpdate Project.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */
#ifndef _LIBCOMPREX_FSNODE_H_
#define _LIBCOMPREX_FSNODE_H_

#include <sys/types.h>
#include <time.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _CxFsNode     CxFsNode;     /**< A filesystem node. */
typedef enum   _CxFsNodeType CxFsNodeType; /**< A type of node. */

#include <libcomprex/archive.h>
#include <libcomprex/directory.h>
#include <libcomprex/file.h>
#include <libcomprex/types.h>

/**
 * A type of filesystem node.
 */
enum _CxFsNodeType
{
	CX_FSNODETYPE_UNKNOWN = 0, /**< Unknown node type. */
	CX_FSNODETYPE_FILE,        /**< A single file.     */
	CX_FSNODETYPE_DIRECTORY,   /**< A directory.       */
};

/**
 * @struct _CxFsNode fsnode.h libcomprex/fsnode.h
 *
 * A representation of a file or directory on the filesystem or
 * in an archive.
 */
struct _CxFsNode
{
	CxArchive *archive;      /**< The archive that owns this node, if any. */
	CxDirectory *parentDir;  /**< The parent directory.                    */

	char *name;              /**< The base filename or directory name.     */

	CxFsNodeType type;       /**< The type of node.                        */

	/**
	 * The full path to the node. This may include a non-physical path
	 * (FTP site, archive, etc.) in the path.
	 */
	char *path;

	mode_t mode;           /**< The node's mode.                        */
	uid_t  uid;            /**< The node's owner user ID.               */
	gid_t  gid;            /**< The node's owner group ID.              */

	time_t date;           /**< The time in seconds since the epoch.    */

	char isLocal;          /**< Non-zero if the node is stored locally. */

	/**
	 * File or directory-specific information.
	 */
	union
	{
		CxFileData      *file; /**< File-specific information.      */
		CxDirectoryData *dir;  /**< Directory-specific information. */

	} u;

	void *moduleData;         /**< Module-specific data.          */

	unsigned int refCount;    /**< The reference count.           */

	CxFsNode *prev;           /**< The previous node in the list. */
	CxFsNode *next;           /**< The next node in the list.     */
};

/**************************************************************************/
/** @name Structure (De)allocation Functions                              */
/**************************************************************************/
/*@{*/

/**
 * Creates a new CxFsNode structure.
 *
 * @return A new, empty CxFsNode structure.
 *
 * @see cxDestroyFsNode()
 */
CxFsNode *cxNewFsNode(void);

/**
 * Destroys a CxFsNode structure.
 *
 * @param node The CxFsNode to destroy.
 *
 * @see cxNewFsNode()
 */
void cxDestroyFsNode(CxFsNode *node);

/*@}*/

/**************************************************************************/
/** @name Attribute Modification Functions                                */
/**************************************************************************/
/*@{*/

/**
 * Sets the archive that owns the node.
 *
 * This should only be used by libcomprex.
 *
 * @param node    The node.
 * @param archive The archive that owns this node.
 *
 * @see cxGetFsNodeArchive()
 */
void cxSetFsNodeArchive(CxFsNode *node, CxArchive *archive);

/**
 * Sets the specified node's parent directory.
 *
 * @param node   The node.
 * @param parent The parent directory.
 *
 * @see cxGetFsNodeParent()
 */
void cxSetFsNodeParent(CxFsNode *node, CxDirectory *parent);

/**
 * Sets the base name of the specified node.
 *
 * @param node The node.
 * @param name The nodename.
 *
 * @see cxGetFsNodeName()
 */
void cxSetFsNodeName(CxFsNode *node, const char *name);

/**
 * Sets the type of node.
 *
 * @param node The node.
 * @param type The type of node.
 *
 * @see cxGetFsNodeType()
 */
void cxSetFsNodeType(CxFsNode *node, CxFsNodeType type);

/**
 * Sets the mode of the specified node.
 *
 * @param node The node.
 * @param mode The mode.
 *
 * @see cxGetFsNodeMode()
 */
void cxSetFsNodeMode(CxFsNode *node, mode_t mode);

/**
 * Sets the user ID of the specified node.
 *
 * @param node The node.
 * @param uid  The user ID.
 *
 * @see cxGetFsNodeUid()
 */
void cxSetFsNodeUid(CxFsNode *node, uid_t uid);

/**
 * Sets the group ID of the specified node.
 *
 * @param node The node.
 * @param gid  The group ID.
 *
 * @see cxGetFsNodeGid()
 */
void cxSetFsNodeGid(CxFsNode *node, gid_t gid);

/**
 * Sets the timestamp of the specified node.
 *
 * @param node The node.
 * @param date The date/time timestamp in seconds since the epoch.
 *
 * @see cxGetFsNodeDate()
 */
void cxSetFsNodeDate(CxFsNode *node, time_t date);

/**
 * Sets whether or not the node is stored locally.
 *
 * If the node is located online, or within an archive, this should be 0.
 * Otherwise, this should be 1.
 *
 * @param node    The node.
 * @param isLocal 1 if the node is stored locally; 0 otherwise.
 *
 * @see cxIsFsNodeLocal()
 */
void cxSetFsNodeLocal(CxFsNode *node, char isLocal);

/*@}*/

/**************************************************************************/
/** @name Attribute Retrieval Functions                                   */
/**************************************************************************/
/*@{*/

/**
 * Returns the archive that owns the specified node.
 *
 * @param node The node.
 *
 * @return The archive that owns this node.
 *
 * @see cxSetFsNodeArchive()
 */
CxArchive *cxGetFsNodeArchive(CxFsNode *node);

/**
 * Returns the specified node's parent directory.
 *
 * @param node The node.
 *
 * @return The specified node's parent directory.
 *
 * @see cxSetFsNodeParent()
 */
CxDirectory *cxGetFsNodeParent(CxFsNode *node);

/**
 * Returns the name of the specified node.
 *
 * @param node The node.
 *
 * @return The node's name.
 *
 * @see cxSetFsNodeName()
 */
const char *cxGetFsNodeName(CxFsNode *node);

/**
 * Returns the full path to the specified node.
 *
 * This may include such non-physical elements as FTP sites, archives,
 * etc. in the path.
 *
 * @param node The node.
 *
 * @return The path to the node.
 */
const char *cxGetFsNodePath(CxFsNode *node);

/**
 * Gets the type of node.
 *
 * @param node The node.
 *
 * @return The type of node.
 *
 * @see cxSetFsNodeType()
 */
CxFsNodeType cxGetFsNodeType(CxFsNode *node);

/**
 * Returns the mode of the specified node.
 *
 * @param node The node.
 *
 * @return The node's mode.
 *
 * @see cxSetFsNodeMode()
 */
mode_t cxGetFsNodeMode(CxFsNode *node);

/**
 * Returns the user ID of the specified node.
 *
 * @param node The node.
 *
 * @return The user ID of the specified node.
 *
 * @see cxSetFsNodeUid()
 */
uid_t cxGetFsNodeUid(CxFsNode *node);

/**
 * Returns the group ID of the specified node.
 *
 * @param node The node.
 *
 * @return The group ID of the specified node.
 *
 * @see cxSetFsNodeGid()
 */
gid_t cxGetFsNodeGid(CxFsNode *node);

/**
 * Returns the timestamp of the specified node.
 *
 * @param node The node.
 *
 * @return The date/time timestamp in seconds since the epoch.
 *
 * @see cxSetFsNodeDate()
 */
time_t cxGetFsNodeDate(CxFsNode *node);

/**
 * Returns whether or not the node is stored locally.
 *
 * If the node is located online, or within an archive, this will be 0.
 * Otherwise, this will be 1.
 *
 * @param node The node.
 *
 * @return 1 if the node is stored locally; 0 otherwise.
 *
 * @see cxSetFsNodeLocal()
 */
char cxIsFsNodeLocal(CxFsNode *node);

/*@}*/

/**************************************************************************/
/** @name Iteration Functions                                             */
/**************************************************************************/
/*@{*/

/**
 * Returns the next node in a list of nodes.
 *
 * @param node The current node.
 *
 * @return The next node in the list.
 * 
 * @see cxGetPreviousFsNode()
 */
CxFsNode *cxGetNextFsNode(CxFsNode *node);

/**
 * Returns the previous node in a list of nodes.
 *
 * @param node The current node.
 * 
 * @return The previous node in the list.
 *
 * @see cxGetNextFsNode()
 */
CxFsNode *cxGetPreviousFsNode(CxFsNode *node);

/*@}*/

/**************************************************************************/
/** @name Utility Functions                                               */
/**************************************************************************/
/*@{*/

/**
 * Returns true if the specified node type is a directory.
 *
 * @param node The node to check.
 *
 * @return true if the node is a directory.
 */
#define CX_IS_DIRECTORY(node) \
	(cxGetFsNodeType(node) == CX_FSNODETYPE_DIRECTORY)

/*@}*/

#ifdef __cplusplus
}
#endif

#endif /* _LIBCOMPREX_FSNODE_H_ */

