* Copyright (c) 1989 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)calendar.c 4.9 (Berkeley) %G%";
while ((ch
= getopt(argc
, argv
, "-a")) != EOF
)
case '-': /* backward contemptible */
"calendar: %s\n", strerror(EPERM
));
while (pw
= getpwent()) {
(void)setegid(pw
->pw_gid
);
(void)seteuid(pw
->pw_uid
);
for (printing
= 0; fgets(buf
, sizeof(buf
), stdin
);) {
if (p
= index(buf
, '\n'))
while ((ch
= getchar()) != '\n' && ch
!= EOF
);
printing
= isnow(buf
) ? 1 : 0;
(void)fprintf(fp
, "%s\n", buf
);
struct iovec header
[] = {
" (Reminder Service)\nTo: ", 24,
"'s Calendar\nPrecedence: bulk\n\n", 30,
/* 1-based month, 0-based days, cumulative */
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,
int *cumdays
, offset
, yrdays
;
if (isleap(tp
->tm_year
+ 1900)) {
/* Friday displays Monday's events */
offset
= tp
->tm_wday
== 6 ? 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.
int day
, flags
, month
, v1
, v2
;
/* didn't recognize anything, skip it */
if (!(v1
= getfield(endp
, &endp
, &flags
)))
if (flags
&F_ISDAY
|| v1
> 12) {
/* if no recognizable month, assume just a day alone */
if (!(month
= getfield(endp
, &endp
, &flags
)))
} else if (flags
&F_ISMONTH
) {
/* if no recognizable day, assume the first */
if (!(day
= getfield(endp
, &endp
, &flags
)))
v2
= getfield(endp
, &endp
, &flags
);
/* F_ISDAY set, v2 > 12, or no way to tell */
/* if no recognizable day, assume the first */
day
= cumdays
[month
] + day
;
/* if today or today + offset days */
if (day
>= tp
->tm_yday
&& day
<= tp
->tm_yday
+ offset
)
/* if number of days left in this year + days to event in next year */
if (yrdays
- tp
->tm_yday
+ day
<= offset
)
if (*p
== '*') { /* `*' is current month */
val
= strtol(p
, &p
, 10); /* if 0, it's failure */
for (; !isdigit(*p
) && !isalpha(*p
); ++p
);
for (start
= p
; isalpha(*++p
););
if (val
= getmonth(start
))
else if (val
= getday(start
))
for (*p
= savech
; !isdigit(*p
) && !isalpha(*p
); ++p
);
char path
[MAXPATHLEN
+ 1];
/* open up calendar file as stdin */
if (!freopen("calendar", "r", stdin
)) {
(void)fprintf(stderr
, "calendar: no calendar file.\n");
/* child -- stdin already setup, set stdout to pipe input */
if (pdes
[1] != STDOUT_FILENO
) {
(void)dup2(pdes
[1], STDOUT_FILENO
);
execl(_PATH_CPP
, "cpp", "-I.", _PATH_INCLUDE
, NULL
);
/* parent -- set stdin to pipe output */
(void)dup2(pdes
[0], STDIN_FILENO
);
/* not reading all calendar files, just set output to 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(fdopen(fd
, "w+"));
int nread
, pdes
[2], status
;
char buf
[1024], *mktemp();
if (fstat(fileno(fp
), &sbuf
) || !sbuf
.st_size
)
/* child -- set stdin to pipe output */
if (pdes
[0] != STDIN_FILENO
) {
(void)dup2(pdes
[0], STDIN_FILENO
);
execl(_PATH_SENDMAIL
, "sendmail", "-i", "-t", "-F",
"\"Reminder Service\"", "-f", "root", NULL
);
(void)fprintf(stderr
, "calendar: %s: %s.\n",
_PATH_SENDMAIL
, strerror(errno
));
/* parent -- write to pipe input */
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
);
while (wait(&status
) >= 0);
static char *months
[] = {
"jan", "feb", "mar", "apr", "may", "jun",
"jul", "aug", "sep", "oct", "nov", "dec", NULL
,
for (p
= months
; *p
; ++p
)
if (!strncasecmp(s
, *p
, 3))
return((p
- months
) + 1);
"sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL
,
if (!strncasecmp(s
, *p
, 3))
(void)fprintf(stderr
, "usage: calendar [-a]\n");