summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
Diffstat (limited to 'libexec')
-rw-r--r--libexec/cron/cron.c8
-rw-r--r--libexec/cron/cron.h27
-rw-r--r--libexec/cron/crontab.518
-rw-r--r--libexec/cron/crontab.c38
-rw-r--r--libexec/cron/database.c46
-rw-r--r--libexec/cron/do_command.c80
-rw-r--r--libexec/cron/entry.c56
-rw-r--r--libexec/cron/env.c46
-rw-r--r--libexec/cron/user.c72
9 files changed, 210 insertions, 181 deletions
diff --git a/libexec/cron/cron.c b/libexec/cron/cron.c
index 1e7a357c06e..17bd6ff8f09 100644
--- a/libexec/cron/cron.c
+++ b/libexec/cron/cron.c
@@ -16,7 +16,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: cron.c,v 1.1.1.1 1994/01/05 20:40:13 jtc Exp $";
+static char rcsid[] = "$Id: cron.c,v 1.1.1.2 1994/01/11 19:10:45 jtc Exp $";
#endif
@@ -177,10 +177,10 @@ cron_tick(db)
* like many bizarre things, it's the standard.
*/
for (u = db->head; u != NULL; u = u->next) {
- Debug(DSCH|DEXT, ("user [%s:%d:%d:...]\n",
- env_get("LOGNAME", u->envp), u->uid, u->gid))
for (e = u->crontab; e != NULL; e = e->next) {
- Debug(DSCH|DEXT, ("entry [%s]\n", e->cmd))
+ Debug(DSCH|DEXT, ("user [%s:%d:%d:...] cmd=\"%s\"\n",
+ env_get("LOGNAME", e->envp),
+ e->uid, e->gid, e->cmd))
if (bit_test(e->minute, minute)
&& bit_test(e->hour, hour)
&& bit_test(e->month, month)
diff --git a/libexec/cron/cron.h b/libexec/cron/cron.h
index c5c2a86115c..cf601ff8a7b 100644
--- a/libexec/cron/cron.h
+++ b/libexec/cron/cron.h
@@ -17,7 +17,7 @@
/* cron.h - header for vixie's cron
*
- * $Id: cron.h,v 1.1.1.1 1994/01/05 20:40:13 jtc Exp $
+ * $Id: cron.h,v 1.1.1.2 1994/01/11 19:10:48 jtc Exp $
*
* vix 14nov88 [rest of log is in RCS]
* vix 14jan87 [0 or 7 can be sunday; thanks, mwm@berkeley]
@@ -33,6 +33,7 @@
#include <stdio.h>
#include <ctype.h>
#include <bitstring.h>
+#include <pwd.h>
#include <sys/wait.h>
#include "pathnames.h"
@@ -144,6 +145,9 @@
typedef struct _entry {
struct _entry *next;
+ uid_t uid;
+ gid_t gid;
+ char **envp;
char *cmd;
bitstr_t bit_decl(minute, MINUTE_COUNT);
bitstr_t bit_decl(hour, HOUR_COUNT);
@@ -151,23 +155,21 @@ typedef struct _entry {
bitstr_t bit_decl(month, MONTH_COUNT);
bitstr_t bit_decl(dow, DOW_COUNT);
int flags;
-#define DOM_STAR 0x1
-#define DOW_STAR 0x2
-#define WHEN_REBOOT 0x4
- uid_t exec_uid; /* 0 = default, else uid */
+#define DOM_STAR 0x01
+#define DOW_STAR 0x02
+#define WHEN_REBOOT 0x04
} entry;
/* the crontab database will be a list of the
- * following structure, one element per user.
+ * following structure, one element per user
+ * plus one for the system.
*
* These are the crontabs.
*/
typedef struct _user {
struct _user *next, *prev; /* links */
- uid_t uid; /* uid from passwd file */
- gid_t gid; /* gid from passwd file */
- char **envp; /* environ for commands */
+ char *name;
time_t mtime; /* last modtime of crontab */
entry *crontab; /* this person's crontab */
} user;
@@ -189,6 +191,7 @@ void set_cron_uid __P((void)),
link_user __P((cron_db *, user *)),
unlink_user __P((cron_db *, user *)),
free_user __P((user *)),
+ env_free __P((char **)),
unget_char __P((int, FILE *)),
free_entry __P((entry *)),
acquire_daemonlock __P((int)),
@@ -211,12 +214,14 @@ char *env_get __P((char *, char **)),
*mkprints __P((unsigned char *, unsigned int)),
*first_word __P((char *, char *)),
**env_init __P((void)),
+ **env_copy __P((char **)),
**env_set __P((char **, char *));
-user *load_user __P((int, char *, int, int, char *, int)),
+user *load_user __P((int, struct passwd *, char *)),
*find_user __P((cron_db *, char *));
-entry *load_entry __P((FILE *, void (*)(), int));
+entry *load_entry __P((FILE *, void (*)(),
+ struct passwd *, char **));
FILE *cron_popen __P((char *, char *));
diff --git a/libexec/cron/crontab.5 b/libexec/cron/crontab.5
index ff33e3ce99b..e1f3d29aabe 100644
--- a/libexec/cron/crontab.5
+++ b/libexec/cron/crontab.5
@@ -15,7 +15,7 @@
.\" * Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul
.\" */
.\"
-.\" $Id: crontab.5,v 1.1.1.1 1994/01/05 20:40:14 jtc Exp $
+.\" $Id: crontab.5,v 1.1.1.2 1994/01/11 19:10:51 jtc Exp $
.\"
.TH CRONTAB 5 "20 December 1993"
.UC 4
@@ -57,17 +57,15 @@ leading or trailing blanks.
Several environment variables are set up
automatically by the
.IR cron (8)
-daemon from the /etc/passwd line of the crontab's owner: USER, HOME, and SHELL.
-HOME and SHELL may be overridden by settings in the crontab; USER may not.
+daemon.
+SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd
+line of the crontab's owner.
+HOME and SHELL may be overridden by settings in the crontab; LOGNAME may not.
.PP
-(Note: for UUCP, always set SHELL=/bin/sh, or
-.IR cron (8)
-will cheerfully try to execute your commands using /usr/lib/uucp/uucico.)
-.PP
-(Another note: the USER variable is sometimes called LOGNAME or worse on
-System V... on these systems, LOGNAME will be set rather than USER.)
+(Another note: the LOGNAME variable is sometimes called USER on BSD systems...
+on these systems, USER will be set also.)
.PP
-In addition to USER, HOME, and SHELL,
+In addition to LOGNAME, HOME, and SHELL,
.IR cron (8)
will look at MAILTO if it has any reason to send mail as a result of running
commands in ``this'' crontab. If MAILTO is defined (and non-empty), mail is
diff --git a/libexec/cron/crontab.c b/libexec/cron/crontab.c
index a8b3da21f29..fb1e23005ba 100644
--- a/libexec/cron/crontab.c
+++ b/libexec/cron/crontab.c
@@ -16,7 +16,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: crontab.c,v 1.1.1.1 1994/01/05 20:40:14 jtc Exp $";
+static char rcsid[] = "$Id: crontab.c,v 1.1.1.2 1994/01/11 19:10:56 jtc Exp $";
#endif
/* crontab - install and manage per-user crontab files
@@ -30,7 +30,6 @@ static char rcsid[] = "$Id: crontab.c,v 1.1.1.1 1994/01/05 20:40:14 jtc Exp $";
#include "cron.h"
#include "externs.h"
-#include <pwd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/file.h>
@@ -46,20 +45,21 @@ static char rcsid[] = "$Id: crontab.c,v 1.1.1.1 1994/01/05 20:40:14 jtc Exp $";
#endif
-static int Pid;
-static char User[MAX_UNAME], RealUser[MAX_UNAME];
-static char Filename[MAX_FNAME];
-static FILE *NewCrontab;
-static int CheckErrorCount;
+static int Pid;
+static char User[MAX_UNAME], RealUser[MAX_UNAME];
+static char Filename[MAX_FNAME];
+static FILE *NewCrontab;
+static int CheckErrorCount;
static enum { opt_unknown, opt_list, opt_delete, opt_edit, opt_replace }
- Option;
-static void list_cmd __P((void)),
- delete_cmd __P((void)),
- edit_cmd __P((void)),
- replace_cmd __P((void)),
- poke_daemon __P((void)),
- check_error __P((char *)),
- parse_args __P((int c, char *v[]));
+ Option;
+static struct passwd *pw;
+static void list_cmd __P((void)),
+ delete_cmd __P((void)),
+ edit_cmd __P((void)),
+ replace_cmd __P((void)),
+ poke_daemon __P((void)),
+ check_error __P((char *)),
+ parse_args __P((int c, char *v[]));
#define NHEADER_LINES 3
@@ -132,7 +132,6 @@ parse_args(argc, argv)
int argc;
char *argv[];
{
- struct passwd *pw;
int argch;
if (!(pw = getpwuid(getuid()))) {
@@ -158,7 +157,7 @@ parse_args(argc, argv)
"must be privileged to use -u\n");
exit(ERROR_EXIT);
}
- if ((struct passwd *)NULL == getpwnam(optarg))
+ if (!(pw = getpwnam(optarg)))
{
fprintf(stderr, "%s: user `%s' unknown\n",
ProgramName, optarg);
@@ -450,6 +449,7 @@ replace_cmd() {
int ch, eof;
entry *e;
time_t now = time(NULL);
+ char **envp = env_init();
(void) sprintf(n, "tmp.%d", Pid);
(void) sprintf(tn, CRON_TAB(n));
@@ -497,8 +497,8 @@ replace_cmd() {
eof = TRUE;
break;
case FALSE:
- e = load_entry(tmp, check_error, 0);
- if (e) free((void*)e);
+ e = load_entry(tmp, check_error, pw, envp);
+ if (e) free(e);
break;
case TRUE:
break;
diff --git a/libexec/cron/database.c b/libexec/cron/database.c
index 12e8e1bdfc9..bd45e178bd5 100644
--- a/libexec/cron/database.c
+++ b/libexec/cron/database.c
@@ -16,7 +16,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: database.c,v 1.1.1.1 1994/01/05 20:40:15 jtc Exp $";
+static char rcsid[] = "$Id: database.c,v 1.1.1.2 1994/01/11 19:11:03 jtc Exp $";
#endif
/* vix 26jan87 [RCS has the log]
@@ -25,7 +25,6 @@ static char rcsid[] = "$Id: database.c,v 1.1.1.1 1994/01/05 20:40:15 jtc Exp $";
#include "cron.h"
#include "externs.h"
-#include <pwd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/file.h>
@@ -81,15 +80,6 @@ load_database(old_db)
return;
}
- /* we used to keep this dir open all the time, for the sake of
- * efficiency. however, we need to close it in every fork, and
- * we fork a lot more often than the mtime of the dir changes.
- */
- if (!(dir = opendir(SPOOL_DIR))) {
- log_it("CRON", getpid(), "OPENDIR FAILED", SPOOL_DIR);
- (void) exit(ERROR_EXIT);
- }
-
/* something's different. make a new database, moving unchanged
* elements from the old database, reloading elements that have
* actually changed. Whatever is left in the old database when
@@ -99,8 +89,18 @@ load_database(old_db)
new_db.head = new_db.tail = NULL;
if (syscron_stat.st_mtime) {
- process_crontab("root", "*root*", SYSCRONTAB,
- &syscron_stat, &new_db, old_db);
+ process_crontab("root", "*system*",
+ SYSCRONTAB, &syscron_stat,
+ &new_db, old_db);
+ }
+
+ /* we used to keep this dir open all the time, for the sake of
+ * efficiency. however, we need to close it in every fork, and
+ * we fork a lot more often than the mtime of the dir changes.
+ */
+ if (!(dir = opendir(SPOOL_DIR))) {
+ log_it("CRON", getpid(), "OPENDIR FAILED", SPOOL_DIR);
+ (void) exit(ERROR_EXIT);
}
while (NULL != (dp = readdir(dir))) {
@@ -133,7 +133,7 @@ load_database(old_db)
*/
Debug(DLOAD, ("unlinking old database:\n"))
for (u = old_db->head; u != NULL; u = nu) {
- Debug(DLOAD, ("\t%s\n", env_get("LOGNAME", u->envp)))
+ Debug(DLOAD, ("\t%s\n", u->name))
nu = u->next;
unlink_user(old_db, u);
free_user(u);
@@ -141,7 +141,6 @@ load_database(old_db)
/* overwrite the database control block with the new one.
*/
- Debug(DLOAD, ("installing new database\n"))
*old_db = new_db;
Debug(DLOAD, ("load_database is done\n"))
}
@@ -188,7 +187,7 @@ find_user(db, name)
user *u;
for (u = db->head; u != NULL; u = u->next)
- if (!strcmp(env_get("LOGNAME", u->envp), name))
+ if (!strcmp(u->name, name))
break;
return u;
}
@@ -196,18 +195,18 @@ find_user(db, name)
static void
process_crontab(uname, fname, tabname, statbuf, new_db, old_db)
- char *uname; /* these are the same except for */
- char *fname; /* *root* processing /etc/crontab */
+ char *uname;
+ char *fname;
char *tabname;
struct stat *statbuf;
cron_db *new_db;
cron_db *old_db;
{
- struct passwd *pw;
- int crontab_fd = OK - 1;
- user *u;
+ struct passwd *pw = NULL;
+ int crontab_fd = OK - 1;
+ user *u;
- if (NULL == (pw = getpwnam(uname))) {
+ if (strcmp(fname, "*system*") && !(pw = getpwnam(uname))) {
/* file doesn't have a user in passwd file.
*/
log_it(fname, getpid(), "ORPHAN", "no passwd entry");
@@ -252,8 +251,7 @@ process_crontab(uname, fname, tabname, statbuf, new_db, old_db)
unlink_user(old_db, u);
free_user(u);
}
- u = load_user(crontab_fd, pw->pw_name, pw->pw_uid, pw->pw_gid,
- pw->pw_dir, (!strcmp(fname, "*root*"))); /* XXX cookie */
+ u = load_user(crontab_fd, pw, fname);
if (u != NULL) {
u->mtime = statbuf->st_mtime;
link_user(new_db, u);
diff --git a/libexec/cron/do_command.c b/libexec/cron/do_command.c
index d963e55882e..da889b05ee8 100644
--- a/libexec/cron/do_command.c
+++ b/libexec/cron/do_command.c
@@ -16,16 +16,13 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: do_command.c,v 1.1.1.1 1994/01/05 20:40:15 jtc Exp $";
+static char rcsid[] = "$Id: do_command.c,v 1.1.1.2 1994/01/11 19:11:07 jtc Exp $";
#endif
#include "cron.h"
#include "externs.h"
-#include <pwd.h>
-#ifdef USE_SIGCHLD
-# include <sys/signal.h>
-#endif
+#include <sys/signal.h>
#if defined(sequent)
# include <sys/universe.h>
#endif
@@ -44,7 +41,7 @@ do_command(e, u)
user *u;
{
Debug(DPROC, ("[%d] do_command(%s, (%s,%d,%d))\n",
- getpid(), e->cmd, env_get("LOGNAME", u->envp), u->uid, u->gid))
+ getpid(), e->cmd, u->name, e->uid, e->gid))
/* fork to become asynchronous -- parent process is done immediately,
* and continues to run the normal cron code, which means return to
@@ -78,10 +75,9 @@ child_process(e, u)
user *u;
{
int stdin_pipe[2], stdout_pipe[2];
- register char *input_data, *usernm, *mailto;
-#ifdef USE_SIGCHLD
+ register char *input_data;
+ char *usernm, *mailto;
int children = 0;
-#endif
Debug(DPROC, ("[%d] child_process('%s')\n", getpid(), e->cmd))
@@ -97,20 +93,22 @@ child_process(e, u)
/* discover some useful and important environment settings
*/
- usernm = env_get("LOGNAME", u->envp);
- mailto = env_get("MAILTO", u->envp);
+ usernm = env_get("LOGNAME", e->envp);
+ mailto = env_get("MAILTO", e->envp);
#ifdef USE_SIGCHLD
/* our parent is watching for our death by catching SIGCHLD. we
* do not care to watch for our children's deaths this way -- we
* use wait() explictly. so we have to disable the signal (which
* was inherited from the parent).
- *
- * this isn't needed for system V, since our parent is already
- * SIG_IGN on SIGCLD -- which, hopefully, will cause children to
- * simply vanish when they die.
*/
(void) signal(SIGCHLD, SIG_IGN);
+#else
+ /* on system-V systems, we are ignoring SIGCLD. we have to stop
+ * ignoring it now or the wait() in cron_pclose() won't work.
+ * because of this, we have to wait() for our children here, as well.
+ */
+ (void) signal(SIGCLD, SIG_DFL);
#endif /*BSD*/
/* create some pipes to talk to our future child
@@ -146,11 +144,16 @@ child_process(e, u)
}
}
- /* fork again, this time so we can exec the user's command. Vfork()
- * is okay this time, since we are going to exec() pretty quickly.
+ /* fork again, this time so we can exec the user's command.
*/
- if (vfork() == 0) {
- Debug(DPROC, ("[%d] grandchild process Vfork()'ed\n", getpid()))
+ switch (vfork()) {
+ case -1:
+ log_it("CRON",getpid(),"error","can't vfork");
+ exit(ERROR_EXIT);
+ /*NOTREACHED*/
+ case 0:
+ Debug(DPROC, ("[%d] grandchild process Vfork()'ed\n",
+ getpid()))
/* write a log message. we've waited this long to do it
* because it was not until now that we knew the PID that
@@ -204,25 +207,17 @@ child_process(e, u)
/* set our directory, uid and gid. Set gid first, since once
* we set uid, we've lost root privledges.
*/
- setgid(u->gid);
+ setgid(e->gid);
# if defined(BSD)
- initgroups(env_get("LOGNAME", u->envp), u->gid);
+ initgroups(env_get("LOGNAME", e->envp), e->gid);
# endif
- /*
- * switch to specified user id. exec_uid is only
- * valid for /etc/crontab, in other environments it
- * will be 0. Note that it is overloaded for root
- * because if 0 it will still pickup u->uid which will
- * still be 0.
- */
- setuid(e->exec_uid ? e->exec_uid : u->uid);
- /* you aren't root after this... */
- chdir(env_get("HOME", u->envp));
+ setuid(e->uid); /* we aren't root after this... */
+ chdir(env_get("HOME", e->envp));
/* exec the command.
*/
{
- char *shell = env_get("SHELL", u->envp);
+ char *shell = env_get("SHELL", e->envp);
# if DEBUGGING
if (DebugFlags & DTEST) {
@@ -233,16 +228,18 @@ child_process(e, u)
_exit(OK_EXIT);
}
# endif /*DEBUGGING*/
- execle(shell, shell, "-c", e->cmd, (char *)0, u->envp);
+ execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);
fprintf(stderr, "execl: couldn't exec `%s'\n", shell);
perror("execl");
_exit(ERROR_EXIT);
}
+ break;
+ default:
+ /* parent process */
+ break;
}
-#ifdef USE_SIGCHLD
children++;
-#endif
/* middle process, child of original cron, parent of process running
* the user's command.
@@ -318,9 +315,7 @@ child_process(e, u)
*/
close(stdin_pipe[WRITE_PIPE]);
-#ifdef USE_SIGCHLD
children++;
-#endif
/*
* read output from the grandchild. it's stderr has been redirected to
@@ -387,7 +382,7 @@ child_process(e, u)
fprintf(mail, "Date: %s\n",
arpadate(&TargetTime));
# endif /* MAIL_DATE */
- for (env = u->envp; *env; env++)
+ for (env = e->envp; *env; env++)
fprintf(mail, "X-Cron-Env: <%s>\n",
*env);
fprintf(mail, "\n");
@@ -445,7 +440,6 @@ child_process(e, u)
fclose(in); /* also closes stdout_pipe[READ_PIPE] */
}
-#ifdef USE_SIGCHLD
/* wait for children to die.
*/
for (; children > 0; children--)
@@ -467,7 +461,6 @@ child_process(e, u)
Debug(DPROC, (", dumped core"))
Debug(DPROC, ("\n"))
}
-#endif /*BSD*/
}
@@ -480,14 +473,12 @@ do_univ(u)
* the passed user structure into the ATT universe if
* necessary. We have to dig the gecos info out of
* the user's password entry to see if the magic
- * "universe(att)" string is present. If we do change
- * the universe, also set "LOGNAME".
+ * "universe(att)" string is present.
*/
struct passwd *p;
char *s;
int i;
- char envstr[MAX_ENVSTR], **env_set();
p = getpwuid(u->uid);
(void) endpwent();
@@ -506,9 +497,6 @@ do_univ(u)
if (strcmp(s, "universe(att)"))
return;
- (void) sprintf(envstr, "LOGNAME=%s", p->pw_name);
- u->envp = env_set(u->envp, envstr);
-
(void) universe(U_ATT);
#endif
}
diff --git a/libexec/cron/entry.c b/libexec/cron/entry.c
index 3dd265502c5..bd3ccee7b82 100644
--- a/libexec/cron/entry.c
+++ b/libexec/cron/entry.c
@@ -16,7 +16,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: entry.c,v 1.1.1.1 1994/01/05 20:40:15 jtc Exp $";
+static char rcsid[] = "$Id: entry.c,v 1.1.1.2 1994/01/11 19:11:11 jtc Exp $";
#endif
/* vix 26jan87 [RCS'd; rest of log is in RCS file]
@@ -28,7 +28,6 @@ static char rcsid[] = "$Id: entry.c,v 1.1.1.1 1994/01/05 20:40:15 jtc Exp $";
#include "cron.h"
#include "externs.h"
-#include <pwd.h>
typedef enum ecode {
@@ -60,15 +59,17 @@ free_entry(e)
entry *e;
{
free(e->cmd);
+ env_free(e->envp);
free(e);
}
entry *
-load_entry(file, error_func, syscron)
- FILE *file;
- void (*error_func)();
- int syscron;
+load_entry(file, error_func, pw, envp)
+ FILE *file;
+ void (*error_func)();
+ struct passwd *pw;
+ char **envp;
{
/* this function reads one crontab entry -- the next -- from a file.
* it skips any leading blank lines, ignores comments, and returns
@@ -87,8 +88,7 @@ load_entry(file, error_func, syscron)
entry *e;
int ch;
char cmd[MAX_COMMAND];
-
- e = (entry *) calloc(sizeof(entry), sizeof(char));
+ char envstr[MAX_ENVSTR];
Debug(DPARS, ("load_entry()...about to eat comments\n"))
@@ -103,6 +103,8 @@ load_entry(file, error_func, syscron)
* of a list of minutes.
*/
+ e = (entry *) calloc(sizeof(entry), sizeof(char));
+
if (ch == '@') {
/* all of these should be flagged and load-limited; i.e.,
* instead of @hourly meaning "0 * * * *" it should mean
@@ -217,9 +219,7 @@ load_entry(file, error_func, syscron)
/* ch is the first character of a command, or a username */
unget_char(ch, file);
- e->exec_uid = 0; /* default to user */
- if (syscron) {
- struct passwd *pw;
+ if (!pw) {
char *username = cmd; /* temp buffer */
Debug(DPARS, ("load_entry()...about to parse username\n"))
@@ -236,15 +236,41 @@ load_entry(file, error_func, syscron)
ecode = e_username;
goto eof;
}
- Debug(DPARS, ("load_entry()...id %d\n",pw->pw_uid))
- e->exec_uid = pw->pw_uid;
+ Debug(DPARS, ("load_entry()...uid %d, gid %d\n",e->uid,e->gid))
}
+ e->uid = pw->pw_uid;
+ e->gid = pw->pw_gid;
+
+ /* copy and fix up environment. some variables are just defaults and
+ * others are overrides.
+ */
+ e->envp = env_copy(envp);
+ if (!env_get("SHELL", e->envp)) {
+ sprintf(envstr, "SHELL=%s", _PATH_BSHELL);
+ e->envp = env_set(e->envp, envstr);
+ }
+ if (!env_get("HOME", e->envp)) {
+ sprintf(envstr, "HOME=%s", pw->pw_dir);
+ e->envp = env_set(e->envp, envstr);
+ }
+ if (!env_get("PATH", e->envp)) {
+ sprintf(envstr, "PATH=%s", _PATH_DEFPATH);
+ e->envp = env_set(e->envp, envstr);
+ }
+ sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name);
+ e->envp = env_set(e->envp, envstr);
+#if defined(BSD)
+ sprintf(envstr, "%s=%s", "USER", pw->pw_name);
+ e->envp = env_set(e->envp, envstr);
+#endif
+
Debug(DPARS, ("load_entry()...about to parse command\n"))
/* Everything up to the next \n or EOF is part of the command...
* too bad we don't know in advance how long it will be, since we
- * need to malloc a string for it... so, we limit it to MAX_COMMAND
+ * need to malloc a string for it... so, we limit it to MAX_COMMAND.
+ * XXX - should use realloc().
*/
ch = get_string(cmd, MAX_COMMAND, file, "\n");
@@ -293,7 +319,7 @@ eof: /* if we want to return EOF, we have to jump down here and
while (ch != EOF && ch != '\n');
if (ch == EOF)
return NULL;
- return load_entry(file, error_func, 0);
+ return load_entry(file, error_func, pw, envp);
}
diff --git a/libexec/cron/env.c b/libexec/cron/env.c
index f1ec5dbab7a..55d6e49bdc0 100644
--- a/libexec/cron/env.c
+++ b/libexec/cron/env.c
@@ -16,7 +16,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: env.c,v 1.1.1.1 1994/01/05 20:40:15 jtc Exp $";
+static char rcsid[] = "$Id: env.c,v 1.1.1.2 1994/01/11 19:11:13 jtc Exp $";
#endif
@@ -34,6 +34,35 @@ env_init()
}
+void
+env_free(envp)
+ char **envp;
+{
+ char **p;
+
+ for (p = envp; *p; p++)
+ free(*p);
+ free(envp);
+}
+
+
+char **
+env_copy(envp)
+ register char **envp;
+{
+ register int count, i;
+ register char **p;
+
+ for (count = 0; envp[count] != NULL; count++)
+ ;
+ p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */
+ for (i = 0; i < count; i++)
+ p[i] = strdup(envp[i]);
+ p[count] = NULL;
+ return p;
+}
+
+
char **
env_set(envp, envstr)
char **envp;
@@ -51,8 +80,7 @@ env_set(envp, envstr)
if (!strcmp_until(envp[count], envstr, '='))
found = count;
}
- count++; /* for the null pointer
- */
+ count++; /* for the NULL */
if (found != -1) {
/*
@@ -135,11 +163,13 @@ load_env(envstr, f)
char *
env_get(name, envp)
- char *name;
- char **envp;
+ register char *name;
+ register char **envp;
{
- for (; *envp; envp++)
- if (!strcmp_until(*envp, name, '='))
- return strchr(*envp, '=') + 1;
+ for (; *envp; envp++) {
+ register char *p = strchr(*envp, '=');
+ if (p && !strncmp(*envp, name, p - *envp))
+ return p+1;
+ }
return NULL;
}
diff --git a/libexec/cron/user.c b/libexec/cron/user.c
index b423c2c64ac..186ec290aa9 100644
--- a/libexec/cron/user.c
+++ b/libexec/cron/user.c
@@ -16,7 +16,7 @@
*/
#if !defined(lint) && !defined(LINT)
-static char rcsid[] = "$Id: user.c,v 1.1.1.1 1994/01/05 20:40:16 jtc Exp $";
+static char rcsid[] = "$Id: user.c,v 1.1.1.2 1994/01/11 19:11:32 jtc Exp $";
#endif
/* vix 26jan87 [log is in RCS file]
@@ -32,33 +32,28 @@ free_user(u)
user *u;
{
entry *e, *ne;
- char **env;
+ free(u->name);
for (e = u->crontab; e != NULL; e = ne) {
ne = e->next;
free_entry(e);
}
- for (env = u->envp; *env; env++)
- (void) free(*env);
- (void) free(u->envp);
- (void) free(u);
+ free(u);
}
user *
-load_user(crontab_fd, name, uid, gid, dir, syscron)
- int crontab_fd;
- char *name;
- int uid;
- int gid;
- char *dir;
- int syscron; /* system crontab file? */
+load_user(crontab_fd, pw, name)
+ int crontab_fd;
+ struct passwd *pw; /* NULL implies syscrontab */
+ char *name;
{
char envstr[MAX_ENVSTR];
FILE *file;
user *u;
entry *e;
int status;
+ char **envp;
if (!(file = fdopen(crontab_fd, "r"))) {
perror("fdopen on crontab_fd in load_user");
@@ -70,50 +65,39 @@ load_user(crontab_fd, name, uid, gid, dir, syscron)
/* file is open. build user entry, then read the crontab file.
*/
u = (user *) malloc(sizeof(user));
- u->uid = uid;
- u->gid = gid;
- u->envp = env_init();
+ u->name = strdup(name);
u->crontab = NULL;
- /*
- * do auto env settings that the user could reset in the cron tab
+ /*
+ * init environment. this will be copied/augmented for each entry.
*/
- sprintf(envstr, "SHELL=%s", _PATH_BSHELL);
- u->envp = env_set(u->envp, envstr);
-
- sprintf(envstr, "HOME=%s", dir);
- u->envp = env_set(u->envp, envstr);
+ envp = env_init();
- /* load the crontab
+ /*
+ * load the crontab
*/
while ((status = load_env(envstr, file)) >= OK) {
- if (status == TRUE) {
- u->envp = env_set(u->envp, envstr);
- } else {
- if (NULL != (e = load_entry(file, NULL, syscron))) {
+ switch (status) {
+ case ERR:
+ free_user(u);
+ u = NULL;
+ goto done;
+ case FALSE:
+ e = load_entry(file, NULL, pw, envp);
+ if (e) {
e->next = u->crontab;
u->crontab = e;
}
+ break;
+ case TRUE:
+ envp = env_set(envp, envstr);
+ break;
}
}
- /*
- * do automatic env settings that should have precedence over any
- * set in the cron tab.
- */
- sprintf(envstr, "%s=%s", "LOGNAME", name);
- u->envp = env_set(u->envp, envstr);
-#if defined(BSD)
- sprintf(envstr, "%s=%s", "USER", name);
- u->envp = env_set(u->envp, envstr);
-#endif
-
- /*
- * done. close file, return pointer to 'user' structure
- */
+ done:
+ env_free(envp);
fclose(file);
-
Debug(DPARS, ("...load_user() done\n"))
-
return u;
}