summaryrefslogtreecommitdiffstats
path: root/src/msntab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/msntab.c')
-rw-r--r--src/msntab.c227
1 files changed, 221 insertions, 6 deletions
diff --git a/src/msntab.c b/src/msntab.c
index 12002d5..446971c 100644
--- a/src/msntab.c
+++ b/src/msntab.c
@@ -30,6 +30,8 @@
#include <stdio.h>
#include <unistd.h>
#include <regex.h>
+#include <time.h>
+#include <ctype.h>
#include <libdaemon/dlog.h>
@@ -82,12 +84,196 @@ int glob_match(const char *e, const char *s) {
}
}
+
+/*
+**
+** The functions make_time, time_match, and day_match have
+** been borrowed from the file rcvbox.c of vbox.
+**
+** Original Copyright:
+**
+** Copyright (C) 1996, 1997 Michael 'Ghandi' Herold
+*/
+
+static time_t make_time(time_t timenow, char *timestr, int mode)
+{
+ struct tm *locala;
+ struct tm localb;
+
+ char timestring[5 + 1];
+ char *hourstr, *minsstr;
+ int hourint, minsint, secsint;
+
+ strncpy(timestring, timestr, 5);
+
+ hourstr = timestring;
+ minsstr = index(hourstr, ':');
+
+ if (!minsstr) {
+ if (!mode)
+ minsstr = "00";
+ else
+ minsstr = "59";
+ }
+ else
+ *minsstr++ = '\0';
+
+ if (!mode)
+ secsint = 0;
+ else
+ secsint = 59;
+
+ hourint = atoi(hourstr);
+ minsint = atoi(minsstr);
+
+ if (hourint < 0 || hourint > 23)
+ return 0;
+ if (minsint < 0 || minsint > 59)
+ return 0;
+
+ locala = localtime(&timenow);
+ if (!locala)
+ return 0;
+
+ localb = *locala;
+
+ localb.tm_sec = secsint;
+ localb.tm_min = minsint;
+ localb.tm_hour = hourint;
+
+ return mktime(&localb);
+}
+
+int time_match(char *timestr)
+{
+ char *timestring;
+ char *timeptr;
+ char *timenxt;
+ char *timebeg, *timeend;
+ time_t timenow;
+ time_t timesecsbeg, timesecsend;
+ int res = 0;
+
+ timestring = strdup(timestr);
+ assert(timestring);
+
+ timeptr = timestring;
+ timenow = time(NULL);
+
+ if (!strcmp(timestring, "*")) {
+ res = 1;
+ goto out;
+ }
+
+ if (!strcmp(timestring, "!") || !strcmp(timestring, "-"))
+ goto out;
+
+ while (timeptr) {
+ timenxt = index(timeptr, ',');
+ if (timenxt)
+ *timenxt++ = '\0';
+
+ timebeg = timeptr;
+ timeend = index(timebeg, '-');
+
+ if (timeend)
+ *timeend++ = '\0';
+ else
+ timeend = timebeg;
+
+ if (!timeend)
+ timeend = timebeg;
+
+ timesecsbeg = make_time(timenow, timebeg, 0);
+ timesecsend = make_time(timenow, timeend, 1);
+
+ if (timesecsbeg < 0 || timesecsend < timesecsbeg)
+ daemon_log(LOG_WARNING, "End time less then begin time in timestring %s", timestr);
+ else if (timenow >= timesecsbeg && timenow <= timesecsend) {
+ res = 1;
+ goto out;
+ }
+
+ timeptr = timenxt;
+ }
+
+out:
+ if (timestring)
+ free(timestring);
+
+ return res;
+}
+
+int day_match(char *strdays)
+{
+ static char *weekdaynames[] = {
+ "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT",
+ "WEEKEND", "WORK", "WORK", "WORK", "WORK", "WORK", "WEEKEND",
+ NULL
+ };
+
+ struct tm *timelocal;
+ char *beg, *nxt;
+ char *days;
+ int i;
+ time_t timenow;
+ int res = 0;
+
+ days = strdup(strdays);
+ assert(days);
+
+ if (!strcmp(days, "*")) {
+ res = 1;
+ goto out;
+ }
+
+ if (!strcmp(days, "-") || !strcmp(days, "!") )
+ goto out;
+
+ timenow = time(NULL);
+
+ timelocal = localtime(&timenow);
+ if (!timelocal)
+ goto out;
+
+ for (i = 0; i < strlen(days); i++) {
+ if (!isalpha(days[i]) && days[i] != ',') {
+ daemon_log(LOG_WARNING, "Error in daystring %s", strdays);
+ goto out;
+ }
+ }
+
+ beg = days;
+
+ while (beg) {
+ nxt = index(beg, ',');
+ if (nxt)
+ *nxt++ = 0;
+
+ for (i = 0; weekdaynames[i]; i++) {
+ if (!strcasecmp(weekdaynames[i], beg) && (i%7) == timelocal->tm_wday) {
+ res = 1;
+ goto out;
+ }
+ }
+
+ beg = nxt;
+ }
+
+out:
+ if (days)
+ free(days);
+
+ return res;
+}
+
+
struct tabentry* msntab_check_call(const char *callee, const char *caller) {
struct tabentry *l = first;
while (l) {
- int a, b;
- assert(l->local && l->remote);
+ int a, b, c, d;
+ assert(l->local && l->remote && l->dayspec && l->timespec);
if (l->local[0] == '~')
a = !regex_match(l->local+1, callee);
@@ -99,8 +285,11 @@ struct tabentry* msntab_check_call(const char *callee, const char *caller) {
b = !regex_match(l->remote+1, caller);
else
b = !glob_match(l->remote, caller);
-
- if (a && b) {
+
+ c = day_match(l->dayspec);
+ d = time_match(l->timespec);
+
+ if (a && b && c && d) {
daemon_log(LOG_INFO, "MSN table entry from '%s:%u' matched.", l->filename, l->line);
return msntab_ref(l);
}
@@ -135,6 +324,8 @@ void msntab_unref(struct tabentry *t) {
free(t->local);
free(t->remote);
+ free(t->dayspec);
+ free(t->timespec);
free(t->filename);
free(t);
@@ -222,7 +413,7 @@ int msntab_load(const char *fn) {
n = 0;
while (!feof(f)) {
- char l[256], *c, *e, *local, *remote, *options, *action;
+ char l[256], *c, *e, *local, *remote, *dayspec, *timespec, *options, *action;
n++;
@@ -274,6 +465,22 @@ int msntab_load(const char *fn) {
if (c)
c+=strspn(c, " \t");
+ if (!(dayspec = strsep(&c, " \t"))) {
+ daemon_log(LOG_ERR, "Parse failure on dayspec field in '%s:%i'.", fn, n);
+ goto fail;
+ }
+
+ if (c)
+ c+=strspn(c, " \t");
+
+ if (!(timespec = strsep(&c, " \t"))) {
+ daemon_log(LOG_ERR, "Parse failure on timespec field in '%s:%i'.", fn, n);
+ goto fail;
+ }
+
+ if (c)
+ c+=strspn(c, " \t");
+
if (!(options = strsep(&c, " \t"))) {
daemon_log(LOG_ERR, "Parse failure on options field in '%s:%i'.", fn, n);
goto fail;
@@ -302,6 +509,12 @@ int msntab_load(const char *fn) {
t->remote = strdup(remote);
assert(t->remote);
+ t->dayspec = strdup(dayspec);
+ assert(t->dayspec);
+
+ t->timespec = strdup(timespec);
+ assert(t->timespec);
+
if (action[0] == '@') {
if (!strcmp(action, "@hangup"))
t->action = CALL_ACTION_HANGUP;
@@ -372,11 +585,13 @@ static void dump_entry(struct tabentry *t) {
} else
strncpy(s, "NOARGS", sizeof(s));
- daemon_log(LOG_INFO, "[%s:%02u] %-12s -> %-12s; shbuf=%c; pipehack=%c; rings=%u; action=%s; args=<%s>",
+ daemon_log(LOG_INFO, "[%s:%02u] %-12s -> %-12s; %s %s; shbuf=%c; pipehack=%c; rings=%u; action=%s; args=<%s>",
t->filename,
t->line,
t->local,
t->remote,
+ t->dayspec,
+ t->timespec,
t->shbuf ? 'y' : 'n',
t->pipehack ? 'y' : 'n',
t->rings,