+
+/* 1-based month, 0-based days, cumulative */
+int daytab[][14] = {
+ 0, 0, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364,
+ 0, 0, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365,
+};
+struct tm *tp;
+int *cumdays, offset, yrdays;
+char dayname[10];
+
+settime()
+{
+ time_t now, time();
+
+ (void)time(&now);
+ tp = localtime(&now);
+ if (isleap(tp->tm_year + 1900)) {
+ yrdays = DAYSPERLYEAR;
+ cumdays = daytab[1];
+ } else {
+ yrdays = DAYSPERNYEAR;
+ 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.
+ */
+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;
+ } 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;
+ }
+ }
+ 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);
+}
+
+getfield(p, endp, flags)
+ char *p, **endp;
+ int *flags;
+{
+ int val;
+ char *start, savech;
+
+ if (*p == '*') { /* `*' is current month */
+ *flags |= F_ISMONTH;
+ return(tp->tm_mon);
+ }
+ if (isdigit(*p)) {
+ val = strtol(p, &p, 10); /* if 0, it's failure */
+ for (; !isdigit(*p) && !isalpha(*p); ++p);
+ *endp = p;
+ return(val);
+ }
+ for (start = p; isalpha(*++p););
+ savech = *p;
+ *p = '\0';
+ if (val = getmonth(start))
+ *flags |= F_ISMONTH;
+ else if (val = getday(start))
+ *flags |= F_ISDAY;
+ else
+ return(0);
+ for (*p = savech; !isdigit(*p) && !isalpha(*p); ++p);
+ *endp = p;
+ return(val);
+}
+
+char path[MAXPATHLEN + 1];
+
+FILE *
+opencal()
+{
+ int fd, pdes[2];
+ char *mktemp();
+
+ /* open up calendar file as stdin */
+ if (!freopen("calendar", "r", stdin)) {
+ if (doall)
+ return((FILE *)NULL);
+ (void)fprintf(stderr, "calendar: no calendar file.\n");
+ exit(1);