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

#include "main.h"
#include "IO.h"
#include "Signal.h"

bool
screws_IO(int s,int n,char **head)
{
	int frk;
	int f_in[2],
		f_out[2],
		f_err[2];
	
	/* IO: DirectIO */
	if (Svr.io==IO_DIRECT) {
		screws_logs_access(n);
		IO_direct(s,n,head);
	} else {

   /* Do the pipes */
   pipe(f_in);
	pipe(f_out);
	pipe(f_err);
	//socketpair(AF_UNIX,SOCK_STREAM,0,f_out);

	frk=fork();
	switch(frk)
	{
	  case -1: /* TODO log errlog */
		   break; /* fork failed */
	  case  0: 
		   /* setperm */
		   if (!  Error( Svr.Lis[n].name,setChildOptions(n) )  ) 
		   {
			   close(0); dup2(f_in [0],(int)0); /* stdin  */
			   close(1); dup2(f_out[1],(int)1); /* stdout */
			   close(2); dup2(f_err[1],(int)2); /* stderr */

				/* Exec Timeout */
				if (! Svr.notimeout && Svr.Lis[n].V[_EXECTIMEOUT] )
				catchTimeout(	getpid(),
						Svr.Lis[n].V[_EXECTIMEOUT],
						ALARM_KILL);

				/* execve */
				doExec(s,n,head);
		   } else {
				write(f_out[1],"Internal error\n",15);
			}
			shutdown(s,SHUT_RDWR);
			close(s);
		   exit(0);
		   break;
	  default:  /* father */
		   
		switch(Svr.io)
		{
			#if POLL
		case IO_POLL:
			IO_poll(s,f_in[1],f_out[0],f_err[0]);
			break;
			#endif
		case IO_BUFFER:
			IO_buffer(n,s,f_out[0]);
			break;
		case IO_SELECT:
			IO_select(n,s,f_out[0]);
			break;
		}

		 if (Svr.v>=V_SHOW)
			printf("[-] Connection Done.\n"); 

		#if LOGS
		if (Svr.io!=IO_DIRECT)
			screws_logs_access(n);
		#endif
		break;
	} /* switch fork */

	} /* else directio */
	return true;
}
