/*
 * log.h - log streams handling classes
 * $Id: log.h,v 1.2 2004/06/05 15:15:17 rdenisc Exp $
 */

/***********************************************************************
 *  Copyright (C) 2002-2004 Remi Denis-Courmont.                       *
 *  This program is free software; you can redistribute and/or modify  *
 *  it under the terms of the GNU General Public License as published  *
 *  by the Free Software Foundation; version 2 of the license.         *
 *                                                                     *
 *  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, you can get it from:              *
 *  http://www.gnu.org/copyleft/gpl.html                               *
 ***********************************************************************/

#ifndef __TCPREEN_LOG_H

# define __TCPREEN_LOG_H
# include <stdio.h>

/*
 * Virtual base class for log files
 */
class DataLog
{
	protected:
		FILE *out; /* output stream */
	
	private:
		int close_out;

	public:
		DataLog (void) : out (NULL), close_out (0)
		{
		}
		
		operator void* (void)
		{
			return (out != NULL) ? this : NULL;
		}
		
		int operator! (void) const
		{
			return out == NULL;
		}

		virtual ~DataLog (void);

		FILE *SetStream (FILE *stream, int do_close = 1)
		{
			close_out = do_close;
			return out = stream;
		}

		virtual int WriteClientData (const void *data, int length,
						int oob = 0);
		virtual int WriteServerData (const void *data, int length,
						int oob = 0);
		virtual void ShutdownServer (void);
		virtual void ShutdownClient (void);
		virtual void Connect (const char *sadddr, const char *sport,
					const char *caddr, const char *cport);
};


/*
 * Class of lists of DataLog objects
 */
class DataLogList;

class OnewayLogList
{
	private:
		DataLogList *mylist;
		int is_client_side;

	public:
		OnewayLogList (DataLogList *list, int client_side)
			: mylist (list), is_client_side (client_side)
		{
		}

		int WriteData (const void *data, int length, int excpt = 0);
		void Shutdown (void);
};



class DataLogList
{
	private:
		struct listnode
		{
			DataLog *log;
			struct listnode *next;
		} *head;
		OnewayLogList clientside, serverside;

	public:
		DataLogList (void) : head (NULL), clientside (this, 1),
			serverside (this, 0)
		{
		}

		~DataLogList (void);
		int AddLog (DataLog *log);
		/* Adds a log in the list (it is assumed that the log was
		 * dynamically allocated with `new'). Returns -1 on error (in
		 * this case, log is NOT deleted) or if log is NULL, 0 on
		 * success. */

		void Connect (const char *server, const char *service,
				const char *client, const char *port);
		int WriteServerData (const void *data, int length,
					int excpt = 0);
		int WriteClientData (const void *data, int length,
					int excpt = 0);
		void ShutdownServer (void);
		void ShutdownClient (void);

		int operator ! (void) const
		{
			return head != NULL;
		}

		operator void * (void)
		{
			return (head != NULL) ? this : NULL;
		}

		OnewayLogList& ClientSide (void)
		{
			return clientside;
		}

		OnewayLogList& ServerSide (void)
		{
			return serverside;
		}
};



inline int
OnewayLogList::WriteData (const void *data, int length, int excpt)
{
	return is_client_side ? mylist->WriteClientData (data, length, excpt)
			: mylist->WriteServerData (data, length, excpt);
}

inline void
OnewayLogList::Shutdown (void)
{
	is_client_side ? mylist->ShutdownClient ()
			: mylist->ShutdownServer ();
}



class DataLogListMaker
{
	private:
		struct listnode
		{
			DataLog *(*maker) (void);
			struct listnode *next;
			FILE *stream;
			char *basename;
		} *head;

	public:
		DataLogListMaker (void) : head (NULL)
		{
			/* WARNING: this constructor might be run SetUID.
			 * We'd better do nothing here.
			 */
		}
		
		~DataLogListMaker (void);

		int operator! (void) const
		{
			return head == NULL;
		}

		operator void * (void)
		{
			return (head != NULL) ? this : NULL;
		}

		int AddLogMaker (DataLog *(*maker) (void),
				FILE *stream = stdout);
		int AddLogMaker (DataLog *(*maker) (void),
				const char *prefix);
		DataLogList *MakeLogList (const char *ad, const char *p) const;
};

typedef DataLog * (*DataLogMaker) (void);

#endif



syntax highlighted by Code2HTML, v. 0.9.1