- opt_complementary = "f-b:b-f:S-L:L-S:d-l";
-#else
- opt_complementary = "f-b:b-f:S-L:L-S";
-#endif
-
- opterr = 0; /* disable getopt 'errors' message. */
- opt = getopt32(ac, av, "l:L:fbSc:"
-#if ENABLE_DEBUG_CROND_OPTION
- "d:"
-#endif
- , &lopt, &Lopt, &copt
-#if ENABLE_DEBUG_CROND_OPTION
- , &dopt
-#endif
- );
- if (opt & 1) {
- LogLevel = xatou(lopt);
- }
- if (opt & 2) {
- if (*Lopt != 0) {
- LogFile = Lopt;
- }
- }
- if (opt & 32) {
- if (*copt != 0) {
- CDir = copt;
- }
- }
-#if ENABLE_DEBUG_CROND_OPTION
- if (opt & 64) {
- DebugOpt = xatou(dopt);
- LogLevel = 0;
- }
-#endif
-
- /*
- * change directory
- */
-
- xchdir(CDir);
- signal(SIGHUP, SIG_IGN); /* hmm.. but, if kill -HUP original
- * version - his died. ;(
- */
- /*
- * close stdin and stdout, stderr.
- * close unused descriptors - don't need.
- * optional detach from controlling terminal
- */
-
- if (!(opt & 4)) {
-#ifdef BB_NOMMU
- /* reexec for vfork() do continue parent */
- vfork_daemon_rexec(1, 0, ac, av, "-f");
-#else
- xdaemon(1, 0);
-#endif
- }
-
- (void) startlogger(); /* need if syslog mode selected */
-
- /*
- * main loop - synchronize to 1 second after the minute, minimum sleep
- * of 1 second.
- */
-
- crondlog("\011%s " VERSION " dillon, started, log level %d\n",
- applet_name, LogLevel);
-
- SynchronizeDir();
-
- {
- time_t t1 = time(NULL);
- time_t t2;
- long dt;
- int rescan = 60;
- short sleep_time = 60;
-
- for (;;) {
- sleep((sleep_time + 1) - (short) (time(NULL) % sleep_time));
-
- t2 = time(NULL);
- dt = t2 - t1;
-
- /*
- * The file 'cron.update' is checked to determine new cron
- * jobs. The directory is rescanned once an hour to deal
- * with any screwups.
- *
- * check for disparity. Disparities over an hour either way
- * result in resynchronization. A reverse-indexed disparity
- * less then an hour causes us to effectively sleep until we
- * match the original time (i.e. no re-execution of jobs that
- * have just been run). A forward-indexed disparity less then
- * an hour causes intermediate jobs to be run, but only once
- * in the worst case.
- *
- * when running jobs, the inequality used is greater but not
- * equal to t1, and less then or equal to t2.
- */
-
- if (--rescan == 0) {
- rescan = 60;
- SynchronizeDir();
- }
- CheckUpdates();
-#if ENABLE_DEBUG_CROND_OPTION
- if (DebugOpt)
- crondlog("\005Wakeup dt=%d\n", dt);
-#endif
- if (dt < -60 * 60 || dt > 60 * 60) {
- t1 = t2;
- crondlog("\111time disparity of %d minutes detected\n", dt / 60);
- } else if (dt > 0) {
- TestJobs(t1, t2);
- RunJobs();
- sleep(5);
- if (CheckJobs() > 0) {
- sleep_time = 10;
- } else {
- sleep_time = 60;
- }
- t1 = t2;
- }
- }
- }
- return 0; /* not reached */
-}
-
-static int ChangeUser(const char *user)
-{
- struct passwd *pas;
- const char *err_msg;
-
- /*
- * Obtain password entry and change privileges
- */
- pas = getpwnam(user);
- if (pas == 0) {
- crondlog("\011failed to get uid for %s", user);
- return -1;
- }
- setenv("USER", pas->pw_name, 1);
- setenv("HOME", pas->pw_dir, 1);
- setenv("SHELL", DEFAULT_SHELL, 1);
-
- /*
- * Change running state to the user in question
- */
- err_msg = change_identity_e2str(pas);
- if (err_msg) {
- crondlog("\011%s for user %s", err_msg, user);
- return -1;
- }
- if (chdir(pas->pw_dir) < 0) {
- crondlog("\011chdir failed: %s: %m", pas->pw_dir);
- if (chdir(TMPDIR) < 0) {
- crondlog("\011chdir failed: %s: %m", TMPDIR);
- return -1;
- }
- }
- return pas->pw_uid;
-}
-
-static void startlogger(void)
-{
- if (LogFile == 0) {
- openlog(applet_name, LOG_CONS | LOG_PID, LOG_CRON);
- }
-#if ENABLE_DEBUG_CROND_OPTION
- else { /* test logfile */
- int logfd;
-
- if ((logfd = open(LogFile, O_WRONLY | O_CREAT | O_APPEND, 0600)) >= 0) {
- close(logfd);
- } else {
- bb_perror_msg("failed to open log file '%s': ", LogFile);
- }
- }
-#endif
-}
-
-
-static const char *const DowAry[] = {
- "sun",
- "mon",
- "tue",
- "wed",
- "thu",
- "fri",
- "sat",
-
- "Sun",
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat",
- NULL
-};
-
-static const char *const MonAry[] = {
- "jan",
- "feb",
- "mar",
- "apr",
- "may",
- "jun",
- "jul",
- "aug",
- "sep",
- "oct",
- "nov",
- "dec",
-
- "Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec",
- NULL
-};
-
-static char *ParseField(char *user, char *ary, int modvalue, int off,
- const char *const *names, char *ptr)