/*
 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
 * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
 * Licensed under the GPL
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <unistd.h>
#include "user.h"
#include "sysdep/ptrace.h"
#include "mconsole.h"
#include "umid.h"
#include "user_util.h"

static struct mconsole_command commands[] = {
	/* With uts namespaces, uts information becomes process-specific, so
	 * we need a process context.  If we try handling this in interrupt
	 * context, we may hit an exiting process without a valid uts
	 * namespace.
	 */
	{ "version", mconsole_version, MCONSOLE_PROC },
	{ "halt", mconsole_halt, MCONSOLE_PROC },
	{ "reboot", mconsole_reboot, MCONSOLE_PROC },
	{ "config", mconsole_config, MCONSOLE_PROC },
	{ "remove", mconsole_remove, MCONSOLE_PROC },
	{ "sysrq", mconsole_sysrq, MCONSOLE_INTR },
	{ "help", mconsole_help, MCONSOLE_INTR },
	{ "cad", mconsole_cad, MCONSOLE_INTR },
	{ "stop", mconsole_stop, MCONSOLE_PROC },
	{ "go", mconsole_go, MCONSOLE_INTR },
	{ "log", mconsole_log, MCONSOLE_INTR },
	{ "proc", mconsole_proc, MCONSOLE_PROC },
        { "stack", mconsole_stack, MCONSOLE_INTR },
};

/* Initialized in mconsole_init, which is an initcall */
char mconsole_socket_name[256];

int mconsole_reply_v0(struct mc_request *req, char *reply)
{
        struct iovec iov;
        struct msghdr msg;

        iov.iov_base = reply;
        iov.iov_len = strlen(reply);

        msg.msg_name = &(req->origin);
        msg.msg_namelen = req->originlen;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
        msg.msg_flags = 0;

        return sendmsg(req->originating_fd, &msg, 0);
}

static struct mconsole_command *mconsole_parse(struct mc_request *req)
{
	struct mconsole_command *cmd;
	int i;

	for(i = 0; i < ARRAY_SIZE(commands); i++){
		cmd = &commands[i];
		if(!strncmp(req->request.data, cmd->command, 
			    strlen(cmd->command))){
			return cmd;
		}
	}
	return NULL;
}

#define MIN(a,b) ((a)<(b) ? (a):(b))

#define STRINGX(x) #x
#define STRING(x) STRINGX(x)

int mconsole_get_request(int fd, struct mc_request *req)
{
	int len;

	req->originlen = sizeof(req->origin);
	req->len = recvfrom(fd, &req->request, sizeof(req->request), 0,
			    (struct sockaddr *) req->origin, &req->originlen);
	if (req->len < 0)
		return 0;

	req->originating_fd = fd;

	if(req->request.magic != MCONSOLE_MAGIC){
		/* Unversioned request */
		len = MIN(sizeof(req->request.data) - 1, 
			  strlen((char *) &req->request));
		memmove(req->request.data, &req->request, len);
		req->request.data[len] = '\0';

		req->request.magic = MCONSOLE_MAGIC;
		req->request.version = 0;
		req->request.len = len;

		mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
				  "not supported by this driver");
		return(0);
	}

	if(req->request.len >= MCONSOLE_MAX_DATA){
		mconsole_reply(req, "Request too large", 1, 0);
		return(0);
	}
	if(req->request.version != MCONSOLE_VERSION){
		mconsole_reply(req, "This driver only supports version " 
                               STRING(MCONSOLE_VERSION) " clients", 1, 0);
	}
	
	req->request.data[req->request.len] = '\0';
	req->cmd = mconsole_parse(req);
	if(req->cmd == NULL){
		mconsole_reply(req, "Unknown command", 1, 0);
		return(0);
	}

	return(1);
}

int mconsole_reply_len(struct mc_request *req, const char *str, int total,
		       int err, int more)
{
	/* XXX This is a stack consumption problem.  It'd be nice to
	 * make it global and serialize access to it, but there are a
	 * ton of callers to this function.
	 */
	struct mconsole_reply reply;
	int len, n;

	do {
		reply.err = err;

		/* err can only be true on the first packet */
		err = 0;

		len = MIN(total, MCONSOLE_MAX_DATA - 1);

		if(len == total) reply.more = more;
		else reply.more = 1;

		memcpy(reply.data, str, len);
		reply.data[len] = '\0';
		total -= len;
		str += len;
		reply.len = len + 1;

		len = sizeof(reply) + reply.len - sizeof(reply.data);

		n = sendto(req->originating_fd, &reply, len, 0,
			   (struct sockaddr *) req->origin, req->originlen);

		if(n < 0) return(-errno);
	} while(total > 0);
	return(0);
}

int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
{
	return mconsole_reply_len(req, str, strlen(str), err, more);
}


int mconsole_unlink_socket(void)
{
	unlink(mconsole_socket_name);
	return 0;
}

static int notify_sock = -1;

int mconsole_notify(char *sock_name, int type, const void *data, int len)
{
	struct sockaddr_un target;
	struct mconsole_notify packet;
	int n, err = 0;

	lock_notify();
	if(notify_sock < 0){
		notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
		if(notify_sock < 0){
			err = -errno;
			printk("mconsole_notify - socket failed, errno = %d\n",
			       err);
		}
	}
	unlock_notify();
	
	if(err)
		return(err);

	target.sun_family = AF_UNIX;
	strcpy(target.sun_path, sock_name);

	packet.magic = MCONSOLE_MAGIC;
	packet.version = MCONSOLE_VERSION;
	packet.type = type;
	len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len;
	packet.len = len;
	memcpy(packet.data, data, len);

	err = 0;
	len = sizeof(packet) + packet.len - sizeof(packet.data);
	n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 
		   sizeof(target));
	if(n < 0){
		err = -errno;
		printk("mconsole_notify - sendto failed, errno = %d\n", errno);
	}
	return(err);
}

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
