xref: /freebsd/usr.sbin/cron/cron/user.c (revision 42249ef2)
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)
19 static const char rcsid[] =
20   "$FreeBSD$";
21 #endif
22 
23 /* vix 26jan87 [log is in RCS file]
24  */
25 
26 
27 #include "cron.h"
28 
29 static char *User_name;
30 
31 void
32 free_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 
45 static void
46 log_error(msg)
47 	char	*msg;
48 {
49 	log_it(User_name, getpid(), "PARSE", msg);
50 }
51 
52 user *
53 load_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