/*
 * This code is part of Screws project.
 * Copylefted by pancake@phreaker.net at 2003
 */

#if 0

  Screws  - Scriptable Web Server
  codedby - pancake <pancake@phreaker.net>
  license - GPL - Please, feel free to use, abuse and distrubute it.
 
#endif

/* basic includes */
#include "main.h"
/* external func */
#include "Config.h"
#include "Error.h"
#include "Args.h"
#include "Engine.h"
#include "Signal.h"

/* Server Struct */
struct Svr Svr;

char **av; /* Global argv */


int
main(argc,argv,envp)
	int argc;
	char *argv[];
	char *envp[];
{
	int err;
	/* I need some global data...ugly but true */
	av=argv;

	/* Show nice msg */
	printf("Screws v%s by pancake <pancake@phreaker.net>"
		   "             Copyleft(2004)\n",VERSION);

	/* Parse cmdline arguments */
	err=Error("-main-", getArgs(argc,argv) );
	switch(err) {
	case ERROR_NULL:
		exit(0);
	default:
		if (err>0) exit(err);
	}

	/* Parse configuration file */
	if ( Error("-main-", ReadConfig(Args.cfg,1) )  )
	{
		exit(1);
	}
	if (Args.v>=0)
		Svr.v=Args.v;

	/* Run in daemon mode? */
	if ( Args.daemon )
	{
		int i=0;
		if (daemon(1,0)<0) // sepharad patch
		{
			Error("-main-",ERROR_SETSID);
			exit(1);
		}

		close(0); close(1); close(2);
		for(i=0;i<3;i++)
		{
			open("/dev/null",O_RDWR);
		}
	}

	/* reName argv0? */
	if (Args.setname)
	{
	while(argc--) memset(argv[argc],0,strlen(argv[argc]));
	memcpy( argv[0],Args.progname,strlen(Args.progname) );
	argv[1]=0;
	}
	
	/* Setting priorities */
	Error( "-main-", setProcPrio(Svr.V[_PRIO]) );

	/* Set main thread permisions */
	if ( setProcPerm(Svr.V[_UID],
		         Svr.V[_EUID],
		         Svr.V[_GID],
		         Svr.V[_EGID]) ) exit(1);

	/* Show server goddies */ // TODO move this printf stuff to IO.c
	switch(Svr.io)
	{
	case IO_DIRECT:
		printf("[i] IO: DirectIO.\n");   break;
	#if POLL
	case IO_POLL:
		printf ("[i] IO: Poll().\n");    break;
	#endif
	case IO_BUFFER:
		printf ("[i] IO: Buffered.\n");  break;
	case IO_SELECT:
		printf ("[i] IO: Select().\n");  break;
	}

	/* Go childrens go! */
	for (argc=0;argc<Svr.l;argc++) /* use argc...less memory xD */
	{
		pid_t pid=launchListen(argc);
		if (!pid) Error("-main-",ERROR_FORK);
		else Svr.Lis[argc].pid=pid;
	}

	/* Catch'm all! */
	if ( Error("-main-",catchSignals(WHO_FATHER) ) )
		exit(1);

	/* StatsWhileLoop */
	Svr.ok=true;
	while(Svr.ok)
	{
		sleep(1); /* Sleep a while specting dead bodies */
		wait(NULL); /* I'm waiting for dead childrens */
		Svr.ok=0;
		printf("[E] Listen thread finished.\n");
	}
	
	/* NULL exit */
	exit((int)NULL);
}
