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: src/usr.sbin/cron/cron/user.c,v 1.8 1999/08/28 01:15:50 peter Exp $";
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#ifdef __APPLE__
66	pw = pw;	// avoid unused parameter warning
67#endif
68	if (!(file = fdopen(crontab_fd, "r"))) {
69		warn("fdopen on crontab_fd in load_user");
70		return NULL;
71	}
72
73	Debug(DPARS, ("load_user()\n"))
74
75	/* file is open.  build user entry, then read the crontab file.
76	 */
77	if ((u = (user *) malloc(sizeof(user))) == NULL) {
78		errno = ENOMEM;
79		return NULL;
80	}
81	if ((u->name = strdup(name)) == NULL) {
82		free(u);
83		errno = ENOMEM;
84		return NULL;
85	}
86	u->crontab = NULL;
87
88	/*
89	 * init environment.  this will be copied/augmented for each entry.
90	 */
91	if ((envp = env_init()) == NULL) {
92		free(u->name);
93		free(u);
94		return NULL;
95	}
96
97	/*
98	 * load the crontab
99	 */
100	while ((status = load_env(envstr, file)) >= OK) {
101		switch (status) {
102		case ERR:
103			free_user(u);
104			u = NULL;
105			goto done;
106		case FALSE:
107			User_name = u->name;    /* for log_error */
108#ifdef __APPLE__
109			e = load_entry(file, log_error, strcmp(name, "*system*") ? name : NULL, envp);
110#else
111			e = load_entry(file, log_error, pw, envp);
112#endif
113			if (e) {
114				e->next = u->crontab;
115				u->crontab = e;
116			}
117			break;
118		case TRUE:
119			if ((tenvp = env_set(envp, envstr))) {
120				envp = tenvp;
121			} else {
122				free_user(u);
123				u = NULL;
124				goto done;
125			}
126			break;
127		}
128	}
129
130 done:
131	env_free(envp);
132	fclose(file);
133	Debug(DPARS, ("...load_user() done\n"))
134	return u;
135}
136