#ifndef NETUTILS_H
#define NETUTILS_H

#include <qstring.h>
#include <sys/types.h>
#include <netinet/in.h>

#define MIN_USER_PORT (unsigned short int)IPPORT_USERRESERVED
#define MAX_USER_PORT 65535

/** 
 * This header contains (very) useful functions to do usual operations on
 * INET hostnames and sockets.
 *
 * First an advice : be careful that the <I>close(bool)</I> function exists
 * for QWidget object and doing something like <I>close(socket)</I> will
 * in fact close your widget !!! You must use <I>::close(socket)</I> instead.
 * This header also provide a function called @ref #closeSocket() (which is
 * just a wrapper).
 *
 * By the way the function <I>connect</I> also exists in QT but the parameters
 * are differents so you'll get a compiler error.
 */

/** 
 * Set <I>name</I> with the local host name.
 * @return TRUE on success (otherwise set <I>error</I> with an error message). 
 */
bool getHostname(QString &name, QString *error = 0);

/** 
 * Set <I>hostAddr</I> and <I>hostName</I> respectively with
 * the host Internet address (something like "125.134.160.12") and 
 * the host name (something like "pc.kde.org") corresponding to the
 * given host name.
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 */
bool getInetAddresses(const char *name, QString &hostAddr, QString &hostName,
					  QString *error = 0);
	
/** 
 * Create an AF_INET socket and set <I>socket</I> with it.
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 * NB : <I>socket</I> is set to -1 on error;
 */
bool createInetSocket(int &socket, QString *error = 0);
	
/** 
 * Close a socket.
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 */
bool closeSocket(int socket, QString *error = 0);

/**
 * Connect the given AF_INET socket <I>socket</I>.
 * @param serverAddr must be the Internet name of the server.
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 */
bool connectInetSocket(int socket, unsigned short int port,
					   const char *serverName, QString *error = 0);
	
/** 
 * Bind and listen the given AF_INET socket.
 * @param backlog is the maximum length of the queue of pending connections.
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 */
bool bindInetSocket(int socket, unsigned short int port, 
					int backlog = 1, QString *error = 0);

/** 
 * Accept on the AF_INET socket.
 * @param newSocket will contain the new socket.
 * @param name and @param address are set with the incoming host name 
 * and address.
 * Be aware that accepting when there is no pending connection can block.
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 */
bool acceptInetSocket(int socket, int &newSocket,
					  QString &name, QString &address,
					  QString *error = 0);

/** 
 * Check if the port is a valid one and set <I>port</I> with its value.
 * A port (for a user application) is valid if included in
 * [IPPORT_USERRESERVED, 65535].
 * @return TRUE on success (otherwise set <I>error</I> with an error message).
 */
bool checkPortValidity(const char *portString, unsigned short int &port,
					   QString *error = 0);

/** Same as above with an unsigned integer on entry. */
bool checkPortValidity(uint portInt, unsigned short int &port,
					   QString *error = 0);
  	 
#endif // NETUTILS_H
