/* 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"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/resource.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 */
    int   UserId;

    UserId = getuid();
    if ((pas = getpwuid(UserId)) == 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
     */

    if ((pas = getpwuid(UserId)) == 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("unable to read replacement file");
    }

    /*
     * Change directory to our crontab directory
     */

    bb_xchdir(CDir);

    /*
     * Handle options as appropriate
     */

    switch(option) {
    case LIST:
	{
	    FILE *fi;
	    char buf[1024];

	    if ((fi = fopen(pas->pw_name, "r"))) {
		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:
	{
	    FILE *fi;
	    int fd;
	    int n;
	    char tmp[128];
	    char buf[1024];

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

	    snprintf(path, sizeof(path), "%s.new", pas->pw_name);
	    if ((fd = open(path, O_CREAT|O_TRUNC|O_APPEND|O_WRONLY, 0600)) >= 0) {
		while ((n = read(repFd, buf, sizeof(buf))) > 0) {
		    write(fd, buf, n);
		}
		close(fd);
		rename(path, pas->pw_name);
	    } else {
		bb_error_msg("unable to 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("unable to 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);
    }
    if ((pid = fork()) < 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);

    bb_default_error_retval = 0;
    fd = bb_xopen3(file, O_RDONLY, 0);
    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;

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

	if (ChangeUser(user, 1) < 0)
	    exit(0);
	if ((ptr = getenv("VISUAL")) == 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
     */

    if ((pas = getpwnam(user)) == NULL) {
	bb_perror_msg_and_die("failed to get uid for %s", user);
	return(-1);
    }
    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 failed: %s %s", user, pas->pw_dir);
	    bb_xchdir(TMPDIR);
	}
    }
    return(pas->pw_uid);
}
