1/* Copyright 1988,1990,1993,1994 by Paul Vixie
2 * All rights reserved
3 *
4 * Distribute freely, except: don't remove my name from the source or
5 * documentation (don't take credit for my work), mark your changes (don't
6 * get me blamed for your possible bugs), don't alter or remove this
7 * notice.  May be sold if buildable source is provided to buyer.  No
8 * warrantee of any kind, express or implied, is included with this
9 * software; use at your own risk, responsibility for damages (if any) to
10 * anyone resulting from the use of this software rests entirely with the
11 * user.
12 *
13 * Send bug reports, bug fixes, enhancements, requests, flames, etc., and
14 * I'll try to keep a version up to date.  I can be reached as follows:
15 * Paul Vixie          <paul@vix.com>          uunet!decwrl!vixie!paul
16 */
17
18#if !defined(lint) && !defined(LINT)
19static const char rcsid[] =
20  "$FreeBSD$";
21#endif
22
23/* vix 26jan87 [log is in RCS file]
24 */
25
26
27#include "cron.h"
28
29static char *User_name;
30
31void
32free_user(u)
33	user	*u;
34{
35	entry	*e, *ne;
36
37	free(u->name);
38	for (e = u->crontab;  e != NULL;  e = ne) {
39		ne = e->next;
40		free_entry(e);
41	}
42	free(u);
43}
44
45static void
46log_error(msg)
47	char	*msg;
48{
49	log_it(User_name, getpid(), "PARSE", msg);
50}
51
52user *
53load_user(crontab_fd, pw, name)
54	int		crontab_fd;
55	struct passwd	*pw;		/* NULL implies syscrontab */
56	char		*name;
57{
58	char	envstr[MAX_ENVSTR];
59	FILE	*file;
60	user	*u;
61	entry	*e;
62	int	status;
63	char	**envp, **tenvp;
64
65	if (!(file = fdopen(crontab_fd, "r"))) {
66		warn("fdopen on crontab_fd in load_user");
67		return NULL;
68	}
69
70	Debug(DPARS, ("load_user()\n"))
71
72	/* file is open.  build user entry, then read the crontab file.
73	 */
74	if ((u = (user *) malloc(sizeof(user))) == NULL) {
75		errno = ENOMEM;
76		return NULL;
77	}
78	if ((u->name = strdup(name)) == NULL) {
79		free(u);
80		errno = ENOMEM;
81		return NULL;
82	}
83	u->crontab = NULL;
84
85	/*
86	 * init environment.  this will be copied/augmented for each entry.
87	 */
88	if ((envp = env_init()) == NULL) {
89		free(u->name);
90		free(u);
91		return NULL;
92	}
93
94	/*
95	 * load the crontab
96	 */
97	while ((status = load_env(envstr, file)) >= OK) {
98		switch (status) {
99		case ERR:
100			free_user(u);
101			u = NULL;
102			goto done;
103		case FALSE:
104			User_name = u->name;    /* for log_error */
105			e = load_entry(file, log_error, pw, envp);
106			if (e) {
107				e->next = u->crontab;
108				u->crontab = e;
109			}
110			break;
111		case TRUE:
112			if ((tenvp = env_set(envp, envstr))) {
113				envp = tenvp;
114			} else {
115				free_user(u);
116				u = NULL;
117				goto done;
118			}
119			break;
120		}
121	}
122
123 done:
124	env_free(envp);
125	fclose(file);
126	Debug(DPARS, ("...load_user() done\n"))
127	return u;
128}
129