Subject: bin/3935: calendar(1) enchancements
To: None <gnats-bugs@gnats.netbsd.org>
From: None <tsarna@endicor.com>
List: netbsd-bugs
Date: 08/03/1997 22:10:35
>Number: 3935
>Category: bin
>Synopsis: calendar(1) enchancements
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people (Utility Bug People)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Aug 3 20:20:01 1997
>Last-Modified:
>Originator: Ty Sarna
>Organization:
Endicor Technologies, Inc., San Antonio, Texas
>Release: NetBSD-current
>Environment:
System: NetBSD lotharon.endicor.com 1.2B NetBSD 1.2B (LOTHARON) #1: Thu Dec 12 12:09:19 CST 1996 tsarna@lotharon.endicor.com:/usr/src/sys/arch/sun3/compile/LOTHARON sun3
>Description:
I wanted to be able to do several things with calendar(1)
that I couldn't, including:
- get entries from a file other than "calendar".
- get entries for a different date than today
- get entries for a whole week in advance, or only one day.
So I added flags that allow these things. See the manpage diffs
for details.
Still to do: allow holidays that move around to be specified
correctly.
>How-To-Repeat:
See above.
>Fix:
Apply this:
*** calendar.c.orig Mon Mar 17 01:18:11 1997
--- calendar.c Sun Apr 6 19:13:33 1997
***************
*** 65,77 ****
--- 65,88 ----
#include "pathnames.h"
+ #ifndef TRUE
+ #define TRUE 1
+ #endif
+ #ifndef FALSE
+ #define FALSE 0
+ #endif
+
+ unsigned short lookahead = 1, weekend = 2;
+ char *fname = "calendar", *datestr = NULL;
struct passwd *pw;
int doall;
+ void atodays __P((char, char *, unsigned short *));
void cal __P((void));
void closecal __P((FILE *));
int getday __P((char *));
int getfield __P((char *, char **, int *));
+ void getmmdd(struct tm *tp, char *ds);
int getmonth __P((char *));
int isnow __P((char *));
FILE *opencal __P((void));
***************
*** 87,93 ****
int ch;
char *caldir;
! while ((ch = getopt(argc, argv, "-a")) != EOF)
switch (ch) {
case '-': /* backward contemptible */
case 'a':
--- 98,104 ----
int ch;
char *caldir;
! while ((ch = getopt(argc, argv, "-ad:f:l:w:")) != EOF)
switch (ch) {
case '-': /* backward contemptible */
case 'a':
***************
*** 97,102 ****
--- 108,125 ----
}
doall = 1;
break;
+ case 'd':
+ datestr = optarg;
+ break;
+ case 'f':
+ fname = optarg;
+ break;
+ case 'l':
+ atodays(ch, optarg, &lookahead);
+ break;
+ case 'w':
+ atodays(ch, optarg, &weekend);
+ break;
case '?':
default:
usage();
***************
*** 176,181 ****
--- 199,207 ----
(void)time(&now);
tp = localtime(&now);
+ if (datestr) {
+ getmmdd(tp, datestr);
+ }
if (isleap(tp->tm_year + 1900)) {
yrdays = DAYSPERLYEAR;
cumdays = daytab[1];
***************
*** 184,190 ****
cumdays = daytab[0];
}
/* Friday displays Monday's events */
! offset = tp->tm_wday == 5 ? 3 : 1;
header[5].iov_base = dayname;
header[5].iov_len = strftime(dayname, sizeof(dayname), "%A", tp);
}
--- 210,216 ----
cumdays = daytab[0];
}
/* Friday displays Monday's events */
! offset = tp->tm_wday == 5 ? lookahead + weekend : lookahead;
header[5].iov_base = dayname;
header[5].iov_len = strftime(dayname, sizeof(dayname), "%A", tp);
}
***************
*** 289,300 ****
int fd, pdes[2];
/* open up calendar file as stdin */
! if (!freopen("calendar", "r", stdin)) {
if (doall)
return (NULL);
errx(1, "no calendar file.");
}
! if (pipe(pdes) < 0)
return (NULL);
switch (vfork()) {
case -1: /* error */
--- 315,326 ----
int fd, pdes[2];
/* open up calendar file as stdin */
! if (!freopen(fname, "r", stdin)) {
if (doall)
return (NULL);
errx(1, "no calendar file.");
}
! if (pipe(pdes) < 0)
return (NULL);
switch (vfork()) {
case -1: /* error */
***************
*** 342,355 ****
(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);
--- 368,381 ----
(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);
***************
*** 409,416 ****
}
void
usage()
{
! (void)fprintf(stderr, "usage: calendar [-a]\n");
exit(1);
}
--- 435,510 ----
}
void
+ atodays(char ch, char *optarg, unsigned short *days)
+ {
+ extern char *__progname;
+ int u;
+
+ u = atoi(optarg);
+ if ((u < 0) || (u > 366)) {
+ fprintf(stderr,
+ "%s: warning: -%c %d out of range 0-366, ignored.\n",
+ __progname, ch, u);
+ } else {
+ *days = u;
+ }
+ }
+
+ #define todigit(x) ((x) - '0')
+ #define ATOI2(x) (todigit((x)[0]) * 10 + todigit((x)[1]))
+ #define ISDIG2(x) (isdigit((x)[0]) && isdigit((x)[1]))
+
+ void
+ getmmdd(struct tm *tp, char *ds)
+ {
+ extern char *__progname;
+ int ok = FALSE;
+ struct tm ttm;
+ char *t;
+
+ ttm = *tp;
+ ttm.tm_isdst = -1;
+
+ if (ISDIG2(ds)) {
+ ttm.tm_mon = ATOI2(ds) - 1;
+ ds += 2;
+ }
+
+ if (ISDIG2(ds)) {
+ ttm.tm_mday = ATOI2(ds);
+ ds += 2;
+
+ ok = TRUE;
+ }
+
+ if (ok) {
+ if (ISDIG2(ds) && ISDIG2(ds + 2)) {
+ ttm.tm_year = ATOI2(ds) * 100 - 1900;
+ ds += 2;
+ ttm.tm_year += ATOI2(ds);
+ } else if (ISDIG2(ds)) {
+ ttm.tm_year = ATOI2(ds);
+ }
+ }
+
+ if (ok && (mktime(&ttm) < 0)) {
+ ok = FALSE;
+ }
+
+ if (ok) {
+ *tp = ttm;
+ } else {
+ fprintf(stderr,
+ "%s: warning: can't convert %s to date, ignored.\n",
+ __progname, ds);
+ usage();
+ }
+ }
+
+ void
usage()
{
! (void)fprintf(stderr, "usage: calendar [-a] [-d MMDD[[YY]YY]" \
! " [-f fname] [-l days] [-w days]\n");
exit(1);
}
*** calendar.1.orig Thu Jul 31 11:31:23 1997
--- calendar.1 Sun Aug 3 21:46:05 1997
***************
*** 42,57 ****
.Sh SYNOPSIS
.Nm calendar
.Op Fl a
.Sh DESCRIPTION
The
.Nm calendar
! utility checks the current directory or the directory specified by the
! .Dq Ev CALENDAR_DIR
! environment variable for a file named
! .Pa calendar
! and displays lines that begin with either today's date
! or tomorrow's.
! On Fridays, events on Friday through Monday are displayed.
.Pp
The following options are available:
.Bl -tag -width Ds
--- 42,55 ----
.Sh SYNOPSIS
.Nm calendar
.Op Fl a
+ .Op Fl f Ar file
+ .Op Fl l Ar days
+ .Op Fl w Ar days
+ .Op Fl d Ar MMDD[[YY]YY]
.Sh DESCRIPTION
The
.Nm calendar
! utility processes text files and displays lines that match certain dates.
.Pp
The following options are available:
.Bl -tag -width Ds
***************
*** 59,64 ****
--- 57,87 ----
Process the ``calendar'' files of all users and mail the results
to them.
This requires super-user privileges.
+ .It Fl d Ar MMDD[[YY]YY]
+ Display lines for the given date. By default, the current date is used.
+ The year, which may be given in either two or four digit format, is used
+ only for purposes of determining wether the given date falls on a Friday
+ in that year (see below). If the year is not specified, the current
+ year is assumed.
+ .It Fl f Ar file
+ Display matching calendar files from the given filename, by default
+ .Pa calendar .
+ The filename may be absolute. If not absolute, it is taken
+ relative to the current directory or the directory specified by the
+ .Dq Ev CALENDAR_DIR
+ environment variable. Or, if the
+ .Fl a
+ flag is given, a non-absolute filename is taken relative to each user's
+ home directory in turn.
+ .It Fl l Ar days
+ Causes the program to ``look ahead'' a given number of days (default
+ one) from the specified date and display their entries as well.
+ .It Fl w Ar days
+ Causes the program to add the specified number of days to the ``look
+ ahead'' number if and only if the day specified is a Friday. The default
+ value is two, which causes
+ .Nm calendar
+ to print entries through the weekend on Fridays.
.El
.Pp
Lines should begin with a month and day.
>Audit-Trail:
>Unformatted: