/*
** xipcust.c for  in 
** 
** Made by 
** Login   <vianney@epita.fr>
** 
** Started on  Wed Sep  1 08:27:18 1999 
** Last update Thu Oct 28 20:24:08 1999 
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "pkt.h"
#include "pktio.h"
#include "pat_ether.h"
#include "pat_arp.h"
#include "pat_ip.h"
#include "pat_icmp.h"
#include "pat_udp.h"
#include "pat_tcp.h"
#include "xiprepl.h"
#include "xipvar.h"
#include <pcap.h>

t_status		xip_pkt_custom(pkt,args)
t_pkt			*pkt;
t_vec			*args;
{
  pid_t			custom_pid;
  int			consumer[2];
  int			producer[2];
  int			custom_status;
  t_status		status;

  if (VEC_COUNT(args) < 2)
    return (ERR_XIP_NEED_ONE_ARG);
  if (pipe(consumer) < 0)
    {
      err_print(ERR_XIP_SYSCALL,"pipe");
      exit(1);
    }
  if (pipe(producer) < 0)
    {
      err_print(ERR_XIP_SYSCALL,"pipe");
      exit(1);
    }
  if ((custom_pid = fork()) < 0)
    {
      err_print(ERR_XIP_SYSCALL,"fork");
      exit(1);
    }
  if (custom_pid)
    {
      close(consumer[1]);
      close(producer[0]);
      if ((status = pkt_write(pkt,
			      producer[1],
			      XIP_ALLOC_PROC,
			      XIP_FREE_PROC)) != 0)
	goto end;
      if ((status = pkt_read(pkt,
			     consumer[0],
			     XIP_ALLOC_PROC,
			     XIP_FREE_PROC)) != 0)
	goto end;
      status = 0;
    end:
      waitpid(custom_pid,&custom_status,NULL);
#ifdef NOTDEF
      if (custom_status != 0)
	return (ERR_XIP_CHILD_PROCESS);
#endif
      return (status);
    }
  else
    {
      char		*argv[10];
      int		i;
      
      if (VEC_COUNT(args) >= 10)
	return (ERR_XIP_TOO_MANY);
      i = 0;
      while (i < (VEC_COUNT(args) - 1))
	{
	  argv[i] = VEC_AT(args,i + 1);
	  i++;
	}
      argv[i] = NULL;
      close(consumer[0]);
      close(producer[1]);
      close(0);
      dup(producer[0]);
      close(1);
      dup(consumer[1]);
#ifdef NOTDEF
      i = 0;
      while (argv[i])
	{
	  fprintf(stderr,"%d %s\n",i,argv[i]);
	  i++;
	}
#endif
      execv(argv[0],argv);
      err_print(ERR_XIP_SYSCALL,"execv %s",argv[0]);
      exit(1);
    }
  return (0);
}

