/* 
 * 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 <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);
}
