Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:kernel-2.6.32
cron
vixie-cron-4.1-syscrondir.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File vixie-cron-4.1-syscrondir.diff of Package cron
--- vixie-cron-4.1/database.c +++ vixie-cron-4.1/database.c @@ -34,13 +34,18 @@ const char *, struct stat *, cron_db *, cron_db *); +static user *get_next_system_crontab(user *curtab); + void load_database(cron_db *old_db) { - struct stat statbuf, syscron_stat; + struct stat statbuf, syscron_stat, crond_stat; cron_db new_db; DIR_T *dp; DIR *dir; user *u, *nu; + time_t syscrond_files_mtime; + char syscrond_fname[MAXPATHLEN+1]; + Debug(DLOAD, ("[%ld] load_database()\n", (long)getpid())) @@ -53,11 +58,57 @@ (void) exit(ERROR_EXIT); } + if (stat(SYSCRONDIR, &crond_stat) < OK) { + log_it("CRON", getpid(), "STAT FAILED", SYSCRONDIR); + (void) exit(ERROR_EXIT); + } + /* track system crontab file */ if (stat(SYSCRONTAB, &syscron_stat) < OK) syscron_stat.st_mtime = 0; + /* Check mod time of SYSCRONDIR. This won't tell us if a file + * in it changed, but will capture deletions, which the individual + * file check won't + */ + if (stat(SYSCRONDIR, &crond_stat) < OK) { + log_it("CRON", getpid(), "STAT FAILED", SYSCRONDIR); + (void) exit(ERROR_EXIT); + } + syscrond_files_mtime = crond_stat.st_mtime; + + /* If SYSCRONDIR was modified, we know that something is changed and + * there is no need for any further checks. If it wasn't, we should + * pass through the old list of files in SYSCRONDIR and check their + * mod time. Therefore a stopped hard drive won't be spun up, since + * we avoid reading of SYSCRONDIR and don't change its access time. + * This is especially important on laptops with APM. + */ + if (old_db->mtime >= syscrond_files_mtime) { + user *systab; + + Debug(DLOAD, ("[%d] system dir mtime unch, check files now.\n", + getpid())); + + for (systab = old_db->head; + (systab = get_next_system_crontab (systab)) != NULL; + systab = systab->next) { + + snprintf(syscrond_fname, MAXPATHLEN, "%s/%s", + SYSCRONDIR, systab->name + 8); + + Debug(DLOAD, ("\t%s:", syscrond_fname)); + + if (stat(syscrond_fname, &crond_stat) < OK) + crond_stat.st_mtime = 0; + syscrond_files_mtime = TMAX(syscrond_files_mtime, + crond_stat.st_mtime); + + Debug(DLOAD, (" [checked]\n")); + } + } + /* if spooldir's mtime has not changed, we don't need to fiddle with * the database. * @@ -65,7 +116,9 @@ * so is guaranteed to be different than the stat() mtime the first * time this function is called. */ - if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) { + if (old_db->mtime == TMAX(crond_stat.st_mtime, + TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) + ){ Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", (long)getpid())) return; @@ -76,13 +129,61 @@ * actually changed. Whatever is left in the old database when * we're done is chaff -- crontabs that disappeared. */ - new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime); + new_db.mtime = TMAX(crond_stat.st_mtime, + TMAX(statbuf.st_mtime, syscron_stat.st_mtime)); new_db.head = new_db.tail = NULL; if (syscron_stat.st_mtime) process_crontab("root", NULL, SYSCRONTAB, &syscron_stat, &new_db, old_db); + if (!(dir = opendir(SYSCRONDIR))) { + log_it("CRON", getpid(), "OPENDIR FAILED", SYSCRONDIR); + (void) exit(ERROR_EXIT); + } + + while (NULL != (dp = readdir(dir))) { + char fname[MAXNAMLEN+1], + tabname[MAXNAMLEN+1]; + size_t len; + + /* avoid file names beginning with ".". this is good + * because we would otherwise waste two guaranteed calls + * to getpwnam() for . and .., and there shouldn't be + * hidden files in here anyway + */ + if (dp->d_name[0] == '.') + continue; + + /* ignore files starting with # and ending with ~ */ + if (dp->d_name[0] == '#') + continue; + + len = strlen(dp->d_name); + + if (len >= sizeof fname) + continue; /* XXX log? */ + + if ((len > 0) && (dp->d_name[len - 1] == '~')) + continue; + + (void) strcpy(fname, dp->d_name); + + if ((len > 8) && (strncmp(fname + len - 8, ".rpmsave", 8) == 0)) + continue; + if ((len > 8) && (strncmp(fname + len - 8, ".rpmorig", 8) == 0)) + continue; + if ((len > 7) && (strncmp(fname + len - 7, ".rpmnew", 7) == 0)) + continue; + + if (!glue_strings(tabname, sizeof tabname, SYSCRONDIR, fname, '/')) + continue; /* XXX log? */ + + process_crontab("root", NULL, tabname, + &crond_stat, &new_db, old_db); + } + closedir(dir); + /* 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. @@ -257,3 +358,11 @@ close(crontab_fd); } } + +static user *get_next_system_crontab(user *curtab) +{ + for ( ; curtab != NULL; curtab = curtab->next) + if (!strncmp(curtab->name, "*system*", 8) && curtab->name[8]) + break; + return curtab; +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor