=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/calendar/io.c,v retrieving revision 1.33 retrieving revision 1.47 diff -u -r1.33 -r1.47 --- src/usr.bin/calendar/io.c 2006/12/11 20:50:54 1.33 +++ src/usr.bin/calendar/io.c 2017/09/25 19:13:56 1.47 @@ -1,4 +1,4 @@ -/* $OpenBSD: io.c,v 1.33 2006/12/11 20:50:54 deraadt Exp $ */ +/* $OpenBSD: io.c,v 1.47 2017/09/25 19:13:56 krw Exp $ */ /* * Copyright (c) 1989, 1993, 1994 @@ -29,21 +29,6 @@ * SUCH DAMAGE. */ -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1989, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static const char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; -#else -static const char rcsid[] = "$OpenBSD: io.c,v 1.33 2006/12/11 20:50:54 deraadt Exp $"; -#endif -#endif /* not lint */ - -#include #include #include #include @@ -59,8 +44,8 @@ #include #include #include -#include #include +#include #include "pathnames.h" #include "calendar.h" @@ -85,7 +70,6 @@ struct event *events, *cur_evt, *ev1, *tmp; char buf[2048 + 1], *prefix = NULL, *p; struct match *m; - size_t nlen; FILE *fp; events = NULL; @@ -105,13 +89,12 @@ if (strncmp(buf, "LANG=", 5) == 0) { (void) setlocale(LC_ALL, buf + 5); setnnames(); - if (!strcmp(buf + 5, "ru_RU.KOI8-R") || - !strcmp(buf + 5, "uk_UA.KOI8-U") || - !strcmp(buf + 5, "by_BY.KOI8-B")) { + if (!strcmp(buf + 5, "ru_RU.UTF-8") || + !strcmp(buf + 5, "uk_UA.UTF-8") || + !strcmp(buf + 5, "by_BY.UTF-8")) { bodun_maybe++; bodun = 0; - if (prefix) - free(prefix); + free(prefix); prefix = NULL; } else bodun_maybe = 0; @@ -136,8 +119,7 @@ calendar = LUNAR; } else if (bodun_maybe && strncmp(buf, "BODUN=", 6) == 0) { bodun++; - if (prefix) - free(prefix); + free(prefix); if ((prefix = strdup(buf + 6)) == NULL) err(1, NULL); continue; @@ -150,8 +132,7 @@ (p - buf == spev[i].nlen) && buf[spev[i].nlen + 1]) { p++; - if (spev[i].uname != NULL) - free(spev[i].uname); + free(spev[i].uname); if ((spev[i].uname = strdup(p)) == NULL) err(1, NULL); spev[i].ulen = strlen(p); @@ -175,13 +156,13 @@ var = 0; if (printing) { struct match *foo; - + ev1 = NULL; while (m) { cur_evt = malloc(sizeof(struct event)); if (cur_evt == NULL) err(1, NULL); - + cur_evt->when = m->when; snprintf(cur_evt->print_date, sizeof(cur_evt->print_date), "%s%c", @@ -223,8 +204,7 @@ tmp = events; while (tmp) { events = tmp; - if (tmp->ldesc) - free(tmp->ldesc); + free(tmp->ldesc); tmp = tmp->next; free(events); } @@ -237,26 +217,28 @@ int val, var, i; char *start, savech; - for (; !isdigit(*p) && !isalpha(*p) && *p != '*' && *p != '\t'; ++p) + for (; !isdigit((unsigned char)*p) && !isalpha((unsigned char)*p) && + *p != '*' && *p != '\t'; ++p) ; if (*p == '*') { /* `*' is every month */ *flags |= F_ISMONTH; *endp = p+1; return (-1); /* means 'every month' */ } - if (isdigit(*p)) { + if (isdigit((unsigned char)*p)) { val = strtol(p, &p, 10); /* if 0, it's failure */ - for (; !isdigit(*p) && !isalpha(*p) && *p != '*'; ++p) + for (; !isdigit((unsigned char)*p) && + !isalpha((unsigned char)*p) && *p != '*'; ++p) ; *endp = p; return (val); } - for (start = p; isalpha(*++p);) + for (start = p; isalpha((unsigned char)*++p);) ; /* Sunday-1 */ if (*p == '+' || *p == '-') - for(; isdigit(*++p); ) + for(; isdigit((unsigned char)*++p); ) ; savech = *p; @@ -295,12 +277,16 @@ } } if (i > NUMEV) { - switch(*start) { + const char *errstr; + + switch (*start) { case '-': case '+': - var = atoi(start); - if (var > 365 || var < -365) + var = strtonum(start + 1, 0, 365, &errstr); + if (errstr) return (0); /* Someone is just being silly */ + if (*start == '-') + var = -var; 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. @@ -308,7 +294,7 @@ * number of special events. */ break; } - *flags |= F_SPECIAL; + *flags |= F_SPECIAL; } if (!(*flags & F_SPECIAL)) { /* undefined rest */ @@ -316,7 +302,8 @@ return (0); } } - for (*p = savech; !isdigit(*p) && !isalpha(*p) && *p != '*' && *p != '\t'; ++p) + for (*p = savech; !isdigit((unsigned char)*p) && + !isalpha((unsigned char)*p) && *p != '*' && *p != '\t'; ++p) ; *endp = p; return (val); @@ -344,12 +331,15 @@ } } - if (pipe(pdes) < 0) + if (pipe(pdes) < 0) { + close(fdin); return (NULL); + } switch (vfork()) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]); + close(fdin); return (NULL); case 0: dup2(fdin, STDIN_FILENO); @@ -359,7 +349,7 @@ (void)close(pdes[1]); } (void)close(pdes[0]); - /* + /* * Set stderr to /dev/null. Necessary so that cron does not * wait for cpp to finish if it's running calendar -a. */ @@ -395,6 +385,7 @@ struct stat sbuf; int nread, pdes[2], status; char buf[1024]; + pid_t pid = -1; if (!doall) return; @@ -404,7 +395,7 @@ goto done; if (pipe(pdes) < 0) goto done; - switch (vfork()) { + switch ((pid = vfork())) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]); @@ -431,8 +422,12 @@ (void)write(pdes[1], buf, nread); (void)close(pdes[1]); done: (void)fclose(fp); - while (wait(&status) >= 0) - ; + if (pid != -1) { + while (waitpid(pid, &status, 0) == -1) { + if (errno != EINTR) + break; + } + } }