+ 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);
+ }
+ 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", "-I.", _PATH_INCLUDE, NULL);
+ _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)sprintf(path, "%s/_calXXXXXX", _PATH_TMP);
+ if ((fd = mkstemp(path)) < 0)
+ return(NULL);
+ return(fdopen(fd, "w+"));
+}
+
+closecal(fp)
+ FILE *fp;
+{
+ struct stat sbuf;
+ int nread, pdes[2], status;
+ char buf[1024], *mktemp();
+
+ 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,
+};
+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,
+};
+getday(s)
+ register char *s;
+{
+ register char **p;
+
+ for (p = days; *p; ++p)
+ if (!strncasecmp(s, *p, 3))
+ return((p - days) + 1);
+ return(0);
+}
+
+usage()
+{
+ (void)fprintf(stderr, "usage: calendar [-a]\n");
+ exit(1);