aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <goliath@infraroot.at>2019-04-03 23:41:09 +0200
committerDavid Oberhollenzer <goliath@infraroot.at>2019-04-04 13:35:44 +0200
commit10b4195af24561c8d4a39b27c31cde21eb1cf1b9 (patch)
tree6b9ea9f7fcfe00c17f89b0ebf9751a708d27cac6
parenta02ef642bd6cf6d2584d6f25b379a363e37eb374 (diff)
Replace rdline with libbsd fparselnHEADmaster
Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
-rw-r--r--Makefile.am11
-rw-r--r--configure.ac17
-rw-r--r--gcrond.h12
-rw-r--r--rdcron.c53
-rw-r--r--rdline.c77
5 files changed, 73 insertions, 97 deletions
diff --git a/Makefile.am b/Makefile.am
index 6f72aea..73f7761 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,16 @@ AM_CFLAGS = $(WARN_CFLAGS)
sbin_PROGRAMS = gcrond
-gcrond_SOURCES = gcrond.c gcrond.h rdcron.c crontab.c cronscan.c rdline.c
+gcrond_SOURCES = gcrond.c gcrond.h rdcron.c crontab.c cronscan.c
+gcrond_CPPFLAGS = $(AM_CPPFLAGS)
+gcrond_CFLAGS = $(AM_CFLAGS)
+gcrond_LDADD =
+
+if HAVE_LIBBSD
+gcrond_CPPFLAGS += -DHAVE_LIBBSD
+gcrond_CFLAGS += $(LIBBSD_CFLAGS)
+gcrond_LDADD += $(LIBBSD_LIBS)
+endif
crontabdir = @GCRONDIR@
crontab_DATA = crontab/0-example
diff --git a/configure.ac b/configure.ac
index 62e94cf..1e89c14 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,6 +8,23 @@ AC_PROG_CC
AC_PROG_CC_C99
AC_PROG_INSTALL
AC_PROG_RANLIB
+AC_CANONICAL_HOST
+
+m4_ifndef([PKG_PROG_PKG_CONFIG],
+ [m4_fatal([Could not locate the pkg-config autoconf
+ macros. These are usually located in /usr/share/aclocal/pkg.m4.
+ If your macros are in a different location, try setting the
+ environment variable AL_OPTS="-I/other/macro/dir" before running
+ ./autogen.sh or autoreconf again. Make sure pkg-config is installed.])])
+PKG_PROG_PKG_CONFIG
+
+case "${host_os}" in
+linux*)
+ AM_CONDITIONAL([HAVE_LIBBSD], [true])
+ PKG_CHECK_MODULES(LIBBSD, [libbsd], [],
+ [AC_MSG_ERROR([missing libbsd])])
+ ;;
+esac
UL_WARN_ADD([-Wall])
UL_WARN_ADD([-Wextra])
diff --git a/gcrond.h b/gcrond.h
index c6f3071..9fe816d 100644
--- a/gcrond.h
+++ b/gcrond.h
@@ -21,6 +21,10 @@
#include <fcntl.h>
#include <time.h>
+#ifdef HAVE_LIBBSD
+#include <bsd/bsd.h>
+#endif
+
#include "config.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -43,14 +47,6 @@ typedef struct {
char *line;
} rdline_t;
-int rdline_init(rdline_t *t, int dirfd, const char *filename);
-
-void rdline_complain(rdline_t *t, const char *msg, ...);
-
-void rdline_cleanup(rdline_t *t);
-
-int rdline(rdline_t *t);
-
crontab_t *rdcron(int dirfd, const char *filename);
void delcron(crontab_t *cron);
diff --git a/rdcron.c b/rdcron.c
index 9a9171e..91be4d0 100644
--- a/rdcron.c
+++ b/rdcron.c
@@ -96,6 +96,10 @@ static const struct {
/*****************************************************************************/
+#define complainf(rd, msg, ...) \
+ fprintf(stderr, "%s: %zu: " msg "\n", \
+ rd->filename, rd->lineno, __VA_ARGS__)
+
static char *readnum(char *line, int *out, int minval, int maxval,
const enum_map_t *mnemonic, rdline_t *rd)
{
@@ -113,7 +117,7 @@ static char *readnum(char *line, int *out, int minval, int maxval,
}
if (ev->name == NULL) {
- rdline_complain(rd, "unexpected '%.*s'", i, line);
+ complainf(rd, "unexpected '%.*s'", i, line);
return NULL;
}
@@ -138,13 +142,14 @@ static char *readnum(char *line, int *out, int minval, int maxval,
*out = value;
return line;
fail_of:
- rdline_complain(rd, "value exceeds maximum (%d > %d)", value, maxval);
+ complainf(rd, "value exceeds maximum (%d > %d)", value, maxval);
return NULL;
fail_uf:
- rdline_complain(rd, "value too small (%d < %d)", value, minval);
+ complainf(rd, "value too small (%d < %d)", value, minval);
return NULL;
fail_mn:
- rdline_complain(rd, "expected numeric value");
+ fprintf(stderr, "%s: %zu: expected numeric value\n",
+ rd->filename, rd->lineno);
return NULL;
}
@@ -201,7 +206,8 @@ next:
return line;
fail:
- rdline_complain(rd, "invalid time range expression");
+ fprintf(stderr, "%s: %zu: invalid time range expression\n",
+ rd->filename, rd->lineno);
return NULL;
}
@@ -229,7 +235,7 @@ static char *cron_interval(crontab_t *cron, rdline_t *rd)
*cron = intervals[i].tab;
return rd->line + j;
fail:
- rdline_complain(rd, "unknown interval '%.*s'", (int)j, rd->line);
+ complainf(rd, "unknown interval '%.*s'", (int)j, rd->line);
return NULL;
}
@@ -266,14 +272,39 @@ crontab_t *rdcron(int dirfd, const char *filename)
crontab_t *cron, *list = NULL;
rdline_t rd;
char *ptr;
+ int fd;
+
+ memset(&rd, 0, sizeof(rd));
+ rd.filename = filename;
+
+ fd = openat(dirfd, filename, O_RDONLY);
+ if (fd == -1) {
+ perror(filename);
+ return NULL;
+ }
- if (rdline_init(&rd, dirfd, filename))
+ rd.fp = fdopen(fd, "r");
+ if (rd.fp == NULL) {
+ perror("fdopen");
+ close(fd);
return NULL;
+ }
+
+ for (;;) {
+ free(rd.line);
+ errno = 0;
+
+ rd.line = fparseln(rd.fp, NULL, &rd.lineno, NULL, 0);
+
+ if (rd.line == NULL) {
+ if (errno)
+ perror(filename);
+ break;
+ }
- while (rdline(&rd) == 0) {
cron = calloc(1, sizeof(*cron));
if (cron == NULL) {
- rdline_complain(&rd, strerror(errno));
+ perror(filename);
break;
}
@@ -293,7 +324,7 @@ crontab_t *rdcron(int dirfd, const char *filename)
cron->exec = strdup(ptr);
if (cron->exec == NULL) {
- rdline_complain(&rd, strerror(errno));
+ perror(filename);
free(cron);
continue;
}
@@ -302,6 +333,6 @@ crontab_t *rdcron(int dirfd, const char *filename)
list = cron;
}
- rdline_cleanup(&rd);
+ fclose(rd.fp);
return list;
}
diff --git a/rdline.c b/rdline.c
deleted file mode 100644
index 99b4f4e..0000000
--- a/rdline.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* SPDX-License-Identifier: ISC */
-#include "gcrond.h"
-
-int rdline(rdline_t *t)
-{
- size_t i, len;
-
- do {
- free(t->line);
- t->line = NULL;
- errno = 0;
- len = 0;
-
- if (getline(&t->line, &len, t->fp) < 0) {
- if (errno) {
- rdline_complain(t, strerror(errno));
- return -1;
- }
- return 1;
- }
-
- t->lineno += 1;
-
- for (i = 0; isspace(t->line[i]); ++i)
- ;
-
- if (t->line[i] == '\0' || t->line[i] == '#') {
- t->line[0] = '\0';
- } else if (i) {
- memmove(t->line, t->line + i, len - i + 1);
- }
- } while (t->line[0] == '\0');
-
- return 0;
-}
-
-void rdline_complain(rdline_t *t, const char *msg, ...)
-{
- va_list ap;
-
- fprintf(stderr, "%s: %zu: ", t->filename, t->lineno);
-
- va_start(ap, msg);
- vfprintf(stderr, msg, ap);
- va_end(ap);
-
- fputc('\n', stderr);
-}
-
-int rdline_init(rdline_t *t, int dirfd, const char *filename)
-{
- int fd;
-
- memset(t, 0, sizeof(*t));
-
- fd = openat(dirfd, filename, O_RDONLY);
- if (fd == -1) {
- perror(filename);
- return -1;
- }
-
- t->fp = fdopen(fd, "r");
- if (t->fp == NULL) {
- perror("fdopen");
- close(fd);
- return -1;
- }
-
- t->filename = filename;
- return 0;
-}
-
-void rdline_cleanup(rdline_t *t)
-{
- free(t->line);
- fclose(t->fp);
-}