scron

simple cron daemon
git clone git://git.2f30.org/scron
Log | Files | Refs | README | LICENSE

commit c2ae1254215fc15c8520ff88ddd620f594a7ef71
parent 2be597ef6b18138429257bad6ea31684ce4cd942
Author: Ari Malinen <ari.malinen@gmail.com>
Date:   Sun, 15 Jun 2014 19:09:35 +0300

improved error handling

Diffstat:
MMakefile | 14+++++++-------
MREADME | 1+
Acrond.c | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dinit.d/cron | 5-----
Ainit.d/crond | 5+++++
5 files changed, 120 insertions(+), 12 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,18 +1,18 @@ CFLAGS=-std=c99 -Wall -Wpedantic -Wextra -all: cron +all: crond -install: cron +install: crond mkdir -p ${DESTDIR}/sbin mkdir -p ${DESTDIR}/etc/init.d - install -m 755 cron ${DESTDIR}/sbin/ - install -m 755 init.d/cron ${DESTDIR}/etc/init.d/ + install -m 755 crond ${DESTDIR}/sbin/ + install -m 755 init.d/crond ${DESTDIR}/etc/init.d/ install -m 644 crontab ${DESTDIR}/etc/ uninstall: - rm -f ${DESTDIR}/sbin/cron - rm ${DESTDIR}/etc/init.d/cron + rm -f ${DESTDIR}/sbin/crond + rm ${DESTDIR}/etc/init.d/crond rm ${DESTDIR}/etc/crontab clean: - rm cron + rm crond diff --git a/README b/README @@ -12,6 +12,7 @@ features Schedule tasks. Single daemon, config and initscript. Log to stdout and syslog. +Good error handling. usage ----- diff --git a/crond.c b/crond.c @@ -0,0 +1,107 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <time.h> +#include <unistd.h> +#include <syslog.h> + +#define LEN 100 + +int main(int argc, char *argv[]) { + char *ep, *col, line[LEN+1], config[LEN+1] = "/etc/crontab"; + int i, j; + time_t t; + struct tm *tm; + FILE *fp; + + openlog(argv[0], LOG_CONS | LOG_PID, LOG_LOCAL1); + + for (i = 1; i < argc; i++) { + if (!strcmp("-d", argv[i])) { + switch (fork()) { + case -1: + fprintf(stderr, "error: failed to daemonize\n"); + syslog(LOG_NOTICE, "error: failed to daemonize"); + break; + case 0: + setsid(); + fclose(stdin); + fclose(stdout); + fclose(stderr); + break; + default: + return 0; + + } + } else if (!strcmp("-f", argv[i])) { + if (argv[i+1] == NULL || argv[i+1][0] == '-') { + fprintf(stderr, "error: -f needs parameter\n"); + syslog(LOG_NOTICE, "error: -f needs parameter"); + return 1; + } + strncpy(config, argv[++i], LEN); + } else { + fprintf(stderr, "usage: %s [options]\n", argv[0]); + fprintf(stderr, "-h help\n"); + fprintf(stderr, "-d daemon\n"); + fprintf(stderr, "-f <file> config file\n"); + return 1; + } + } + + while (1) { + t = time(NULL); + sleep(60 - t % 60); + t = time(NULL); + tm = localtime(&t); + + if ((fp = fopen(config, "r")) == NULL) { + fprintf(stderr, "error: cant read %s\n", config); + syslog(LOG_NOTICE, "error: cant read %s", config); + continue; + } + + for (i = 0; fgets(line, LEN+1, fp); i++) { + if (line[0] == '#' || line[0] == '\n') + continue; + + for (j = 0, col = strtok(line,"\t"); col; j++, col = strtok(NULL, "\t")) { + ep = ""; + + if ((j == 0 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_min) && *ep == '\0') || + (j == 1 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_hour) && *ep == '\0') || + (j == 2 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_mday) && *ep == '\0') || + (j == 3 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_mon) && *ep == '\0') || + (j == 4 && (col[0] == '*' || strtol(col, &ep, 0) == tm->tm_wday) && *ep == '\0')) { + continue; + } else if (j == 5) { + printf("run: %s", col); + syslog(LOG_NOTICE, "run: %s", col); + switch (fork()) { + case -1: + fprintf(stderr, "error: job failed: %s", col); + syslog(LOG_NOTICE, "error: job failed: %s", col); + break; + case 0: + execl("/bin/sh", "/bin/sh", "-c", col, (char *) NULL); + fprintf(stderr, "error: job failed: %s", col); + syslog(LOG_NOTICE, "error: job failed: %s", col); + return 1; + break; + } + } else if (!isdigit(col[0]) || *col < 0 || *col > 59 || *ep != '\0') { + fprintf(stderr, "error: %s line %d column %d\n", config, i+1, j+1); + syslog(LOG_NOTICE, "error: %s line %d column %d", config, i+1, j+1); + } + + break; + } + } + + fclose(fp); + } + + closelog(); + return 0; +} diff --git a/init.d/cron b/init.d/cron @@ -1,5 +0,0 @@ -#!/sbin/runscript - -command=cron -command_args=-d -name="cron" diff --git a/init.d/crond b/init.d/crond @@ -0,0 +1,5 @@ +#!/sbin/runscript + +command=crond +command_args=-d +name="cron daemon"