/* ================================================ */
/*
    maxtab.c
    Steve Isaacson

    chown bin maxtab
    chgrp cron maxtab
    chmod 2111 maxtab
    mv maxtab /usr/bin/maxtab

  This is the maxtab program similiar to crontab.
*/
/* ================================================ */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUFSIZE 200
#define PERMS 0600
extern int errno;

char *tdir="/tmp";

/* should be owned by, and only writeable by bin */
char *dir="/usr/spool/cron/maxtabs";

main(argc, argv)
int argc;
char *argv[];
{
    int fd, tempfd, n;
    char *pfn;
    char buf[BUFSIZE], tabname[BUFSIZE];
    char tempname[BUFSIZE];

    /* create the filenames */
    sprintf(tabname, "%s/%s", dir, cuserid(NULL) );
    sprintf(tempname, "%s/tmp.%d", tdir, getuid());

    switch ( argc ) {

        case 1: /* take input from stdin */
            fd=0;
            break;

        case 2: /* if it's not a command-line option,
                   then it's a file */
            if ( argv[1][0] != '-' ) {
                pfn=argv[1];
                if ( (fd=open(pfn, O_RDONLY)) == -1 ) {
                    perror(pfn);
                    exit(errno);
                }
            }
            else switch ( argv[1][1] ) {
                case 'l':
                    /* list existing maxtab file */
                    if ( (fd=open(tabname,
                                  O_RDONLY)) == -1 ) {
                        perror(tabname);
                        exit(errno);
                    }
                    while ((n=read(fd, buf,
                                    sizeof(buf))) > 0)
                        write(1, buf, n);
                    exit(0);
                    break;

                case 'r':
                    /* remove existing maxtab file */
                    if ( unlink(tabname) == -1 )
                        perror(tabname);
                    exit(errno);
                    break;

                default:
                    fprintf(stderr,
                    "Error: illegal argument: %s\n",argv[1]);
                    usage();
            }
            break;

        default:
            fprintf(stderr, "Error: Too many args\n");
            usage();
            break;
    }

    /* open a temp file to work in. This is required
       because you don't want to wipe out an 
       existing maxtab file until you're sure
       you have a new one to replace it with. */
    if ( (tempfd=open(tempname,
            O_TRUNC|O_RDWR|O_CREAT, PERMS)) == -1 ) {
        perror(tempname);
        exit(errno);
    }

    chown(tempname, geteuid(), getegid());
    chmod (tempname, PERMS);

    /* write to it. */
    while ((n=read(fd, buf, sizeof(buf))) > 0)
        write(tempfd, buf, n);

    unlink(tabname); /* ignore error return */

    if ( link(tempname, tabname) ) {
        perror("link");
        exit(errno);
    }

    close (fd);
    close (tempfd);
    if ( unlink(tempname) == -1 )
        perror(tempname);
    exit(errno);
}

/* ================================================ */

usage() {

    fprintf(stderr, "Usage: maxtab [filename]\n");
    fprintf(stderr, "       maxtab [-r|-l]\n");
    exit(1);
}

/* ================================================ */
