/* ============================================================================
 * << File: gems_server.h >>
 * -------------------------
 *  Authors: Emiliano Castagnari (aka Torian) <ecastag@fi.uba.ar>
 *           Diego Essaya <dessaya@fi.uba.ar>
 *     Date: 29/12/03
 * ============================================================================
 * ============================================================================
 *
 * ChangeLog: View Changelog
 *
 * ============================================================================
 * Copyright (C) 2003, 2004 Diego Essaya, Emiliano Castagnari
 * 
 * This file is part of gems.
 * 
 * gems is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * gems 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 General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * ============================================================================
 */

#ifndef _GEMS_SERVER_H_
#define _GEMS_SERVER_H_

#include <netinet/in.h> /* struct sockaddr_in */

#include "common.h"     /* fbool_t            */
#include "protocol.h"   /* gems_msg_type_t    */
#include "sock_info.h"  /* t_clsock           */

/* Server options: */
typedef struct t_options
{
	t_ip ip;
	int port;
	char *flog;					/* Archivo de log - file | Syslog */
	int script;
	char *script_bin;
	int maxconn;
	int expected_connections;		/* Cantidad de clientes a esperar */
}
t_options;

/* Server-related information: */
typedef struct t_server_data
{
	int sock_server;			/* Socket for accept()ing connections */
	int input_fd;				/* Data input fd */
	fd_set open_fds;			/* Array of open fds */
	int fdmax;					/* Maximum open file descriptor */

	int clients;				/* Number of connected clients */
	struct t_clsock *client_list;	/* List of connected clients */
	struct t_waiting_client *waiting_client_list;	/* List of clients 
													   awaiting connection */
} t_server_data;

status_t init_sock_server(t_server_data *data, t_options *options);
void close_sockets(t_server_data *data);
fbool_t validate_client(int fd, int max_conn, t_server_data *data);
fbool_t accept_new_client(t_server_data *data, int max_conn);
struct t_clsock *add_client(int socket, struct sockaddr_in *client_data, t_server_data *data);
void init_clsock(struct t_clsock *client_sock);
void del_client(t_clsock *client, t_server_data *data);
fbool_t send_to_all(gems_msg_type_t type, char *buffer, int n, t_server_data *data);
fbool_t send_input_to_clients(t_server_data *data);
void attend_client(t_clsock *client, t_server_data *data);
void send_winsize_to_clients(t_server_data *data);
void init_data(t_server_data *data, int input_fd, int expected_connections);
status_t gems_server(int input_fd, t_options *options);
fbool_t check_new_client(t_server_data *data, int expected_connections);
void remove_waiting_client(t_server_data *data, t_waiting_client *wc);
t_waiting_client *add_waiting_client(t_server_data *data, pid_t pid,
	int socket, struct sockaddr_in *addr_data);
void kill_waiting_clients(t_server_data *data);
char *create_lock(t_options *options);
void release_lock(char *name);
void check_winsize();

#endif

/* vim: set ts=4 sw=4: */
