version 1.2, 1997/09/12 04:12:48 |
version 1.9, 2000/08/02 04:10:47 |
|
|
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
#include <tzfile.h> |
#include <unistd.h> |
#include <unistd.h> |
|
|
#include "pathnames.h" |
#include "pathnames.h" |
|
|
char *calendarHome = ".calendar"; /* HOME */ |
char *calendarHome = ".calendar"; /* HOME */ |
char *calendarNoMail = "nomail"; /* don't sent mail if this file exist */ |
char *calendarNoMail = "nomail"; /* don't sent mail if this file exist */ |
|
|
struct fixs neaster, npaskha; |
|
|
|
struct iovec header[] = { |
struct iovec header[] = { |
{"From: ", 6}, |
{"From: ", 6}, |
{NULL, 0}, |
{NULL, 0}, |
|
|
register int printing; |
register int printing; |
register char *p; |
register char *p; |
FILE *fp; |
FILE *fp; |
int ch, l; |
int ch, l, i; |
int month; |
|
int day; |
|
int var; |
int var; |
char buf[2048 + 1]; |
char buf[2048 + 1]; |
|
struct event *events, *cur_evt, *ev1, *tmp; |
|
struct match *m; |
|
|
|
events = NULL; |
|
cur_evt = NULL; |
if ((fp = opencal()) == NULL) |
if ((fp = opencal()) == NULL) |
return; |
return; |
for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) { |
for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) { |
|
|
setnnames(); |
setnnames(); |
continue; |
continue; |
} |
} |
if (strncasecmp(buf, "Easter=", 7) == 0 && buf[7]) { |
/* User defined names for special events */ |
if (neaster.name != NULL) |
if ((p = strchr(buf, '='))) { |
free(neaster.name); |
for (i = 0; i < NUMEV; i++) { |
if ((neaster.name = strdup(buf + 7)) == NULL) |
if (strncasecmp(buf, spev[i].name, spev[i].nlen) == 0 && |
errx(1, "cannot allocate memory"); |
(p - buf == spev[i].nlen) && buf[spev[i].nlen + 1]) { |
neaster.len = strlen(buf + 7); |
p++; |
|
if (spev[i].uname != NULL) |
|
free(spev[i].uname); |
|
if ((spev[i].uname = strdup(p)) == NULL) |
|
errx(1, "cannot allocate memory"); |
|
spev[i].ulen = strlen(p); |
|
i = NUMEV + 1; |
|
} |
|
} |
|
if (i > NUMEV) |
continue; |
continue; |
} |
} |
if (strncasecmp(buf, "Paskha=", 7) == 0 && buf[7]) { |
|
if (npaskha.name != NULL) |
|
free(npaskha.name); |
|
if ((npaskha.name = strdup(buf + 7)) == NULL) |
|
errx(1, "cannot allocate memory"); |
|
npaskha.len = strlen(buf + 7); |
|
continue; |
|
} |
|
if (buf[0] != '\t') { |
if (buf[0] != '\t') { |
printing = isnow(buf, &month, &day, &var) ? 1 : 0; |
printing = (m = isnow(buf)) ? 1 : 0; |
if ((p = strchr(buf, '\t')) == NULL) |
if ((p = strchr(buf, '\t')) == NULL) { |
|
printing = 0; |
continue; |
continue; |
|
} |
|
/* Need the following to catch hardwired "variable" |
|
* dates */ |
if (p > buf && p[-1] == '*') |
if (p > buf && p[-1] == '*') |
var = 1; |
var = 1; |
|
else |
|
var = 0; |
if (printing) { |
if (printing) { |
struct tm tm; |
struct match *foo; |
char dbuf[30]; |
|
|
ev1 = NULL; |
|
while (m) { |
|
cur_evt = (struct event *) malloc(sizeof(struct event)); |
|
if (cur_evt == NULL) |
|
errx(1, "cannot allocate memory"); |
|
|
tm.tm_sec = 0; /* unused */ |
cur_evt->when = m->when; |
tm.tm_min = 0; /* unused */ |
snprintf(cur_evt->print_date, |
tm.tm_hour = 0; /* unused */ |
sizeof(cur_evt->print_date), "%s%c", |
tm.tm_wday = 0; /* unused */ |
m->print_date, (var + m->var) ? '*' : ' '); |
tm.tm_mon = month - 1; |
if (ev1) { |
tm.tm_mday = day; |
cur_evt->desc = ev1->desc; |
tm.tm_year = tp->tm_year; /* unused */ |
cur_evt->ldesc = NULL; |
(void)strftime(dbuf, sizeof(dbuf), "%c", &tm); |
} else { |
dbuf[10] = '\0'; |
if ((cur_evt->ldesc = strdup(p)) == NULL) |
(void)fprintf(fp, "%s%c%s\n", |
errx(1, "cannot allocate memory"); |
dbuf + 4/* skip weekdays */, |
cur_evt->desc = &(cur_evt->ldesc); |
var ? '*' : ' ', p); |
ev1 = cur_evt; |
|
} |
|
insert(&events, cur_evt); |
|
foo = m; |
|
m = m->next; |
|
free(foo); |
|
} |
} |
} |
} |
} |
else if (printing) |
else if (printing) { |
fprintf(fp, "%s\n", buf); |
if ((ev1->ldesc = realloc(ev1->ldesc, |
|
(2 + strlen(ev1->ldesc) + strlen(buf)))) == NULL) |
|
errx(1, "cannot allocate memory"); |
|
strcat(ev1->ldesc, "\n"); |
|
strcat(ev1->ldesc, buf); |
|
} |
} |
} |
|
tmp = events; |
|
while (tmp) { |
|
(void)fprintf(fp, "%s%s\n", tmp->print_date, *(tmp->desc)); |
|
tmp = tmp->next; |
|
} |
|
tmp = events; |
|
while (tmp) { |
|
events = tmp; |
|
if (tmp->ldesc) |
|
free(tmp->ldesc); |
|
tmp = tmp->next; |
|
free(events); |
|
} |
closecal(fp); |
closecal(fp); |
} |
} |
|
|
|
|
char *p, **endp; |
char *p, **endp; |
int *flags; |
int *flags; |
{ |
{ |
int val, var; |
int val, var, i; |
char *start, savech; |
char *start, savech; |
|
|
for (; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p) |
for (; !isdigit(*p) && !isalpha(*p) && *p != '*' && *p != '\t'; ++p) |
; |
; |
if (*p == '*') { /* `*' is current month */ |
if (*p == '*') { /* `*' is every month */ |
*flags |= F_ISMONTH; |
*flags |= F_ISMONTH; |
*endp = p+1; |
*endp = p+1; |
return (tp->tm_mon + 1); |
return (-1); /* means 'every month' */ |
} |
} |
if (isdigit(*p)) { |
if (isdigit(*p)) { |
val = strtol(p, &p, 10); /* if 0, it's failure */ |
val = strtol(p, &p, 10); /* if 0, it's failure */ |
|
|
|
|
/* variable weekday */ |
/* variable weekday */ |
if ((var = getdayvar(start)) != 0) { |
if ((var = getdayvar(start)) != 0) { |
if (var <=5 && var >= -4) |
if (var <= 5 && var >= -4) |
val += var * 10; |
val += var * 10; |
#ifdef DEBUG |
#ifdef DEBUG |
printf("var: %d\n", var); |
printf("var: %d\n", var); |
|
|
} |
} |
} |
} |
|
|
/* Easter */ |
/* Try specials (Easter, Paskha, ...) */ |
else if ((val = geteaster(start, tp->tm_year + 1900)) != 0) |
|
*flags |= F_EASTER; |
|
|
|
/* Paskha */ |
|
else if ((val = getpaskha(start, tp->tm_year + 1900)) != 0) |
|
*flags |= F_EASTER; |
|
|
|
/* undefined rest */ |
|
else { |
else { |
*p = savech; |
for (i = 0; i < NUMEV; i++) { |
return (0); |
if (strncasecmp(start, spev[i].name, spev[i].nlen) == 0) { |
|
start += spev[i].nlen; |
|
val = i + 1; |
|
i = NUMEV + 1; |
|
} else if (spev[i].uname != NULL && |
|
strncasecmp(start, spev[i].uname, spev[i].ulen) == 0) { |
|
start += spev[i].ulen; |
|
val = i + 1; |
|
i = NUMEV + 1; |
|
} |
|
} |
|
if (i > NUMEV) { |
|
switch(*start) { |
|
case '-': |
|
case '+': |
|
var = atoi(start); |
|
if (var > 365 || var < -365) |
|
return (0); /* Someone is just being silly */ |
|
val += (NUMEV + 1) * var; |
|
/* We add one to the matching event and multiply by |
|
* (NUMEV + 1) so as not to return 0 if there's a match. |
|
* val will overflow if there is an obscenely large |
|
* number of special events. */ |
|
break; |
|
} |
|
*flags |= F_SPECIAL; |
|
} |
|
if (!(*flags & F_SPECIAL)) { |
|
/* undefined rest */ |
|
*p = savech; |
|
return (0); |
|
} |
} |
} |
for (*p = savech; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p) |
for (*p = savech; !isdigit(*p) && !isalpha(*p) && *p != '*' && *p != '\t'; ++p) |
; |
; |
*endp = p; |
*endp = p; |
return (val); |
return (val); |
|
|
if (!freopen(calendarFile, "r", stdin)) |
if (!freopen(calendarFile, "r", stdin)) |
return (NULL); |
return (NULL); |
} else { |
} else { |
chdir(getenv("HOME")); |
char *home = getenv("HOME"); |
|
if (home == NULL || *home == '\0') |
|
errx(1, "cannot get home directory"); |
|
chdir(home); |
if (!(chdir(calendarHome) == 0 && |
if (!(chdir(calendarHome) == 0 && |
freopen(calendarFile, "r", stdin))) |
freopen(calendarFile, "r", stdin))) |
errx(1, "no calendar file: ``%s'' or ``~/%s/%s", |
errx(1, "no calendar file: ``%s'' or ``~/%s/%s", |
|
|
(void)setuid(geteuid()); |
(void)setuid(geteuid()); |
(void)setgid(getegid()); |
(void)setgid(getegid()); |
execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F", |
execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F", |
"\"Reminder Service\"", "-f", "root", NULL); |
"\"Reminder Service\"", NULL); |
warn(_PATH_SENDMAIL); |
warn(_PATH_SENDMAIL); |
_exit(1); |
_exit(1); |
} |
} |
|
|
done: (void)fclose(fp); |
done: (void)fclose(fp); |
(void)unlink(path); |
(void)unlink(path); |
while (wait(&status) >= 0); |
while (wait(&status) >= 0); |
|
} |
|
|
|
|
|
void |
|
insert(head, cur_evt) |
|
struct event **head; |
|
struct event *cur_evt; |
|
{ |
|
struct event *tmp, *tmp2; |
|
|
|
if (*head) { |
|
/* Insert this one in order */ |
|
tmp = *head; |
|
tmp2 = NULL; |
|
while (tmp->next && |
|
tmp->when <= cur_evt->when) { |
|
tmp2 = tmp; |
|
tmp = tmp->next; |
|
} |
|
if (tmp->when > cur_evt->when) { |
|
cur_evt->next = tmp; |
|
if (tmp2) |
|
tmp2->next = cur_evt; |
|
else |
|
*head = cur_evt; |
|
} else { |
|
cur_evt->next = tmp->next; |
|
tmp->next = cur_evt; |
|
} |
|
} else { |
|
*head = cur_evt; |
|
cur_evt->next = NULL; |
|
} |
} |
} |