root/usr.sbin/cron/cron/user.c
/* Copyright 1988,1990,1993,1994 by Paul Vixie
 * All rights reserved
 *
 * Distribute freely, except: don't remove my name from the source or
 * documentation (don't take credit for my work), mark your changes (don't
 * get me blamed for your possible bugs), don't alter or remove this
 * notice.  May be sold if buildable source is provided to buyer.  No
 * warrantee of any kind, express or implied, is included with this
 * software; use at your own risk, responsibility for damages (if any) to
 * anyone resulting from the use of this software rests entirely with the
 * user.
 *
 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
 * I'll try to keep a version up to date.  I can be reached as follows:
 * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
 *
 * $FreeBSD: src/usr.sbin/cron/cron/user.c,v 1.8 1999/08/28 01:15:50 peter Exp $
 */

/* vix 26jan87 [log is in RCS file]
 */


#include "cron.h"

static char *User_name;

void
free_user(user *u)
{
        entry   *e, *ne;

        free(u->name);
        for (e = u->crontab;  e != NULL;  e = ne) {
                ne = e->next;
                free_entry(e);
        }
        free(u);
}

static void
log_error(const char *msg)
{
        log_it(User_name, getpid(), "PARSE", msg);
}

user *
load_user(int crontab_fd, struct passwd *pw, const char *name)
/* pw == NULL implies syscrontab */
{
        char    envstr[MAX_ENVSTR];
        FILE    *file;
        user    *u;
        entry   *e;
        int     status;
        char    **envp, **tenvp;

        if (!(file = fdopen(crontab_fd, "r"))) {
                warn("fdopen on crontab_fd in load_user");
                return NULL;
        }

        Debug(DPARS, ("load_user()\n"))

        /* file is open.  build user entry, then read the crontab file.
         */
        if ((u = (user *) malloc(sizeof(user))) == NULL) {
                errno = ENOMEM;
                return NULL;
        }
        if ((u->name = strdup(name)) == NULL) {
                free(u);
                errno = ENOMEM;
                return NULL;
        }
        u->crontab = NULL;

        /* 
         * init environment.  this will be copied/augmented for each entry.
         */
        if ((envp = env_init()) == NULL) {
                free(u->name);
                free(u);
                return NULL;
        }

        /*
         * load the crontab
         */
        while ((status = load_env(envstr, file)) >= OK) {
                switch (status) {
                case ERR:
                        free_user(u);
                        u = NULL;
                        goto done;
                case FALSE:
                        User_name = u->name;    /* for log_error */
                        e = load_entry(file, log_error, pw, envp);
                        if (e) {
                                e->next = u->crontab;
                                u->crontab = e;
                        }
                        break;
                case TRUE:
                        if ((tenvp = env_set(envp, envstr))) {
                                envp = tenvp;
                        } else {
                                free_user(u);
                                u = NULL;
                                goto done;
                        }
                        break;
                }
        }

 done:
        env_free(envp);
        fclose(file);
        Debug(DPARS, ("...load_user() done\n"))
        return u;
}