/*
 * server.h
 * File Revision 0
 * Primary header for http server.
 * (c) 2000 Jacob Lundberg, jacob@chaos2.org
 */


/*
 * 2000.11.10	Initial implementation
 */


#ifndef __SERVER_H__
#define __SERVER_H__


#include <netdb.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


/* Versioning. */
#define  SERVER_ID                      "Indigo Simple Server/" VERSION " (Unix)"


/*
 * boolean logic
 * We provide a form that gcc will accept by default.  However, it isn't
 * strictly correct to define arbitrary values for both members of an enum
 * so unless we know we're compiling with a GNU C compiler we'll refrain.
 */
#ifdef __GNUC__

typedef enum boolean {
   false = 0,
   true = !false
} bool;

#else /* def __GNUC__ */

typedef int bool;
#define  false  0
#define  true   !false

#endif /* def __GNUC__ */


/*
 * Debug output, not strictly ANSI (ellipsi).
 * DEBUG should be set in the Makefile.
 */
#if defined( __GNUC__ ) && defined( DEBUG ) && ( DEBUG > 1 )
#define  DBG_PRN(A, B...)               printf("%5i - %s - " A, getpid(), ##B); \
                                        fflush(stdout)
#else /* DEBUG > 1 */
#define  DBG_PRN(A, B...)               /* nothing */
#endif /* DEBUG > 1 */


/*
 * Single Unix names flags for shutdown(). Since I'm using them,
 * I provide them here for systems that don't define them for me.
 */
#ifndef  SHUT_RD
#define  SHUT_RD        0
#endif   /* ndef SHUT_RD */

#ifndef  SHUT_WR
#define  SHUT_WR        1
#endif   /* ndef SHUT_WR */

#ifndef  SHUT_RDWR
#define  SHUT_RDWR      2
#endif   /* ndef SHUT_RDWR */


/* Default port the server listens on if no port is specified. */
#define  SV_DEFAULT_PORT                80
/* Give the listen max backlog.  BSD may lower it to 5 though. */
#define  SV_LISTEN_BACKLOG              16


/* Tuning for buffer allocations in sockio.c. */
#define  SV_BUFFER_GROW_SIZE            512
#define  SV_BUFFER_MAX_GROWTHS          32


/* Enumerate the request types. */
typedef enum _sv_req_type {
   SV_REQ_NONE = false,                 /* bad request type */
   SV_REQ_GET,                          /* GET method */
   SV_REQ_HEAD,                         /* HEAD method */
} sv_req_type;


/* Define a struct to store information about a request in. */
typedef struct _sv_req {
   sv_req_type req_type;                /* type of request */
   char *filename;                      /* file name requested */
   int file;                            /* file opened (if one is) */
} sv_req;


/* Am I the parent or the child? */
extern int sv_fork_level;

/* Global socket descriptors. */
extern int sv_sock_lstn;
extern int sv_sock_comm;


/* parse.c */
void fill_request(sv_req *request);
bool parse_request(sv_req *request, char *buffer);

/* server.c */
void action_fork(void);
void action_serve(void);
void do_exit(int exit_val);

/* signals.c */
void handle_signals(void);
void ignore_signals(void);

/* sockio.c */
void action_accept(void);
char *action_read(char *buffer);
void action_write(char *buffer, int size);
void setup_bind(unsigned short port);
void setup_listen(int backlog);
void setup_socket(void);


#endif /* ndef __SERVER_H__ */

