/* vi: set sw=4 ts=4: */
/*
 * CRONTAB
 *
 * usually setuid root, -c option only works if getuid() == geteuid()
 *
 * Copyright 1994 Matthew Dillon (dillon@apollo.west.oic.com)
 * Vladimir Oleynik <dzo@simtreas.ru> (C) 2002
 *
 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
 */

#include "busybox.h"

#ifndef CRONTABS
#define CRONTABS        "/var/spool/cron/crontabs"
#endif
#ifndef TMPDIR
#define TMPDIR          "/var/spool/cron"
#endif
#ifndef CRONUPDATE
#define CRONUPDATE      "cron.update"
#endif
#ifndef PATH_VI
#define PATH_VI         "/bin/vi"   /* location of vi */
#endif

static const char *CDir = CRONTABS;

static void EditFile(const char *user, const char *file);
static int GetReplaceStream(const char *user, const char *file);
static int ChangeUser(const char *user, short dochdir);

int crontab_main(int ac, char **av)
{
	enum { NONE, EDIT, LIST, REPLACE, DELETE } option = NONE;
	const struct passwd *pas;
	const char *repFile = NULL;
	int repFd = 0;
	int i;
	char caller[256];           /* user that ran program */
	char buf[1024];
	int UserId;

	UserId = getuid();
	pas = getpwuid(UserId);
	if (pas == NULL)
		bb_perror_msg_and_die("getpwuid");

	safe_strncpy(caller, pas->pw_name, sizeof(caller));

	i = 1;
	if (ac > 1) {
		if (av[1][0] == '-' && av[1][1] == 0) {
			option = REPLACE;
			++i;
		} else if (av[1][0] != '-') {
			option = REPLACE;
			++i;
			repFile = av[1];
		}
	}

	for (; i < ac; ++i) {
		char *ptr = av[i];

		if (*ptr != '-')
			break;
		ptr += 2;

		switch (ptr[-1]) {
		case 'l':
			if (ptr[-1] == 'l')
				option = LIST;
			/* fall through */
		case 'e':
			if (ptr[-1] == 'e')
				option = EDIT;
			/* fall through */
		case 'd':
			if (ptr[-1] == 'd')
				option = DELETE;
			/* fall through */
		case 'u':
			if (i + 1 < ac && av[i+1][0] != '-') {
				++i;
				if (getuid() == geteuid()) {
					pas = getpwnam(av[i]);
					if (pas) {
						UserId = pas->pw_uid;
					} else {
						bb_error_msg_and_die("user %s unknown", av[i]);
					}
				} else {
					bb_error_msg_and_die("only the superuser may specify a user");
				}
			}
			break;
		case 'c':
			if (getuid() == geteuid()) {
				CDir = (*ptr) ? ptr : av[++i];
			} else {
				bb_error_msg_and_die("-c option: superuser only");
			}
			break;
		default:
			i = ac;
			break;
		}
	}
	if (i != ac || option == NONE)
		bb_show_usage();

	/*
	 * Get password entry
	 */

	pas = getpwuid(UserId);
	if (pas == NULL)
		bb_perror_msg_and_die("getpwuid");

	/*
	 * If there is a replacement file, obtain a secure descriptor to it.
	 */

	if (repFile) {
		repFd = GetReplaceStream(caller, repFile);
		if (repFd < 0)
			bb_error_msg_and_die("cannot read replacement file");
	}

	/*
	 * Change directory to our crontab directory
	 */

	xchdir(CDir);

	/*
	 * Handle options as appropriate
	 */

	switch (option) {
	case LIST:
		{
			FILE *fi;

			fi = fopen(pas->pw_name, "r");
			if (fi) {
				while (fgets(buf, sizeof(buf), fi) != NULL)
					fputs(buf, stdout);
				fclose(fi);
			} else {
				bb_error_msg("no crontab for %s", pas->pw_name);
			}
		}
		break;
	case EDIT:
		{
/* FIXME: messy code here! we have file copying helpers for this! */
			FILE *fi;
			int fd;
			int n;
			char tmp[128];

			snprintf(tmp, sizeof(tmp), TMPDIR "/crontab.%d", getpid());
			fd = xopen3(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600);
/* race, use fchown */
			chown(tmp, getuid(), getgid());
			fi = fopen(pas->pw_name, "r");
			if (fi) {
				while ((n = fread(buf, 1, sizeof(buf), fi)) > 0)
					full_write(fd, buf, n);
			}
			EditFile(caller, tmp);
			remove(tmp);
			lseek(fd, 0L, SEEK_SET);
			repFd = fd;
		}
		option = REPLACE;
		/* fall through */
	case REPLACE:
		{
/* same here */
			char path[1024];
			int fd;
			int n;

			snprintf(path, sizeof(path), "%s.new", pas->pw_name);
			fd = open(path, O_CREAT|O_TRUNC|O_APPEND|O_WRONLY, 0600);
			if (fd >= 0) {
				while ((n = read(repFd, buf, sizeof(buf))) > 0) {
					full_write(fd, buf, n);
				}
				close(fd);
				rename(path, pas->pw_name);
			} else {
				bb_error_msg("cannot create %s/%s", CDir, path);
			}
			close(repFd);
		}
		break;
	case DELETE:
		remove(pas->pw_name);
		break;
	case NONE:
	default:
		break;
	}

	/*
	 *  Bump notification file.  Handle window where crond picks file up
	 *  before we can write our entry out.
	 */

	if (option == REPLACE || option == DELETE) {
		FILE *fo;
		struct stat st;

		while ((fo = fopen(CRONUPDATE, "a"))) {
			fprintf(fo, "%s\n", pas->pw_name);
			fflush(fo);
			if (fstat(fileno(fo), &st) != 0 || st.st_nlink != 0) {
				fclose(fo);
				break;
			}
			fclose(fo);
			/* loop */
		}
		if (fo == NULL) {
			bb_error_msg("cannot append to %s/%s", CDir, CRONUPDATE);
		}
	}
	return 0;
}

static int GetReplaceStream(const char *user, const char *file)
{
	int filedes[2];
	int pid;
	int fd;
	int n;
	char buf[1024];

	if (pipe(filedes) < 0) {
		perror("pipe");
		return -1;
	}
	pid = fork();
	if (pid < 0) {
		perror("fork");
		return -1;
	}
	if (pid > 0) {
		/*
		 * PARENT
		 */

		close(filedes[1]);
		if (read(filedes[0], buf, 1) != 1) {
			close(filedes[0]);
			filedes[0] = -1;
		}
		return filedes[0];
	}

	/*
	 * CHILD
	 */

	close(filedes[0]);

	if (ChangeUser(user, 0) < 0)
		exit(0);

	xfunc_error_retval = 0;
	fd = xopen(file, O_RDONLY);
	buf[0] = 0;
	write(filedes[1], buf, 1);
	while ((n = read(fd, buf, sizeof(buf))) > 0) {
		write(filedes[1], buf, n);
	}
	exit(0);
}

static void EditFile(const char *user, const char *file)
{
	int pid = fork();

	if (pid == 0) {
		/*
		 * CHILD - change user and run editor
		 */
		char *ptr;
		char visual[1024];

		if (ChangeUser(user, 1) < 0)
			exit(0);
		ptr = getenv("VISUAL");
		if (ptr == NULL || strlen(ptr) > 256)
			ptr = PATH_VI;

		snprintf(visual, sizeof(visual), "%s %s", ptr, file);
		execl(DEFAULT_SHELL, DEFAULT_SHELL, "-c", visual, NULL);
		perror("exec");
		exit(0);
	}
	if (pid < 0) {
		/*
		 * PARENT - failure
		 */
		bb_perror_msg_and_die("fork");
	}
	wait4(pid, NULL, 0, NULL);
}

static int ChangeUser(const char *user, short dochdir)
{
	struct passwd *pas;

	/*
	 * Obtain password entry and change privileges
	 */

	pas = getpwnam(user);
	if (pas == NULL) {
		bb_perror_msg_and_die("failed to get uid for %s", user);
	}
	setenv("USER", pas->pw_name, 1);
	setenv("HOME", pas->pw_dir, 1);
	setenv("SHELL", DEFAULT_SHELL, 1);

	/*
	 * Change running state to the user in question
	 */
	change_identity(pas);

	if (dochdir) {
		if (chdir(pas->pw_dir) < 0) {
			bb_perror_msg("chdir(%s) by %s failed", pas->pw_dir, user);
			xchdir(TMPDIR);
		}
	}
	return pas->pw_uid;
}
