--- trunk/mkinitrd-magellan/busybox/miscutils/crond.c 2010/04/29 20:38:48 983 +++ trunk/mkinitrd-magellan/busybox/miscutils/crond.c 2010/05/30 11:32:42 984 @@ -23,17 +23,13 @@ #endif -#ifndef CRONTABS -#define CRONTABS "/var/spool/cron/crontabs" -#endif -#ifndef TMPDIR -#define TMPDIR "/var/spool/cron" -#endif +#define TMPDIR CONFIG_FEATURE_CROND_DIR +#define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs" #ifndef SENDMAIL #define SENDMAIL "sendmail" #endif #ifndef SENDMAIL_ARGS -#define SENDMAIL_ARGS "-ti", "oem" +#define SENDMAIL_ARGS "-ti", NULL #endif #ifndef CRONUPDATE #define CRONUPDATE "cron.update" @@ -59,7 +55,7 @@ #if ENABLE_FEATURE_CROND_CALL_SENDMAIL int cl_MailPos; /* 'empty file' size */ smallint cl_MailFlag; /* running pid is for mail */ - char *cl_MailTo; /* whom to mail results */ + char *cl_MailTo; /* whom to mail results */ #endif /* ordered by size, not in natural order. makes code smaller: */ char cl_Dow[7]; /* 0-6, beginning sunday */ @@ -126,15 +122,16 @@ static void DeleteFile(const char *userName); +/* 0 is the most verbose, default 8 */ #define LVL5 "\x05" #define LVL7 "\x07" #define LVL8 "\x08" -#define LVL9 "\x09" #define WARN9 "\x49" #define DIE9 "\xc9" /* level >= 20 is "error" */ #define ERR20 "\x14" +static void crondlog(const char *ctl, ...) __attribute__ ((format (printf, 1, 2))); static void crondlog(const char *ctl, ...) { va_list va; @@ -146,12 +143,20 @@ /* Syslog mode: all to syslog (logmode = LOGMODE_SYSLOG), */ if (!DebugOpt && LogFile) { /* Otherwise (log to file): we reopen log file at every write: */ - int logfd = open3_or_warn(LogFile, O_WRONLY | O_CREAT | O_APPEND, 0600); + int logfd = open3_or_warn(LogFile, O_WRONLY | O_CREAT | O_APPEND, 0666); if (logfd >= 0) xmove_fd(logfd, STDERR_FILENO); } -// TODO: ERR -> error, WARN -> warning, LVL -> info - bb_verror_msg(ctl + 1, va, /* strerr: */ NULL); + /* When we log to syslog, level > 8 is logged at LOG_ERR + * syslog level, level <= 8 is logged at LOG_INFO. */ + if (level > 8) { + bb_verror_msg(ctl + 1, va, /* strerr: */ NULL); + } else { + char *msg = NULL; + vasprintf(&msg, ctl + 1, va); + bb_info_msg("%s: %s", applet_name, msg); + free(msg); + } } va_end(va); if (ctl[0] & 0x80) @@ -161,25 +166,25 @@ int crond_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int crond_main(int argc UNUSED_PARAM, char **argv) { - unsigned opt; + unsigned opts; INIT_G(); /* "-b after -f is ignored", and so on for every pair a-b */ - opt_complementary = "f-b:b-f:S-L:L-S" USE_FEATURE_CROND_D(":d-l") + opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") ":l+:d+"; /* -l and -d have numeric param */ - opt = getopt32(argv, "l:L:fbSc:" USE_FEATURE_CROND_D("d:"), + opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), &LogLevel, &LogFile, &CDir - USE_FEATURE_CROND_D(,&LogLevel)); + IF_FEATURE_CROND_D(,&LogLevel)); /* both -d N and -l N set the same variable: LogLevel */ - if (!(opt & OPT_f)) { + if (!(opts & OPT_f)) { /* close stdin, stdout, stderr. * close unused descriptors - don't need them. */ bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv); } - if (!DebugOpt && LogFile == NULL) { + if (!(opts & OPT_d) && LogFile == NULL) { /* logging to syslog */ openlog(applet_name, LOG_CONS | LOG_PID, LOG_CRON); logmode = LOGMODE_SYSLOG; @@ -188,20 +193,21 @@ xchdir(CDir); //signal(SIGHUP, SIG_IGN); /* ? original crond dies on HUP... */ xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */ - crondlog(LVL9 "crond (busybox "BB_VER") started, log level %d", LogLevel); + crondlog(LVL8 "crond (busybox "BB_VER") started, log level %d", LogLevel); SynchronizeDir(); /* main loop - synchronize to 1 second after the minute, minimum sleep * of 1 second. */ { time_t t1 = time(NULL); - time_t t2; - long dt; int rescan = 60; int sleep_time = 60; write_pidfile("/var/run/crond.pid"); for (;;) { + time_t t2; + long dt; + sleep((sleep_time + 1) - (time(NULL) % sleep_time)); t2 = time(NULL); @@ -231,7 +237,7 @@ if (DebugOpt) crondlog(LVL5 "wakeup dt=%ld", dt); if (dt < -60 * 60 || dt > 60 * 60) { - crondlog(WARN9 "time disparity of %d minutes detected", dt / 60); + crondlog(WARN9 "time disparity of %ld minutes detected", dt / 60); } else if (dt > 0) { TestJobs(t1, t2); RunJobs(); @@ -243,8 +249,9 @@ } } t1 = t2; - } + } /* for (;;) */ } + return 0; /* not reached */ } @@ -252,14 +259,12 @@ /* We set environment *before* vfork (because we want to use vfork), * so we cannot use setenv() - repeated calls to setenv() may leak memory! * Using putenv(), and freeing memory after unsetenv() won't leak */ -static void safe_setenv4(char **pvar_val, const char *var, const char *val /*, int len*/) +static void safe_setenv(char **pvar_val, const char *var, const char *val) { - const int len = 4; /* both var names are 4 char long */ char *var_val = *pvar_val; if (var_val) { - var_val[len] = '\0'; /* nuke '=' */ - unsetenv(var_val); + bb_unsetenv(var_val); free(var_val); } *pvar_val = xasprintf("%s=%s", var, val); @@ -270,10 +275,10 @@ static void SetEnv(struct passwd *pas) { #if SETENV_LEAKS - safe_setenv4(&env_var_user, "USER", pas->pw_name); - safe_setenv4(&env_var_home, "HOME", pas->pw_dir); + safe_setenv(&env_var_user, "USER", pas->pw_name); + safe_setenv(&env_var_home, "HOME", pas->pw_dir); /* if we want to set user's shell instead: */ - /*safe_setenv(env_var_user, "SHELL", pas->pw_shell, 5);*/ + /*safe_setenv(env_var_user, "SHELL", pas->pw_shell);*/ #else xsetenv("USER", pas->pw_name); xsetenv("HOME", pas->pw_dir); @@ -287,7 +292,7 @@ /* careful: we're after vfork! */ change_identity(pas); /* - initgroups, setgid, setuid */ if (chdir(pas->pw_dir) < 0) { - crondlog(LVL9 "can't chdir(%s)", pas->pw_dir); + crondlog(WARN9 "can't chdir(%s)", pas->pw_dir); if (chdir(TMPDIR) < 0) { crondlog(DIE9 "can't chdir(%s)", TMPDIR); /* exits */ } @@ -326,11 +331,13 @@ skip = 1; ++ptr; } else if (isdigit(*ptr)) { + char *endp; if (n1 < 0) { - n1 = strtol(ptr, &ptr, 10) + off; + n1 = strtol(ptr, &endp, 10) + off; } else { - n2 = strtol(ptr, &ptr, 10) + off; + n2 = strtol(ptr, &endp, 10) + off; } + ptr = endp; /* gcc likes temp var for &endp */ skip = 1; } else if (names) { int i; @@ -367,7 +374,9 @@ n2 = n1; } if (*ptr == '/') { - skip = strtol(ptr + 1, &ptr, 10); + char *endp; + skip = strtol(ptr + 1, &endp, 10); + ptr = endp; /* gcc likes temp var for &endp */ } /* @@ -645,14 +654,14 @@ /* Find jobs > t1 and <= t2 */ for (t = t1 - t1 % 60; t <= t2; t += 60) { - struct tm *tp; + struct tm *ptm; CronFile *file; CronLine *line; if (t <= t1) continue; - tp = localtime(&t); + ptm = localtime(&t); for (file = FileBase; file; file = file->cf_Next) { if (DebugOpt) crondlog(LVL5 "file %s:", file->cf_User); @@ -661,9 +670,9 @@ for (line = file->cf_LineBase; line; line = line->cl_Next) { if (DebugOpt) crondlog(LVL5 " line %s", line->cl_Shell); - if (line->cl_Mins[tp->tm_min] && line->cl_Hrs[tp->tm_hour] - && (line->cl_Days[tp->tm_mday] || line->cl_Dow[tp->tm_wday]) - && line->cl_Mons[tp->tm_mon] + if (line->cl_Mins[ptm->tm_min] && line->cl_Hrs[ptm->tm_hour] + && (line->cl_Days[ptm->tm_mday] || line->cl_Dow[ptm->tm_wday]) + && line->cl_Mons[ptm->tm_mon] ) { if (DebugOpt) { crondlog(LVL5 " job: %d %s", @@ -762,7 +771,7 @@ /* prepare things before vfork */ pas = getpwnam(user); if (!pas) { - crondlog(LVL9 "can't get uid for %s", user); + crondlog(WARN9 "can't get uid for %s", user); goto err; } SetEnv(pas); @@ -781,7 +790,7 @@ } /* crond 3.0pl1-100 puts tasks in separate process groups */ bb_setpgrp(); - execlp(prog, prog, cmd, arg, NULL); + execlp(prog, prog, cmd, arg, (char *) NULL); crondlog(ERR20 "can't exec, user %s cmd %s %s %s", user, prog, cmd, arg); if (mail_filename) { fdprintf(1, "Exec failed: %s -c %s\n", prog, arg); @@ -836,7 +845,7 @@ line->cl_Shell); line->cl_MailPos = lseek(mailFd, 0, SEEK_CUR); } else { - crondlog(ERR20 "cannot create mail file %s for user %s, " + crondlog(ERR20 "can't create mail file %s for user %s, " "discarding output", mailFile, user); } } @@ -902,7 +911,7 @@ /* prepare things before vfork */ pas = getpwnam(user); if (!pas) { - crondlog(LVL9 "can't get uid for %s", user); + crondlog(WARN9 "can't get uid for %s", user); goto err; } SetEnv(pas); @@ -918,7 +927,7 @@ } /* crond 3.0pl1-100 puts tasks in separate process groups */ bb_setpgrp(); - execl(DEFAULT_SHELL, DEFAULT_SHELL, "-c", line->cl_Shell, NULL); + execl(DEFAULT_SHELL, DEFAULT_SHELL, "-c", line->cl_Shell, (char *) NULL); crondlog(ERR20 "can't exec, user %s cmd %s %s %s", user, DEFAULT_SHELL, "-c", line->cl_Shell); _exit(EXIT_SUCCESS);