Subject: bin/30771: [PATCH] add -m option to calendar(1)
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Denis Lagno <dlagno@rambler.ru>
List: netbsd-bugs
Date: 07/17/2005 22:13:00
>Number:         30771
>Category:       bin
>Synopsis:       patch to add -m option to calendar(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Jul 17 22:13:00 +0000 2005
>Originator:     Denis Lagno
>Release:        NetBSD 3.99.7
>Organization:
>Environment:
System: NetBSD flam.gado 3.99.7 NetBSD 3.99.7 (FLAM) #0: Fri Jul 15 03:56:37 MSD 2005 dina@flam.gado:/volatile/worksrc/netbsd-current/src/sys/arch/i386/compile/FLAM i386
Architecture: i386
Machine: i386
>Description:
calendar has two functions: it can print calendar to stdout and it can mail it to user.
However mailing to user is currently implemented only via -a option (for superuser only)
and it mails to ALL users on system (including pseudo-users).

The patch adds -m option which allows:

user can put
calendar -m $USER
to his crontab

root can put
calendar -m user1 -m user2 -m user3
to root crontab

Effect would be mailing calendars to user1, user2, user3.
>How-To-Repeat:
>Fix:
--- calendar.c.orig	2005-07-17 15:50:24.000000000 +0400
+++ calendar.c	2005-07-18 01:54:28.000000000 +0400
@@ -47,6 +47,7 @@
 #include <sys/stat.h>
 #include <sys/uio.h>
 #include <sys/wait.h>
+#include <sys/queue.h>
 
 #include <ctype.h>
 #include <err.h>
@@ -74,6 +75,7 @@
 static char *defaultnames[] = {"calendar", ".calendar", _PATH_SYSTEM_CALENDAR, NULL};
 static struct passwd *pw;
 static int doall;
+static int domailing;
 static char path[MAXPATHLEN + 1];
 static int cpp_restricted = 0;
 
@@ -105,6 +107,14 @@
 	"jul", "aug", "sep", "oct", "nov", "dec", NULL,
 };
 
+struct uentry {
+	SLIST_ENTRY(uentry) ulink;
+	char *name;
+};
+
+static SLIST_HEAD(, uentry) ulist;
+static struct uentry *ue;
+
 int	 main(int, char **);
 
 static void	 atodays(int, char *, unsigned short *);
@@ -127,7 +137,7 @@
 	int ch;
 	const char *caldir;
 
-	while ((ch = getopt(argc, argv, "-ad:f:l:w:x")) != -1)
+	while ((ch = getopt(argc, argv, "-am:d:f:l:w:x")) != -1)
 		switch (ch) {
 		case '-':		/* backward contemptible */
 		case 'a':
@@ -135,7 +145,13 @@
 				errno = EPERM;
 				err(1, NULL);
 			}
-			doall = 1;
+			doall = domailing = 1;
+			break;
+		case 'm':
+			ue = (struct uentry *)malloc(sizeof(struct uentry));
+			ue->name = optarg;
+			SLIST_INSERT_HEAD(&ulist, ue, ulink);
+			domailing = 1;
 			break;
 		case 'd':
 			datestr = optarg;
@@ -171,6 +187,16 @@
 				cal();
 			(void)seteuid(0);
 		}
+	} else if (domailing) {
+		SLIST_FOREACH(ue, &ulist, ulink) {
+			if ((pw = getpwnam(ue->name)) != NULL) {
+				(void)setegid(pw->pw_gid);
+				(void)seteuid(pw->pw_uid);
+				if (geteuid() == pw->pw_uid && !chdir(pw->pw_dir))
+					cal();
+				(void)seteuid(0);
+			}
+		}
 	} else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {
 		if(!chdir(caldir))
 			cal();
@@ -195,7 +221,7 @@
 		if (line[0] == '\0')
 			continue;
 		if (line[0] != '\t')
-			printing = isnow(line) ? 1 : 0;
+			printing = isnow(line);
 		if (printing)
 			(void)fprintf(fp, "%s\n", line);
 		free(line);
@@ -362,12 +388,12 @@
 				break;
 		}
 		if (*name == NULL) {
-			if (doall)
+			if (domailing)
 				return (NULL);
 			err(1, "Cannot open calendar file");
 		}
 	} else if (!freopen(fname, "rf", stdin)) {
-		if (doall)
+		if (domailing)
 			return (NULL);
 		err(1, "Cannot open `%s'", fname);
 	}
@@ -406,7 +432,7 @@
 	(void)close(pdes[1]);
 
 	/* not reading all calendar files, just set output to stdout */
-	if (!doall)
+	if (!domailing)
 		return (stdout);
 
 	/* set output to a temporary file, so if no output don't send mail */
@@ -426,7 +452,7 @@
 	int nread, pdes[2], status;
 	char buf[1024];
 
-	if (!doall)
+	if (!domailing)
 		return;
 
 	(void)rewind(fp);
--- calendar.1.orig	2004-12-29 22:04:28.000000000 +0300
+++ calendar.1	2005-07-18 01:45:38.000000000 +0400
@@ -38,6 +38,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl ax
+.Op Fl m Ar user
 .Op Fl d Ar MMDD[[YY]YY]
 .Op Fl f Ar file
 .Op Fl l Ar days
@@ -54,6 +55,12 @@
 .Dq calendar
 files of all users and mail the results to them.
 This requires super-user privileges.
+.It Fl m Ar user
+Process the
+.Dq calendar
+file of given user and mail the result to him (her).
+This option may be specified several times.
+Processing calendar files of other users requires super-user priveleges.
 .It Fl d Ar MMDD[[YY]YY]
 Display lines for the given date.
 By default, the current date is used.