Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/cron/cron/database.c
/* Copyright 1988,1990,1993,1994 by Paul Vixie | /* Copyright 1988,1990,1993,1994 by Paul Vixie | ||||
* All rights reserved | * All rights reserved | ||||
*/ | |||||
/* | |||||
* Copyright (c) 1997 by Internet Software Consortium | |||||
* | * | ||||
* Distribute freely, except: don't remove my name from the source or | * Permission to use, copy, modify, and distribute this software for any | ||||
* documentation (don't take credit for my work), mark your changes (don't | * purpose with or without fee is hereby granted, provided that the above | ||||
* get me blamed for your possible bugs), don't alter or remove this | * copyright notice and this permission notice appear in all copies. | ||||
* notice. May be sold if buildable source is provided to buyer. No | |||||
* warrantee of any kind, express or implied, is included with this | |||||
* software; use at your own risk, responsibility for damages (if any) to | |||||
* anyone resulting from the use of this software rests entirely with the | |||||
* user. | |||||
* | * | ||||
* Send bug reports, bug fixes, enhancements, requests, flames, etc., and | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS | ||||
* I'll try to keep a version up to date. I can be reached as follows: | * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||||
* Paul Vixie <paul@vix.com> uunet!decwrl!vixie!paul | * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE | ||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR | |||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||||
* SOFTWARE. | |||||
*/ | */ | ||||
#if !defined(lint) && !defined(LINT) | #if !defined(lint) && !defined(LINT) | ||||
static const char rcsid[] = | static const char rcsid[] = | ||||
"$FreeBSD$"; | "$Id: database.c,v 1.3 1998/08/14 00:32:38 vixie Exp $"; | ||||
#endif | #endif | ||||
/* vix 26jan87 [RCS has the log] | /* vix 26jan87 [RCS has the log] | ||||
*/ | */ | ||||
#include "cron.h" | #include "cron.h" | ||||
#include <fcntl.h> | |||||
#include <sys/stat.h> | |||||
#include <sys/file.h> | |||||
#define TMAX(a,b) ((a)>(b)?(a):(b)) | #define TMAX(a,b) ((a)>(b)?(a):(b)) | ||||
static void process_crontab(const char *, const char *, | |||||
static void process_crontab(char *, char *, char *, | const char *, struct stat *, | ||||
struct stat *, | |||||
cron_db *, cron_db *); | cron_db *, cron_db *); | ||||
void | void | ||||
load_database(cron_db *old_db) | load_database(cron_db *old_db) | ||||
{ | { | ||||
DIR *dir; | struct stat statbuf, syscron_stat, st; | ||||
struct stat statbuf; | |||||
struct stat syscron_stat, st; | |||||
time_t maxmtime; | |||||
DIR_T *dp; | |||||
cron_db new_db; | cron_db new_db; | ||||
DIR_T *dp; | |||||
DIR *dir; | |||||
user *u, *nu; | user *u, *nu; | ||||
time_t maxmtime; | |||||
struct { | struct { | ||||
const char *name; | const char *name; | ||||
struct stat st; | struct stat st; | ||||
} syscrontabs [] = { | } syscrontabs [] = { | ||||
{ SYSCRONTABS }, | { SYSCRONTABS }, | ||||
{ LOCALSYSCRONTABS } | { LOCALSYSCRONTABS } | ||||
}; | }; | ||||
int i, ret; | int i, ret; | ||||
▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | load_database(cron_db *old_db) | ||||
* we fork a lot more often than the mtime of the dir changes. | * we fork a lot more often than the mtime of the dir changes. | ||||
*/ | */ | ||||
if (!(dir = opendir(SPOOL_DIR))) { | if (!(dir = opendir(SPOOL_DIR))) { | ||||
log_it("CRON", getpid(), "OPENDIR FAILED", SPOOL_DIR); | log_it("CRON", getpid(), "OPENDIR FAILED", SPOOL_DIR); | ||||
(void) exit(ERROR_EXIT); | (void) exit(ERROR_EXIT); | ||||
} | } | ||||
while (NULL != (dp = readdir(dir))) { | while (NULL != (dp = readdir(dir))) { | ||||
char fname[MAXNAMLEN+1], | char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; | ||||
tabname[MAXNAMLEN+1]; | |||||
/* avoid file names beginning with ".". this is good | /* avoid file names beginning with ".". this is good | ||||
* because we would otherwise waste two guaranteed calls | * because we would otherwise waste two guaranteed calls | ||||
* to getpwnam() for . and .., and also because user names | * to getpwnam() for . and .., and also because user names | ||||
* starting with a period are just too nasty to consider. | * starting with a period are just too nasty to consider. | ||||
*/ | */ | ||||
if (dp->d_name[0] == '.') | if (dp->d_name[0] == '.') | ||||
continue; | continue; | ||||
(void) strncpy(fname, dp->d_name, sizeof(fname)); | (void) strncpy(fname, dp->d_name, sizeof(fname)); | ||||
fname[sizeof(fname)-1] = '\0'; | fname[sizeof(fname)-1] = '\0'; | ||||
(void) snprintf(tabname, sizeof tabname, CRON_TAB(fname)); | |||||
if (snprintf(tabname, sizeof tabname, CRON_TAB(fname)) | |||||
>= sizeof(tabname)) | |||||
continue; /* XXX log? */ | |||||
process_crontab(fname, fname, tabname, | process_crontab(fname, fname, tabname, | ||||
&statbuf, &new_db, old_db); | &statbuf, &new_db, old_db); | ||||
} | } | ||||
closedir(dir); | closedir(dir); | ||||
/* if we don't do this, then when our children eventually call | /* if we don't do this, then when our children eventually call | ||||
* getpwnam() in do_command.c's child_process to verify MAILTO=, | * getpwnam() in do_command.c's child_process to verify MAILTO=, | ||||
* they will screw us up (and v-v). | * they will screw us up (and v-v). | ||||
Show All 11 Lines | load_database(cron_db *old_db) | ||||
} | } | ||||
/* overwrite the database control block with the new one. | /* overwrite the database control block with the new one. | ||||
*/ | */ | ||||
*old_db = new_db; | *old_db = new_db; | ||||
Debug(DLOAD, ("load_database is done\n")) | Debug(DLOAD, ("load_database is done\n")) | ||||
} | } | ||||
void | void | ||||
link_user(cron_db *db, user *u) | link_user(cron_db *db, user *u) | ||||
{ | { | ||||
if (db->head == NULL) | if (db->head == NULL) | ||||
db->head = u; | db->head = u; | ||||
if (db->tail) | if (db->tail) | ||||
db->tail->next = u; | db->tail->next = u; | ||||
u->prev = db->tail; | u->prev = db->tail; | ||||
u->next = NULL; | u->next = NULL; | ||||
db->tail = u; | db->tail = u; | ||||
} | } | ||||
void | void | ||||
unlink_user(cron_db *db, user *u) | unlink_user(cron_db *db, user *u) | ||||
{ | { | ||||
if (u->prev == NULL) | if (u->prev == NULL) | ||||
db->head = u->next; | db->head = u->next; | ||||
else | else | ||||
u->prev->next = u->next; | u->prev->next = u->next; | ||||
if (u->next == NULL) | if (u->next == NULL) | ||||
db->tail = u->prev; | db->tail = u->prev; | ||||
else | else | ||||
u->next->prev = u->prev; | u->next->prev = u->prev; | ||||
} | } | ||||
user * | user * | ||||
find_user(cron_db *db, char *name) | find_user(cron_db *db, const char *name) | ||||
{ | { | ||||
user *u; | user *u; | ||||
for (u = db->head; u != NULL; u = u->next) | for (u = db->head; u != NULL; u = u->next) | ||||
if (!strcmp(u->name, name)) | if (strcmp(u->name, name) == 0) | ||||
break; | break; | ||||
return u; | return (u); | ||||
} | } | ||||
static void | static void | ||||
process_crontab(char *uname, char *fname, char *tabname, struct stat *statbuf, | process_crontab(const char *uname, const char *fname, const char *tabname, | ||||
cron_db *new_db, cron_db *old_db) | struct stat *statbuf, cron_db *new_db, cron_db *old_db) | ||||
{ | { | ||||
struct passwd *pw = NULL; | struct passwd *pw = NULL; | ||||
int crontab_fd = OK - 1; | int crontab_fd = OK - 1; | ||||
user *u; | user *u; | ||||
entry *e; | entry *e; | ||||
time_t now; | time_t now; | ||||
if (strcmp(fname, SYS_NAME) && !(pw = getpwnam(uname))) { | if (strcmp(fname, SYS_NAME) != 0 && !(pw = getpwnam(uname))) { | ||||
/* file doesn't have a user in passwd file. | /* file doesn't have a user in passwd file. | ||||
*/ | */ | ||||
log_it(fname, getpid(), "ORPHAN", "no passwd entry"); | log_it(fname, getpid(), "ORPHAN", "no passwd entry"); | ||||
goto next_crontab; | goto next_crontab; | ||||
} | } | ||||
if ((crontab_fd = open(tabname, O_RDONLY, 0)) < OK) { | if ((crontab_fd = open(tabname, O_RDONLY, 0)) < OK) { | ||||
/* crontab not accessible? | /* crontab not accessible? | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | if (TargetTime != 0) { | ||||
for (e = u->crontab; e != NULL; e = e->next) { | for (e = u->crontab; e != NULL; e = e->next) { | ||||
if ((e->flags & INTERVAL) != 0) | if ((e->flags & INTERVAL) != 0) | ||||
e->lastexit = now; | e->lastexit = now; | ||||
} | } | ||||
} | } | ||||
link_user(new_db, u); | link_user(new_db, u); | ||||
} | } | ||||
next_crontab: | next_crontab: | ||||
if (crontab_fd >= OK) { | if (crontab_fd >= OK) { | ||||
Debug(DLOAD, (" [done]\n")) | Debug(DLOAD, (" [done]\n")) | ||||
close(crontab_fd); | close(crontab_fd); | ||||
} | } | ||||
} | } |