diff options
author | Wolfram Schneider <wosch@FreeBSD.org> | 1996-02-02 06:02:41 +0000 |
---|---|---|
committer | Wolfram Schneider <wosch@FreeBSD.org> | 1996-02-02 06:02:41 +0000 |
commit | c9c822e6325383218938cef907e0f9766efe0440 (patch) | |
tree | ec2d23fe6eecf6aeec0846f3362a3c6b9b008c8d /usr.bin/calendar/calendar.c | |
parent | 4ad1bd1e33bc3dd54dca281ee225429b24c00c6b (diff) | |
download | src-c9c822e6325383218938cef907e0f9766efe0440.tar.gz src-c9c822e6325383218938cef907e0f9766efe0440.zip |
Notes
Diffstat (limited to 'usr.bin/calendar/calendar.c')
-rw-r--r-- | usr.bin/calendar/calendar.c | 351 |
1 files changed, 38 insertions, 313 deletions
diff --git a/usr.bin/calendar/calendar.c b/usr.bin/calendar/calendar.c index 7302dfbf7ec5..c33842341a5d 100644 --- a/usr.bin/calendar/calendar.c +++ b/usr.bin/calendar/calendar.c @@ -41,37 +41,23 @@ static char copyright[] = static char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; #endif /* not lint */ -#include <sys/param.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <sys/uio.h> -#include <sys/wait.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> #include <pwd.h> #include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <unistd.h> +#include <errno.h> +#include <err.h> +#include <stdlib.h> +#include <time.h> #include "pathnames.h" +#include "calendar.h" struct passwd *pw; -int doall; +int doall = 0; +time_t f_time = 0; -void cal __P((void)); -void closecal __P((FILE *)); -int getday __P((char *)); -int getfield __P((char *, char **, int *)); -int getmonth __P((char *)); -int isnow __P((char *)); -FILE *opencal __P((void)); -void settime __P((void)); -void usage __P((void)); -#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0) +int f_dayAfter = 0; /* days after current date */ +int f_dayBefore = 0; /* days before current date */ int main(argc, argv) @@ -81,7 +67,7 @@ main(argc, argv) extern int optind; int ch; - while ((ch = getopt(argc, argv, "-a")) != EOF) + while ((ch = getopt(argc, argv, "?-af:t:A:B:")) != EOF) switch (ch) { case '-': /* backward contemptible */ case 'a': @@ -91,6 +77,24 @@ main(argc, argv) } doall = 1; break; + + + case 'f': /* other calendar file */ + calendarFile = optarg; + break; + + case 't': /* other date, undocumented, for tests */ + f_time = Mktime (optarg); + break; + + case 'A': /* days after current date */ + f_dayAfter = atoi(optarg); + break; + + case 'B': /* days before current date */ + f_dayBefore = atoi(optarg); + break; + case '?': default: usage(); @@ -101,7 +105,12 @@ main(argc, argv) if (argc) usage(); - settime(); + /* use current time */ + if (f_time <= 0) + (void)time(&f_time); + + settime(f_time); + if (doall) while ((pw = getpwent()) != NULL) { (void)setegid(pw->pw_gid); @@ -115,297 +124,13 @@ main(argc, argv) exit(0); } -void -cal() -{ - register int printing; - register char *p; - FILE *fp; - int ch; - char buf[2048 + 1]; - - if ((fp = opencal()) == NULL) - return; - for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) { - if ((p = strchr(buf, '\n')) != NULL) - *p = '\0'; - else - while ((ch = getchar()) != '\n' && ch != EOF); - if (buf[0] == '\0') - continue; - if (buf[0] != '\t') - printing = isnow(buf) ? 1 : 0; - if (printing) - (void)fprintf(fp, "%s\n", buf); - } - closecal(fp); -} - -struct iovec header[] = { - "From: ", 6, - NULL, 0, - " (Reminder Service)\nTo: ", 24, - NULL, 0, - "\nSubject: ", 10, - NULL, 0, - "'s Calendar\nPrecedence: bulk\n\n", 30, -}; - -/* 1-based month, 0-based days, cumulative */ -int daytab[][14] = { - 0, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364, - 0, -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, -}; -struct tm *tp; -int *cumdays, offset, yrdays; -char dayname[10]; - -void -settime() -{ - time_t now; - - (void)time(&now); - tp = localtime(&now); - if (isleap(tp->tm_year + 1900)) { - yrdays = 366; - cumdays = daytab[1]; - } else { - yrdays = 365; - cumdays = daytab[0]; - } - /* Friday displays Monday's events */ - offset = tp->tm_wday == 5 ? 3 : 1; - header[5].iov_base = dayname; - header[5].iov_len = strftime(dayname, sizeof(dayname), "%A", tp); -} - -/* - * Possible date formats include any combination of: - * 3-charmonth (January, Jan, Jan) - * 3-charweekday (Friday, Monday, mon.) - * numeric month or day (1, 2, 04) - * - * Any character may separate them, or they may not be separated. Any line, - * following a line that is matched, that starts with "whitespace", is shown - * along with the matched line. - */ -int -isnow(endp) - char *endp; -{ - int day, flags, month, v1, v2; - -#define F_ISMONTH 0x01 -#define F_ISDAY 0x02 - flags = 0; - /* didn't recognize anything, skip it */ - if (!(v1 = getfield(endp, &endp, &flags))) - return (0); - if (flags & F_ISDAY || v1 > 12) { - /* found a day */ - day = v1; - /* if no recognizable month, assume just a day alone */ - if (!(month = getfield(endp, &endp, &flags))) - month = tp->tm_mon + 1; - } else if (flags & F_ISMONTH) { - month = v1; - /* if no recognizable day, assume the first */ - if (!(day = getfield(endp, &endp, &flags))) - day = 1; - } else { - v2 = getfield(endp, &endp, &flags); - if (flags & F_ISMONTH) { - day = v1; - month = v2; - } else { - /* F_ISDAY set, v2 > 12, or no way to tell */ - month = v1; - /* if no recognizable day, assume the first */ - day = v2 ? v2 : 1; - } - } - if (flags & F_ISDAY) - day = tp->tm_mday + (((day - 1) - tp->tm_wday + 7) % 7); - day = cumdays[month] + day; - - /* if today or today + offset days */ - if (day >= tp->tm_yday && day <= tp->tm_yday + offset) - return (1); - /* if number of days left in this year + days to event in next year */ - if (yrdays - tp->tm_yday + day <= offset) - return (1); - return (0); -} - -int -getfield(p, endp, flags) - char *p, **endp; - int *flags; -{ - int val; - char *start, savech; - - for (; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p); - if (*p == '*') { /* `*' is current month */ - *flags |= F_ISMONTH; - *endp = p+1; - return (tp->tm_mon + 1); - } - if (isdigit(*p)) { - val = strtol(p, &p, 10); /* if 0, it's failure */ - for (; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p); - *endp = p; - return (val); - } - for (start = p; isalpha(*++p);); - savech = *p; - *p = '\0'; - if ((val = getmonth(start)) != 0) - *flags |= F_ISMONTH; - else if ((val = getday(start)) != 0) - *flags |= F_ISDAY; - else { - *p = savech; - return (0); - } - for (*p = savech; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p); - *endp = p; - return (val); -} - -char path[MAXPATHLEN + 1]; - -FILE * -opencal() -{ - int fd, pdes[2]; - - /* open up calendar file as stdin */ - if (!freopen("calendar", "r", stdin)) { - if (doall) - return (NULL); - errx(1, "no calendar file in current directory."); - } - if (pipe(pdes) < 0) - return (NULL); - switch (vfork()) { - case -1: /* error */ - (void)close(pdes[0]); - (void)close(pdes[1]); - return (NULL); - case 0: - /* child -- stdin already setup, set stdout to pipe input */ - if (pdes[1] != STDOUT_FILENO) { - (void)dup2(pdes[1], STDOUT_FILENO); - (void)close(pdes[1]); - } - (void)close(pdes[0]); - execl(_PATH_CPP, "cpp", "-P", "-I.", _PATH_INCLUDE, NULL); - (void)fprintf(stderr, - "calendar: execl: %s: %s.\n", _PATH_CPP, strerror(errno)); - _exit(1); - } - /* parent -- set stdin to pipe output */ - (void)dup2(pdes[0], STDIN_FILENO); - (void)close(pdes[0]); - (void)close(pdes[1]); - - /* not reading all calendar files, just set output to stdout */ - if (!doall) - return (stdout); - - /* set output to a temporary file, so if no output don't send mail */ - (void)snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP); - if ((fd = mkstemp(path)) < 0) - return (NULL); - return (fdopen(fd, "w+")); -} - -void -closecal(fp) - FILE *fp; -{ - struct stat sbuf; - int nread, pdes[2], status; - char buf[1024]; - - if (!doall) - return; - - (void)rewind(fp); - if (fstat(fileno(fp), &sbuf) || !sbuf.st_size) - goto done; - if (pipe(pdes) < 0) - goto done; - switch (vfork()) { - case -1: /* error */ - (void)close(pdes[0]); - (void)close(pdes[1]); - goto done; - case 0: - /* child -- set stdin to pipe output */ - if (pdes[0] != STDIN_FILENO) { - (void)dup2(pdes[0], STDIN_FILENO); - (void)close(pdes[0]); - } - (void)close(pdes[1]); - execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F", - "\"Reminder Service\"", "-f", "root", NULL); - (void)fprintf(stderr, - "calendar: %s: %s.\n", _PATH_SENDMAIL, strerror(errno)); - _exit(1); - } - /* parent -- write to pipe input */ - (void)close(pdes[0]); - - header[1].iov_base = header[3].iov_base = pw->pw_name; - header[1].iov_len = header[3].iov_len = strlen(pw->pw_name); - writev(pdes[1], header, 7); - while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0) - (void)write(pdes[1], buf, nread); - (void)close(pdes[1]); -done: (void)fclose(fp); - (void)unlink(path); - while (wait(&status) >= 0); -} - -static char *months[] = { - "jan", "feb", "mar", "apr", "may", "jun", - "jul", "aug", "sep", "oct", "nov", "dec", NULL, -}; - -int -getmonth(s) - register char *s; -{ - register char **p; - - for (p = months; *p; ++p) - if (!strncasecmp(s, *p, 3)) - return ((p - months) + 1); - return (0); -} - -static char *days[] = { - "sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL, -}; - -int -getday(s) - register char *s; -{ - register char **p; - - for (p = days; *p; ++p) - if (!strncasecmp(s, *p, 3)) - return ((p - days) + 1); - return (0); -} void usage() { - (void)fprintf(stderr, "usage: calendar [-a]\n"); + (void)fprintf(stderr, + "usage: calendar [-a] [-A days] [-B days] [-f calendarfile]\n"); exit(1); } + + |