diff options
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/cron/cron.c | 8 | ||||
| -rw-r--r-- | libexec/cron/cron.h | 27 | ||||
| -rw-r--r-- | libexec/cron/crontab.5 | 18 | ||||
| -rw-r--r-- | libexec/cron/crontab.c | 38 | ||||
| -rw-r--r-- | libexec/cron/database.c | 46 | ||||
| -rw-r--r-- | libexec/cron/do_command.c | 80 | ||||
| -rw-r--r-- | libexec/cron/entry.c | 56 | ||||
| -rw-r--r-- | libexec/cron/env.c | 46 | ||||
| -rw-r--r-- | libexec/cron/user.c | 72 |
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; } |
