=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/calendar/day.c,v retrieving revision 1.8 retrieving revision 1.22 diff -u -r1.8 -r1.22 --- src/usr.bin/calendar/day.c 1999/03/04 03:34:35 1.8 +++ src/usr.bin/calendar/day.c 2009/10/27 23:59:36 1.22 @@ -1,4 +1,4 @@ -/* $OpenBSD: day.c,v 1.8 1999/03/04 03:34:35 pjanzen Exp $ */ +/* $OpenBSD: day.c,v 1.22 2009/10/27 23:59:36 deraadt Exp $ */ /* * Copyright (c) 1989, 1993, 1994 @@ -12,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,20 +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 char rcsid[] = "$OpenBSD: day.c,v 1.8 1999/03/04 03:34:35 pjanzen Exp $"; -#endif -#endif /* not lint */ - #include #include @@ -69,6 +51,8 @@ struct tm *tp; int *cumdays, offset; char dayname[10]; +enum calendars calendar; +u_long julian; /* 1-based month, 0-based days, cumulative */ @@ -93,7 +77,8 @@ static struct fixs nmonths[13]; /* short national month names */ -void setnnames(void) +void +setnnames(void) { char buf[80]; int i, l; @@ -108,7 +93,7 @@ if (ndays[i].name != NULL) free(ndays[i].name); if ((ndays[i].name = strdup(buf)) == NULL) - errx(1, "cannot allocate memory"); + err(1, NULL); ndays[i].len = strlen(buf); l = strftime(buf, sizeof(buf), "%A", &tm); @@ -118,7 +103,7 @@ if (fndays[i].name != NULL) free(fndays[i].name); if ((fndays[i].name = strdup(buf)) == NULL) - errx(1, "cannot allocate memory"); + err(1, NULL); fndays[i].len = strlen(buf); } @@ -131,7 +116,7 @@ if (nmonths[i].name != NULL) free(nmonths[i].name); if ((nmonths[i].name = strdup(buf)) == NULL) - errx(1, "cannot allocate memory"); + err(1, NULL); nmonths[i].len = strlen(buf); l = strftime(buf, sizeof(buf), "%B", &tm); @@ -141,26 +126,28 @@ if (fnmonths[i].name != NULL) free(fnmonths[i].name); if ((fnmonths[i].name = strdup(buf)) == NULL) - errx(1, "cannot allocate memory"); + err(1, NULL); fnmonths[i].len = strlen(buf); } /* Hardwired special events */ - spev[0].name = strdup(EASTER); - spev[0].nlen = EASTERNAMELEN; - spev[0].getev = easter; - spev[1].name = strdup(PASKHA); - spev[1].nlen = PASKHALEN; - spev[1].getev = paskha; + spev[0].name = strdup(PESACH); + spev[0].nlen = PESACHLEN; + spev[0].getev = pesach; + spev[1].name = strdup(EASTER); + spev[1].nlen = EASTERNAMELEN; + spev[1].getev = easter; + spev[2].name = strdup(PASKHA); + spev[2].nlen = PASKHALEN; + spev[2].getev = paskha; for (i = 0; i < NUMEV; i++) { if (spev[i].name == NULL) - errx(1, "cannot allocate memory"); + err(1, NULL); spev[i].uname = NULL; } } void -settime(now) - time_t *now; +settime(time_t *now) { tp = localtime(now); tp->tm_sec = 0; @@ -175,7 +162,7 @@ cumdays = daytab[0]; /* Friday displays Monday's events */ offset = tp->tm_wday == 5 ? 3 : 1; - if (f_dayAfter) + if (f_SetdayAfter) offset = 0; /* Except not when range is set explicitly */ header[5].iov_base = dayname; @@ -189,72 +176,91 @@ /* convert [Year][Month]Day into unix time (since 1970) * Year: two or four digits, Month: two digits, Day: two digits */ -time_t Mktime (date) - char *date; +time_t +Mktime(char *date) { - time_t t; - int len; - struct tm tm; + time_t t; + int len; + struct tm tm; - (void)time(&t); - tp = localtime(&t); + (void)time(&t); + tp = localtime(&t); - len = strlen(date); - if (len < 2) - return((time_t)-1); - tm.tm_sec = 0; - tm.tm_min = 0; - /* Avoid getting caught by a timezone shift; set time to noon */ - tm.tm_isdst = 0; - tm.tm_hour = 12; - tm.tm_wday = 0; - tm.tm_mday = tp->tm_mday; - tm.tm_mon = tp->tm_mon; - tm.tm_year = tp->tm_year; + len = strlen(date); + if (len < 2) + return((time_t)-1); + tm.tm_sec = 0; + tm.tm_min = 0; + /* Avoid getting caught by a timezone shift; set time to noon */ + tm.tm_isdst = 0; + tm.tm_hour = 12; + tm.tm_wday = 0; + tm.tm_mday = tp->tm_mday; + tm.tm_mon = tp->tm_mon; + tm.tm_year = tp->tm_year; - /* Day */ - tm.tm_mday = atoi(date + len - 2); + /* Day */ + tm.tm_mday = atoi(date + len - 2); - /* Month */ - if (len >= 4) { - *(date + len - 2) = '\0'; - tm.tm_mon = atoi(date + len - 4) - 1; - } + /* Month */ + if (len >= 4) { + *(date + len - 2) = '\0'; + tm.tm_mon = atoi(date + len - 4) - 1; + } - /* Year */ - if (len >= 6) { + /* Year */ + if (len >= 6) { *(date + len - 4) = '\0'; tm.tm_year = atoi(date); - /* tm_year up TM_YEAR_BASE ... */ - if (tm.tm_year < 69) /* Y2K */ - tm.tm_year += 2000 - TM_YEAR_BASE; - else if (tm.tm_year < 100) - tm.tm_year += 1900 - TM_YEAR_BASE; - else if (tm.tm_year > TM_YEAR_BASE) - tm.tm_year -= TM_YEAR_BASE; - } + /* tm_year up TM_YEAR_BASE ... */ + if (tm.tm_year < 69) /* Y2K */ + tm.tm_year += 2000 - TM_YEAR_BASE; + else if (tm.tm_year < 100) + tm.tm_year += 1900 - TM_YEAR_BASE; + else if (tm.tm_year > TM_YEAR_BASE) + tm.tm_year -= TM_YEAR_BASE; + } #if DEBUG - printf("Mktime: %d %d %d %s\n", (int)mktime(&tm), (int)t, len, - asctime(&tm)); + printf("Mktime: %d %d %d %s\n", (int)mktime(&tm), (int)t, len, + asctime(&tm)); #endif - return(mktime(&tm)); + return(mktime(&tm)); } +void +adjust_calendar(int *day, int *month) +{ + switch (calendar) { + case GREGORIAN: + break; + + case JULIAN: + *day += julian; + if (*day > (cumdays[*month + 1] - cumdays[*month])) { + *day -= (cumdays[*month + 1] - cumdays[*month]); + if (++*month > 12) + *month = 1; + } + break; + case LUNAR: + break; + } +} + /* * 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. + * Any character except \t or '*' may separate them, or they may not be + * separated. Any line following a line that is matched, that starts + * with \t, is shown along with the matched line. */ struct match * -isnow(endp) - char *endp; +isnow(char *endp, int bodun) { int day = 0, flags = 0, month = 0, v1, v2, i; int monthp, dayp, varp = 0; @@ -279,6 +285,10 @@ if (!(v1 = getfield(endp, &endp, &flags))) return (NULL); + /* adjust bodun rate */ + if (bodun && !bodun_always) + bodun = !arc4random_uniform(3); + /* Easter or Easter depending days */ if (flags & F_SPECIAL) vwd = v1; @@ -311,7 +321,8 @@ if (month == -1) { month = tp->tm_mon + 1; interval = MONTHLY; - } + } else if (calendar) + adjust_calendar(&day, &month); if ((month > 12) || (month < 1)) return (NULL); } @@ -329,8 +340,11 @@ day = 1; /* If a weekday was spelled out without an ordering, * assume the first of that day in the month */ - if ((flags & F_ISDAY) && (day >= 1) && (day <=7)) - day += 10; + if ((flags & F_ISDAY)) { + if ((day >= 1) && (day <=7)) + day += 10; + } else if (calendar) + adjust_calendar(&day, &month); } /* Hm ... */ @@ -347,7 +361,8 @@ if (month == -1) { month = tp->tm_mon + 1; interval = MONTHLY; - } + } else if (calendar) + adjust_calendar(&day, &month); } /* {Month} {Weekday,Day} ... */ @@ -356,8 +371,11 @@ month = v1; /* if no recognizable day, assume the first */ day = v2 ? v2 : 1; - if ((flags & F_ISDAY) && (day >= 1) && (day <= 7)) - day += 10; + if ((flags & F_ISDAY)) { + if ((day >= 1) && (day <= 7)) + day += 10; + } else + adjust_calendar(&day, &month); } } @@ -423,24 +441,33 @@ if ((v2 += isleap(tp->tm_year + TM_YEAR_BASE) ? 366 : 365) <= v1) tmtmp.tm_year++; - else + else if(!bodun || (day - tp->tm_yday) != -1) return(NULL); } if ((tmp = malloc(sizeof(struct match))) == NULL) - errx(1, "cannot allocate memory"); - tmp->when = f_time + v2 * SECSPERDAY; + err(1, NULL); + + if (bodun && (day - tp->tm_yday) == -1) { + tmp->when = f_time - 1 * SECSPERDAY; + tmtmp.tm_mday++; + tmp->bodun = 1; + } else { + tmp->when = f_time + v2 * SECSPERDAY; + tmp->bodun = 0; + } + (void)mktime(&tmtmp); if (strftime(tmp->print_date, sizeof(tmp->print_date), /* "%a %b %d", &tm); Skip weekdays */ "%b %d", &tmtmp) == 0) tmp->print_date[sizeof(tmp->print_date) - 1] = '\0'; + tmp->var = varp; tmp->next = NULL; return(tmp); } - } - else { + } else { varp = 1; /* Set up v1 to the event number and ... */ v1 = vwd % (NUMEV + 1) - 1; @@ -498,7 +525,7 @@ if (flags & F_SPECIAL) { tmtmp.tm_mon = 0; /* Gee, mktime() is nice */ tmtmp.tm_mday = spev[v1].getev(tmtmp.tm_year + - vwd + TM_YEAR_BASE); + TM_YEAR_BASE) + vwd; } else if (vwd) { v1 = vwd; variable_weekday(&v1, tmtmp.tm_mon + 1, @@ -517,16 +544,19 @@ warnx("time out of range: %s", endp); else { tdiff = difftime(ttmp, f_time)/ SECSPERDAY; - if (tdiff <= offset + f_dayAfter) { - if (tdiff >= 0) { + if (tdiff <= offset + f_dayAfter || + (bodun && tdiff == -1)) { + if (tdiff >= 0 || + (bodun && tdiff == -1)) { if ((tmp = malloc(sizeof(struct match))) == NULL) - errx(1, "cannot allocate memory"); + err(1, NULL); tmp->when = ttmp; if (strftime(tmp->print_date, sizeof(tmp->print_date), /* "%a %b %d", &tm); Skip weekdays */ "%b %d", &tmtmp) == 0) tmp->print_date[sizeof(tmp->print_date) - 1] = '\0'; + tmp->bodun = bodun && tdiff == -1; tmp->var = varp; tmp->next = NULL; if (tmp2) @@ -546,10 +576,9 @@ int -getmonth(s) - register char *s; +getmonth(char *s) { - register char **p; + char **p; struct fixs *n; for (n = fnmonths; n->name; ++n) @@ -566,10 +595,9 @@ int -getday(s) - register char *s; +getday(char *s) { - register char **p; + char **p; struct fixs *n; for (n = fndays; n->name; ++n) @@ -590,10 +618,9 @@ * ... etc ... */ int -getdayvar(s) - register char *s; +getdayvar(char *s) { - register int offset; + int offset; offset = strlen(s); @@ -631,8 +658,7 @@ int -foy(year) - int year; +foy(int year) { /* 0-6; what weekday Jan 1 is */ year--; @@ -642,8 +668,7 @@ void -variable_weekday(day, month, year) - int *day, month, year; +variable_weekday(int *day, int month, int year) { int v1, v2; int *cumdays;