#include <unistd.h>
#include <sys/stat.h>
#include <sys/syslog.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <linux/unistd.h>
#define MAIN
#include "xattr.h"
#undef MAIN
#include "auth.h"

char *auth_file=NULL;

int xattrd_socket;

static int makesock(int,int,int);

int real_main (int, char**);

int main(int argc, char **argv)
{
   int ret_crash;

   if (fork()==0)
     {   
       setsid();
       chdir("/");
       umask(0);

       xattrd_socket=makesock(XATTRDPORT,IPPROTO_UDP,8192);
      
       /* Initialize the AUTH module. */
       auth_init(auth_file);       

       ret_crash=real_main(argc, argv);
       syslog(LOG_DAEMON, "ARGGHHHHHHHHHHHH ... Extended Attribute Daemon Crashed");
   
       return ret_crash;
     }

   return 0;
}

static int makesock(int port, int proto, int socksz)
{
	struct sockaddr_in sin;
	int s;
	int sock_type;

	sock_type = (proto == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
	s = socket(AF_INET, sock_type, proto);
	if (s < 0) {
		/*dprintf(0, "Could not make a socket: %s\n", strerror(errno));*/
		return (-1);
	}
	memset((char *) &sin, 0, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = INADDR_ANY;
	sin.sin_port = htons(port);

	{
		int val = 1;

		if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 0)
			/*dprintf(0, "setsockopt failed: %s\n", strerror(errno));*/
			;
	}

#ifdef SO_SNDBUF
	{
		int sblen, rblen;

		/* 1024 for rpc & transport overheads */
		sblen = rblen = socksz + 1024;
		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sblen, sizeof sblen) < 0 ||
		    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rblen, sizeof rblen) < 0)
			/*dprintf(0, "setsockopt failed: %s\n", strerror(errno));*/
			;
	}
#endif				/* SO_SNDBUF */

	if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
		/*dprintf(0, "Could not bind name to socket: %s\n", strerror(errno));*/
		return (-1);
	}
	return (s);
}

