diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Makemodule.am | 9 | ||||
| -rw-r--r-- | lib/cron/cronscan.c | 77 | ||||
| -rw-r--r-- | lib/cron/crontab.c | 50 | ||||
| -rw-r--r-- | lib/cron/delcron.c | 38 | ||||
| -rw-r--r-- | lib/cron/rdcron.c | 503 | ||||
| -rw-r--r-- | lib/include/crontab.h | 55 | 
6 files changed, 2 insertions, 730 deletions
| diff --git a/lib/Makemodule.am b/lib/Makemodule.am index 11a96e5..5ce7239 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -17,11 +17,6 @@ libcfg_a_SOURCES += lib/libcfg/pack_argv.c lib/include/libcfg.h  libcfg_a_CPPFLAGS = $(AM_CPPFLAGS)  libcfg_a_CFLAGS = $(AM_CFLAGS) -libcron_a_SOURCES = lib/cron/rdcron.c lib/cron/delcron.c lib/cron/crontab.c -libcron_a_SOURCES += lib/cron/cronscan.c lib/include/crontab.h -libcron_a_CPPFLAGS = $(AM_CPPFLAGS) -libcron_a_CFLAGS = $(AM_CFLAGS) +EXTRA_DIST += $(HEADRS) lib/include/libcfg.h -EXTRA_DIST += $(HEADRS) lib/include/libcfg.h lib/include/crontab.h - -noinst_LIBRARIES += libinit.a libcfg.a libcron.a libutil.a +noinst_LIBRARIES += libinit.a libcfg.a libutil.a diff --git a/lib/cron/cronscan.c b/lib/cron/cronscan.c deleted file mode 100644 index e28fb03..0000000 --- a/lib/cron/cronscan.c +++ /dev/null @@ -1,77 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <stddef.h> -#include <dirent.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <fcntl.h> -#include <ctype.h> - -#include "crontab.h" - -int cronscan(const char *directory, crontab_t **list) -{ -	struct dirent *ent; -	int dfd, ret = 0; -	crontab_t *cron; -	DIR *dir; - -	dir = opendir(directory); -	if (dir == NULL) { -		perror(directory); -		return -1; -	} - -	dfd = dirfd(dir); -	if (dfd < 0) { -		perror(directory); -		closedir(dir); -		return -1; -	} - -	for (;;) { -		errno = 0; -		ent = readdir(dir); - -		if (ent == NULL) { -			if (errno != 0) { -				perror(directory); -				ret = -1; -			} -			break; -		} - -		if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) -			continue; - -		cron = rdcron(dfd, ent->d_name); -		if (cron == NULL) { -			ret = -1; -			continue; -		} - -		cron->next = *list; -		*list = cron; -	} - -	closedir(dir); -	return ret; -} diff --git a/lib/cron/crontab.c b/lib/cron/crontab.c deleted file mode 100644 index f761ec0..0000000 --- a/lib/cron/crontab.c +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ -#include <string.h> - -#include "crontab.h" - -void cron_tm_to_mask(crontab_t *out, struct tm *t) -{ -	memset(out, 0, sizeof(*out)); -	out->minute     = 1UL << ((unsigned long)t->tm_min); -	out->hour       = 1 << t->tm_hour; -	out->dayofmonth = 1 << (t->tm_mday - 1); -	out->month      = 1 << t->tm_mon; -	out->dayofweek  = 1 << t->tm_wday; -} - -bool cron_should_run(const crontab_t *t, const crontab_t *mask) -{ -	if ((t->minute & mask->minute) == 0) -		return false; - -	if ((t->hour & mask->hour) == 0) -		return false; - -	if ((t->dayofmonth & mask->dayofmonth) == 0) -		return false; - -	if ((t->month & mask->month) == 0) -		return false; - -	if ((t->dayofweek & mask->dayofweek) == 0) -		return false; - -	return true; -} diff --git a/lib/cron/delcron.c b/lib/cron/delcron.c deleted file mode 100644 index 1877db1..0000000 --- a/lib/cron/delcron.c +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ -#include <stdlib.h> - -#include "crontab.h" - -void delcron(crontab_t *cron) -{ -	exec_t *e; - -	if (cron == NULL) -		return; - -	while (cron->exec != NULL) { -		e = cron->exec; -		cron->exec = e->next; - -		free(e); -	} - -	free(cron->ctty); -	free(cron); -} diff --git a/lib/cron/rdcron.c b/lib/cron/rdcron.c deleted file mode 100644 index 8781a6f..0000000 --- a/lib/cron/rdcron.c +++ /dev/null @@ -1,503 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <limits.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <ctype.h> -#include <pwd.h> -#include <grp.h> - -#include "crontab.h" -#include "libcfg.h" -#include "util.h" - - -static const enum_map_t weekday[] = { -	{ "MON", 1 }, -	{ "TUE", 2 }, -	{ "WED", 3 }, -	{ "THU", 4 }, -	{ "FRI", 5 }, -	{ "SAT", 6 }, -	{ "SUN", 0 }, -}; - -static const enum_map_t month[] = { -	{ "JAN", 1 }, -	{ "FEB", 2 }, -	{ "MAR", 3 }, -	{ "APR", 4 }, -	{ "MAY", 5 }, -	{ "JUN", 6 }, -	{ "JUL", 7 }, -	{ "AUG", 8 }, -	{ "SEP", 9 }, -	{ "OCT", 10 }, -	{ "NOV", 11 }, -	{ "DEC", 12 }, -}; - -static const struct { -	const char *macro; -	crontab_t tab; -} intervals[] = { -	{ -		.macro = "yearly", -		.tab = { -			.minute = 0x01, -			.hour = 0x01, -			.dayofmonth = 0x01, -			.month = 0x01, -			.dayofweek = 0xFF -		}, -	}, { -		.macro = "annually", -		.tab = { -			.minute = 0x01, -			.hour = 0x01, -			.dayofmonth = 0x01, -			.month = 0x01, -			.dayofweek = 0xFF -		}, -	}, { -		.macro = "monthly", -		.tab = { -			.minute = 0x01, -			.hour = 0x01, -			.dayofmonth = 0x01, -			.month = 0xFFFF, -			.dayofweek = 0xFF -		}, -	}, { -		.macro = "weekly", -		.tab = { -			.minute = 0x01, -			.hour = 0x01, -			.dayofmonth = 0xFFFFFFFF, -			.month = 0xFFFF, -			.dayofweek = 0x01 -		}, -	}, { -		.macro = "daily", -		.tab = { -			.minute = 0x01, -			.hour = 0x01, -			.dayofmonth = 0xFFFFFFFF, -			.month = 0xFFFF, -			.dayofweek = 0xFF -		}, -	}, { -		.macro = "hourly", -		.tab = { -			.minute = 0x01, -			.hour = 0xFFFFFFFF, -			.dayofmonth = 0xFFFFFFFF, -			.month = 0xFFFF, -			.dayofweek = 0xFF -		}, -	}, -}; - -/*****************************************************************************/ - -static int try_unescape(char *arg, rdline_t *rd) -{ -	if (unescape(arg)) { -		fprintf(stderr, "%s: %zu: malformed string constant\n", -			rd->filename, rd->lineno); -		return -1; -	} -	return 0; -} - -static char *try_strdup(const char *str, rdline_t *rd) -{ -	char *out = strdup(str); - -	if (out == NULL) { -		fprintf(stderr, "%s: %zu: out of memory\n", -			rd->filename, rd->lineno); -	} -	return out; -} - -static char *readnum(char *line, int *out, int minval, int maxval, -		     const enum_map_t *mnemonic, rdline_t *rd) -{ -	int i, temp, value = 0; -	const enum_map_t *ev; - -	if (!isdigit(*line)) { -		if (!mnemonic) -			goto fail_mn; - -		for (i = 0; isalnum(line[i]); ++i) -			; -		if (i == 0) -			goto fail_mn; - -		temp = line[i]; -		line[i] = '\0'; -		ev = enum_by_name(mnemonic, line); -		if (!ev) { -			fprintf(stderr, "%s: %zu: unexpected '%s'", -				rd->filename, rd->lineno, line); -		} -		line[i] = temp; -		if (!ev) -			return NULL; -		*out = ev->value; -		return line + i; -	} - -	while (isdigit(*line)) { -		i = ((*(line++)) - '0'); -		if (value > (maxval - i) / 10) -			goto fail_of; -		value = value * 10 + i; -	} - -	if (value < minval) -		goto fail_uf; - -	*out = value; -	return line; -fail_of: -	fprintf(stderr, "%s: %zu: value exceeds maximum (%d > %d)\n", -		rd->filename, rd->lineno, value, maxval); -	return NULL; -fail_uf: -	fprintf(stderr, "%s: %zu: value too small (%d < %d)\n", -		rd->filename, rd->lineno, value, minval); -	return NULL; -fail_mn: -	fprintf(stderr, "%s: %zu: expected numeric value", -		rd->filename, rd->lineno); -	return NULL; -} - -static char *readfield(char *line, uint64_t *out, int minval, int maxval, -		       const enum_map_t *mnemonic, rdline_t *rd) -{ -	int value, endvalue, step; -	uint64_t v = 0; -next: -	if (*line == '*') { -		++line; -		value = minval; -		endvalue = maxval; -	} else { -		line = readnum(line, &value, minval, maxval, mnemonic, rd); -		if (!line) -			goto fail; - -		if (*line == '-') { -			line = readnum(line + 1, &endvalue, minval, maxval, -				       mnemonic, rd); -			if (!line) -				goto fail; -		} else { -			endvalue = value; -		} -	} - -	if (endvalue < value) -		goto fail; - -	if (*line == '/') { -		line = readnum(line + 1, &step, 1, maxval + 1, NULL, rd); -		if (!line) -			goto fail; -	} else { -		step = 1; -	} - -	while (value <= endvalue) { -		v |= 1UL << (unsigned long)(value - minval); -		value += step; -	} - -	if (*line == ',' || *line == ' ') { -		++line; -		goto next; -	} - -	if (*line != '\0') -		goto fail; - -	*out = v; -	return line; -fail: -	fprintf(stderr, "%s: %zu: invalid time range expression\n", -		rd->filename, rd->lineno); -	return NULL; -} - -/*****************************************************************************/ - -static int cron_exec(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	exec_t *e, *end; -	(void)flags; - -	e = calloc(1, sizeof(*e) + strlen(arg) + 1); -	if (e == NULL) { -		fprintf(stderr, "%s: %zu: out of memory\n", -			rd->filename, rd->lineno); -		return -1; -	} - -	strcpy(e->args, arg); - -	e->argc = pack_argv(e->args); -	if (e->argc < 0) { -		fprintf(stderr, "%s: %zu: malformed string constant\n", -			rd->filename, rd->lineno); -		return -1; -	} - -	if (cron->exec == NULL) { -		cron->exec = e; -	} else { -		for (end = cron->exec; end->next != NULL; end = end->next) -			; -		end->next = e; -	} -	return 0; -} - -static int cron_hour(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	uint64_t value; -	(void)flags; - -	if (!readfield(arg, &value, 0, 23, NULL, rd)) -		return -1; - -	cron->hour = value; -	return 0; -} - -static int cron_minute(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	uint64_t value; -	(void)flags; - -	if (!readfield(arg, &value, 0, 59, NULL, rd)) -		return -1; - -	cron->minute = value; -	return 0; -} - -static int cron_dayofmonth(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	uint64_t value; -	(void)flags; - -	if (!readfield(arg, &value, 1, 31, NULL, rd)) -		return -1; - -	cron->dayofmonth = value; -	return 0; -} - -static int cron_dayofweek(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	uint64_t value; -	(void)flags; - -	if (!readfield(arg, &value, 0, 6, weekday, rd)) -		return -1; - -	cron->dayofweek = value; -	return 0; -} - -static int cron_month(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	uint64_t value; -	(void)flags; - -	if (!readfield(arg, &value, 1, 12, month, rd)) -		return -1; - -	cron->month = value; -	return 0; -} - -static int cron_interval(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	size_t i; -	(void)flags; - -	for (i = 0; i < ARRAY_SIZE(intervals); ++i) { -		if (!strcmp(intervals[i].macro, arg)) { -			cron->minute = intervals[i].tab.minute; -			cron->hour = intervals[i].tab.hour; -			cron->dayofmonth = intervals[i].tab.dayofmonth; -			cron->month = intervals[i].tab.month; -			cron->dayofweek = intervals[i].tab.dayofweek; -			return 0; -		} -	} - -	fprintf(stderr, "%s: %zu: unknown interval '%s'\n", -		rd->filename, rd->lineno, arg); -	return -1; -} - -static int cron_user(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	struct passwd *pwd; -	bool isnumeric; -	char *ptr; -	int value; -	(void)flags; - -	for (ptr = arg; isdigit(*ptr); ++ptr) -		; - -	isnumeric = (*ptr == '\0'); -	pwd = getpwnam(arg); - -	if (pwd == NULL && !isnumeric) { -		fprintf(stderr, "%s: %zu: unknown user '%s'\n", -			rd->filename, rd->lineno, arg); -		return -1; -	} - -	if (pwd != NULL) { -		cron->uid = pwd->pw_uid; -	} else { -		if (readnum(arg, &value, 0, INT_MAX, NULL, rd)) -			return -1; -		cron->uid = value; -	} -	return 0; -} - -static int cron_group(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	struct group *group; -	bool isnumeric; -	char *ptr; -	int value; -	(void)flags; - -	for (ptr = arg; isdigit(*ptr); ++ptr) -		; - -	isnumeric = (*ptr == '\0'); -	group = getgrnam(arg); - -	if (group == NULL && !isnumeric) { -		fprintf(stderr, "%s: %zu: unknown group '%s'\n", -			rd->filename, rd->lineno, arg); -		return -1; -	} - -	if (group != NULL) { -		cron->gid = group->gr_gid; -	} else { -		if (readnum(arg, &value, 0, INT_MAX, NULL, rd)) -			return -1; -		cron->gid = value; -	} -	return 0; -} - -static int cron_tty(void *user, char *arg, rdline_t *rd, int flags) -{ -	crontab_t *cron = user; -	(void)flags; - -	if (strncmp(arg, "truncate", 8) == 0 && isspace(arg[8])) { -		cron->tty_truncate = 1; -		arg += 8; -		while (isspace(*arg)) -			++arg; -	} - -	if (try_unescape(arg, rd)) -		return -1; - -	cron->ctty = try_strdup(arg, rd); -	return cron->ctty == NULL ? -1 : 0; -} - - - -static const cfg_param_t cron_params[] = { -	{ "hour", 0, cron_hour }, -	{ "minute", 0, cron_minute }, -	{ "dayofmonth", 0, cron_dayofmonth }, -	{ "dayofweek", 0, cron_dayofweek }, -	{ "month", 0, cron_month }, -	{ "interval", 0, cron_interval }, -	{ "user", 0, cron_user }, -	{ "group", 0, cron_group }, -	{ "tty", 0, cron_tty }, -	{ "exec", 1, cron_exec }, -}; - -crontab_t *rdcron(int dirfd, const char *filename) -{ -	crontab_t *cron = NULL; -	rdline_t rd; -	int ret; - -	if (rdline_init(&rd, dirfd, filename, 0, NULL)) -		return NULL; - -	cron = calloc(1, sizeof(*cron)); -	if (cron == NULL) { -		fputs("out of memory\n", stderr); -		goto out; -	} - -	cron->minute = 0xFFFFFFFFFFFFFFFFUL; -	cron->hour = 0xFFFFFFFF; -	cron->dayofmonth = 0xFFFFFFFF; -	cron->month = 0xFFFF; -	cron->dayofweek = 0xFF; - -	ret = rdcfg(cron, &rd, cron_params, ARRAY_SIZE(cron_params), 0); -	if (ret) { -		delcron(cron); -		cron = NULL; -	} -out: -	rdline_cleanup(&rd); -	return cron; -} diff --git a/lib/include/crontab.h b/lib/include/crontab.h deleted file mode 100644 index 1ea3883..0000000 --- a/lib/include/crontab.h +++ /dev/null @@ -1,55 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * Copyright (C) 2018 - David Oberhollenzer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program.  If not, see <https://www.gnu.org/licenses/>. - */ -#ifndef CRONTAB_H -#define CRONTAB_H - -#include <sys/types.h> -#include <stdbool.h> -#include <stdint.h> -#include <time.h> - -#include "service.h" - -typedef struct crontab_t { -	struct crontab_t *next; -	exec_t *exec; -	char *ctty; - -	uid_t uid; -	gid_t gid; - -	uint64_t minute; -	uint32_t hour; -	uint32_t dayofmonth; -	uint16_t month; -	uint8_t dayofweek; - -	unsigned int tty_truncate : 1; -} crontab_t; - -crontab_t *rdcron(int dirfd, const char *filename); - -void delcron(crontab_t *cron); - -int cronscan(const char *directory, crontab_t **list); - -void cron_tm_to_mask(crontab_t *out, struct tm *t); - -bool cron_should_run(const crontab_t *t, const crontab_t *mask); - -#endif /* CRONTAB_H */ | 
