/* 
 * dhcpcd - DHCP client daemon
 * Copyright (c) 2006-2009 Roy Marples <roy@marples.name>
 * All rights reserved

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <linux/socket.h>
#include <sys/stat.h>
#include <sys/un.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "config.h"
#include "common.h"
#include "dhcpcd.h"
#include "control.h"
#include "eloop.h"

static int fd = -1;
static char buffer[1024];
static char *argvp[255];

struct sockaddr_un sun;
struct fd_list *fds = NULL;

static void
remove_control_data(void *arg)
{
	struct fd_list *l, *last = NULL;

	for (l = fds; l != NULL; l = l->next) {
		if (l == arg) {
			close(l->fd);
			delete_event(l->fd);
			if (last == NULL)
				fds = l->next;
			else
				last->next = l->next;
			free(l);
			break;
		}
		last = l;
	}
}

static void
handle_control_data(void *arg)
{
	struct fd_list *l = arg;
	ssize_t bytes;
	int argc;
	char *e, *p;
	char **ap;

	bytes = read(l->fd, buffer, sizeof(buffer) - 1);
	if (bytes == -1 || bytes == 0) {
		remove_control_data(l);
		return;
	}
	buffer[bytes] = '\0';
	p = buffer;
	e = buffer + bytes;
	argc = 0;
	ap = argvp;
	while (p < e && (size_t)argc < sizeof(argvp)) {
		argc++;
		*ap++ = p;
		p += strlen(p) + 1;
	}
	handle_args(l, argc, argvp);
}

/* ARGSUSED */
static void
handle_control(_unused void *arg)
{
	struct sockaddr_un run;
	socklen_t len;
	struct fd_list *l;
	int f;

	len = sizeof(run);
	if ((f = accept(fd, (struct sockaddr *)&run, &len)) == -1)
		return;
	l = xmalloc(sizeof(*l));
	l->fd = f;
	l->listener = 0;
	l->next = fds;
	fds = l;
	add_event(l->fd, handle_control_data, l);
}

static int
make_sock(void)
{
	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		return -1;
	memset(&sun, 0, sizeof(sun));
	sun.sun_family = AF_UNIX;
	strlcpy(sun.sun_path, CONTROLSOCKET, sizeof(sun.sun_path));
	return sizeof(sun.sun_family) + strlen(sun.sun_path) + 1;
}

int
start_control(void)
{
	int len;

	if ((len = make_sock()) == -1)
		return -1;
	unlink(CONTROLSOCKET);
	if (bind(fd, (struct sockaddr *)&sun, len) == -1 ||
	    chmod(CONTROLSOCKET,
		S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) == -1 ||
	    set_cloexec(fd) == -1 ||
	    set_nonblock(fd) == -1 ||
	    listen(fd, sizeof(fds)) == -1)
	{
		close(fd);
		return -1;
	}
	add_event(fd, handle_control, NULL);
	return fd;
}

int
stop_control(void)
{
	int retval = 0;
	struct fd_list *l, *ll;

	delete_event(fd);
	if (shutdown(fd, SHUT_RDWR) == -1)
		retval = 1;
	fd = -1;
	if (unlink(CONTROLSOCKET) == -1)
		retval = -1;

	l = fds;
	while (l != NULL) {
		ll = l->next;
		delete_event(l->fd);
		shutdown(l->fd, SHUT_RDWR);
		free(l);
		l = ll;
	}

	return retval;
}

int
open_control(void)
{
	int len;

	if ((len = make_sock()) == -1)
		return -1;
	return connect(fd, (struct sockaddr *)&sun, len);
}

int
send_control(int argc, char * const *argv)
{
	char *p = buffer;
	int i;
	size_t len;

	if (argc > 255) {
		errno = ENOBUFS;
		return -1;
	}
	for (i = 0; i < argc; i++) {
		len = strlen(argv[i]) + 1;
		if ((p - buffer) + len > sizeof(buffer)) {
			errno = ENOBUFS;
			return -1;
		}
		memcpy(p, argv[i], len);
		p += len;
	}
	return write(fd, buffer, p - buffer);
}
