--- usr.bin/calendar/calendar.h.orig 2020-06-12 06:49:55.000000000 -0500 +++ usr.bin/calendar/calendar.h 2020-06-21 08:27:41.471752000 -0500 @@ -164,9 +164,6 @@ /* io.c */ void cal(void); -void closecal(FILE *); -FILE *opencalin(void); -FILE *opencalout(void); /* ostern.c / paskha.c */ int paskha(int); --- usr.bin/calendar/io.c.orig 2020-06-12 06:49:55.000000000 -0500 +++ usr.bin/calendar/io.c 2020-06-21 08:27:41.472278000 -0500 @@ -51,24 +51,14 @@ #include #include #include -#include -#define _WITH_GETLINE #include #include #include -#include -#include #include #include "pathnames.h" #include "calendar.h" -enum { - T_OK = 0, - T_ERR, - T_PROCESS, -}; - const char *calendarFile = "calendar"; /* default calendar file */ static const char *calendarHomes[] = {".calendar", _PATH_INCLUDE}; /* HOME */ static const char *calendarNoMail = "nomail";/* don't sent mail if file exist */ @@ -78,151 +68,8 @@ struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon; struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice; -static int cal_parse(FILE *in, FILE *out); - -static StringList *definitions = NULL; -static struct event *events[MAXCOUNT]; -static char *extradata[MAXCOUNT]; - -static void -trimlr(char **buf) -{ - char *walk = *buf; - char *last; - - while (isspace(*walk)) - walk++; - if (*walk != '\0') { - last = walk + strlen(walk) - 1; - while (last > walk && isspace(*last)) - last--; - *(last+1) = 0; - } - - *buf = walk; -} - -static FILE * -cal_fopen(const char *file) -{ - FILE *fp; - char *home = getenv("HOME"); - unsigned int i; - - if (home == NULL || *home == '\0') { - warnx("Cannot get home directory"); - return (NULL); - } - - if (chdir(home) != 0) { - warnx("Cannot enter home directory"); - return (NULL); - } - - for (i = 0; i < nitems(calendarHomes); i++) { - if (chdir(calendarHomes[i]) != 0) - continue; - - if ((fp = fopen(file, "r")) != NULL) - return (fp); - } - - warnx("can't open calendar file \"%s\"", file); - - return (NULL); -} - -static int -token(char *line, FILE *out, bool *skip) -{ - char *walk, c, a; - - if (strncmp(line, "endif", 5) == 0) { - *skip = false; - return (T_OK); - } - - if (*skip) - return (T_OK); - - if (strncmp(line, "include", 7) == 0) { - walk = line + 7; - - trimlr(&walk); - - if (*walk == '\0') { - warnx("Expecting arguments after #include"); - return (T_ERR); - } - - if (*walk != '<' && *walk != '\"') { - warnx("Excecting '<' or '\"' after #include"); - return (T_ERR); - } - - a = *walk; - walk++; - c = walk[strlen(walk) - 1]; - - switch(c) { - case '>': - if (a != '<') { - warnx("Unterminated include expecting '\"'"); - return (T_ERR); - } - break; - case '\"': - if (a != '\"') { - warnx("Unterminated include expecting '>'"); - return (T_ERR); - } - break; - default: - warnx("Unterminated include expecting '%c'", - a == '<' ? '>' : '\"' ); - return (T_ERR); - } - walk[strlen(walk) - 1] = '\0'; - - if (cal_parse(cal_fopen(walk), out)) - return (T_ERR); - - return (T_OK); - } - - if (strncmp(line, "define", 6) == 0) { - if (definitions == NULL) - definitions = sl_init(); - walk = line + 6; - trimlr(&walk); - - if (*walk == '\0') { - warnx("Expecting arguments after #define"); - return (T_ERR); - } - - sl_add(definitions, strdup(walk)); - return (T_OK); - } - - if (strncmp(line, "ifndef", 6) == 0) { - walk = line + 6; - trimlr(&walk); - - if (*walk == '\0') { - warnx("Expecting arguments after #ifndef"); - return (T_ERR); - } - - if (definitions != NULL && sl_find(definitions, walk) != NULL) - *skip = true; - - return (T_OK); - } - - return (T_PROCESS); - -} +static void closecal(FILE *fp); +static FILE *opencal(void); #define REPLACE(string, slen, struct_) \ if (strncasecmp(buf, (string), (slen)) == 0 && buf[(slen)]) { \ @@ -233,55 +80,42 @@ struct_.len = strlen(buf + (slen)); \ continue; \ } -static int -cal_parse(FILE *in, FILE *out) + +void +cal(void) { - char *line = NULL; - char *buf; - size_t linecap = 0; - ssize_t linelen; - ssize_t l; - static int d_first = -1; - static int count = 0; - int i; + char *pp, p; + FILE *fp; + int ch, l; + int count, i; int month[MAXCOUNT]; int day[MAXCOUNT]; int year[MAXCOUNT]; - bool skip = false; - char dbuf[80]; - char *pp, p; - struct tm tm; + char **extradata; /* strings of 20 length */ int flags; + static int d_first = -1; + char buf[2048 + 1]; + struct event *events[MAXCOUNT]; + struct tm tm; + char dbuf[80]; - /* Unused */ - tm.tm_sec = 0; - tm.tm_min = 0; - tm.tm_hour = 0; - tm.tm_wday = 0; - - if (in == NULL) - return (1); - - while ((linelen = getline(&line, &linecap, in)) > 0) { - if (*line == '#') { - switch (token(line+1, out, &skip)) { - case T_ERR: - free(line); - return (1); - case T_OK: - continue; - case T_PROCESS: - break; - default: - break; - } - } - - if (skip) - continue; + extradata = (char **)calloc(MAXCOUNT, sizeof(char *)); + for (i = 0; i < MAXCOUNT; i++) { + extradata[i] = (char *)calloc(1, 20); + } - buf = line; - for (l = linelen; + count = 0; + if ((fp = opencal()) == NULL) { + free(extradata); + return; + } + while (fgets(buf, sizeof(buf), stdin) != NULL) { + if ((pp = strchr(buf, '\n')) != NULL) + *pp = '\0'; + else + /* Flush this line */ + while ((ch = getchar()) != '\n' && ch != EOF); + for (l = strlen(buf); l > 0 && isspace((unsigned char)buf[l - 1]); l--) ; @@ -368,64 +202,83 @@ } } - free(line); - fclose(in); - - return (0); -} - -void -cal(void) -{ - FILE *fpin; - FILE *fpout; - int i; - - for (i = 0; i < MAXCOUNT; i++) - extradata[i] = (char *)calloc(1, 20); - - - if ((fpin = opencalin()) == NULL) - return; - - if ((fpout = opencalout()) == NULL) { - fclose(fpin); - return; - } - - if (cal_parse(fpin, fpout)) - return; - - event_print_all(fpout); - closecal(fpout); + event_print_all(fp); + closecal(fp); + free(extradata); } -FILE * -opencalin(void) +static FILE * +opencal(void) { + uid_t uid; + size_t i; + int fd, found, pdes[2]; struct stat sbuf; - FILE *fpin; - /* open up calendar file */ - if ((fpin = fopen(calendarFile, "r")) == NULL) { + /* open up calendar file as stdin */ + if (!freopen(calendarFile, "r", stdin)) { if (doall) { if (chdir(calendarHomes[0]) != 0) return (NULL); if (stat(calendarNoMail, &sbuf) == 0) return (NULL); - if ((fpin = fopen(calendarFile, "r")) == NULL) + if (!freopen(calendarFile, "r", stdin)) return (NULL); } else { - fpin = cal_fopen(calendarFile); + char *home = getenv("HOME"); + if (home == NULL || *home == '\0') + errx(1, "cannot get home directory"); + if (chdir(home) != 0) + errx(1, "cannot enter home directory"); + for (found = i = 0; i < sizeof(calendarHomes) / + sizeof(calendarHomes[0]); i++) + if (chdir(calendarHomes[i]) == 0 && + freopen(calendarFile, "r", stdin)) { + found = 1; + break; + } + if (!found) + errx(1, + "can't open calendar file \"%s\": %s (%d)", + calendarFile, strerror(errno), errno); } } - return (fpin); -} - -FILE * -opencalout(void) -{ - int fd; + if (pipe(pdes) < 0) + return (NULL); + switch (fork()) { + 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]); + uid = geteuid(); + if (setuid(getuid()) < 0) { + warnx("first setuid failed"); + _exit(1); + } + if (setgid(getegid()) < 0) { + warnx("setgid failed"); + _exit(1); + } + if (setuid(uid) < 0) { + warnx("setuid failed"); + _exit(1); + } + execl(_PATH_CPP, "cpp", "-traditional", "-undef", "-U__GNUC__", + "-P", "-I.", "-I"_PATH_INCLUDE, (char *)NULL); + warn(_PATH_CPP); + _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) @@ -438,7 +291,7 @@ return (fdopen(fd, "w+")); } -void +static void closecal(FILE *fp) { uid_t uid; --- usr.bin/calendar/pathnames.h.orig 2020-06-12 06:49:55.000000000 -0500 +++ usr.bin/calendar/pathnames.h 2020-06-21 08:27:41.472474000 -0500 @@ -32,4 +32,5 @@ #include +#define _PATH_CPP "/usr/local/bin/tradcpp" #define _PATH_INCLUDE "/usr/share/calendar"