Subject: bin/19121: calendar patch (to support NIS)
To: None <gnats-bugs@gnats.netbsd.org>
From: None <joerg@gmx.net>
List: netbsd-bugs
Date: 11/21/2002 15:04:02
>Number: 19121
>Category: bin
>Synopsis: calendar patch (to support NIS)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Nov 21 06:07:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator: Joerg Klemenz
>Release: NetBSD 1.6
>Organization:
All Virtual Devils
>Environment:
System: NetBSD evo.infnet.sa 1.6 NetBSD 1.6 (VPC5) #0: Sun Nov 3 21:01:51 UTC 2002 root@faith.infnet.sa:/usr/src/sys/arch/i386/compile/VPC5 i386
Architecture: i386
Machine: i386
>Description:
Here is a patch for the calendar(1) program.
It adds a new function (inuidlist) that builds a dynamicly allocated
linked list to check if the specified UID has already been processed.
Due to the reverse-sorted nature of the list (3-2-1) there is almost
no overhead for a typical no-NIS system where the password file is
semi-sorted in an 1-2-3 fashion. The added functionality for NIS
systems makes it well worth the little overhead IMHO.
The reason is that without that function "calendar -a" will send out
multiple copies of mail to individual users in a NIS environment (see
man getpwent).
I have used the patch for some time and it looks OK.
The patch also contains some cosmetic fixes that you can ignore.
>How-To-Repeat:
>Fix:
--- calendar.c_org Tue Nov 5 09:32:36 2002
+++ calendar.c Wed Nov 20 10:18:47 2002
@@ -1,4 +1,4 @@
-/* $NetBSD: calendar.c,v 1.26 2001/12/04 15:55:32 christos Exp $ */
+/* $Id: calendar.c,v 1.6 2002/11/20 10:18:38 joerg Exp $ */
/*
* Copyright (c) 1989, 1993, 1994
@@ -43,7 +43,7 @@
#if 0
static char sccsid[] = "@(#)calendar.c 8.4 (Berkeley) 1/7/95";
#endif
-__RCSID("$NetBSD: calendar.c,v 1.26 2001/12/04 15:55:32 christos Exp $");
+__RCSID("$Id: calendar.c,v 1.6 2002/11/20 10:18:38 joerg Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -75,7 +75,7 @@
#endif
static unsigned short lookahead = 1, weekend = 2;
-static char *fname = "calendar", *datestr = NULL;
+static char *fname = ".calendar", *datestr = NULL; /* cal -> .cal (jk) */
static struct passwd *pw;
static int doall;
static char path[MAXPATHLEN + 1];
@@ -108,6 +108,12 @@
"jul", "aug", "sep", "oct", "nov", "dec", NULL,
};
+struct uidlist_s {
+ uid_t uid;
+ struct uidlist_s *next;
+};
+
+
int main(int, char **);
static void atodays(int, char *, unsigned short *);
@@ -118,10 +124,12 @@
static void getmmdd(struct tm *, char *);
static int getmonth(char *);
static int isnow(char *);
+static int inuidlist(struct uidlist_s *, uid_t);
static FILE *opencal(void);
static void settime(void);
static void usage(void) __attribute__((__noreturn__));
+
int
main(argc, argv)
int argc;
@@ -129,6 +137,11 @@
{
int ch;
const char *caldir;
+ struct uidlist_s *uidlist_ptr;
+
+ /* create the tail of the linked list */
+ if (uidlist_ptr=malloc(sizeof *uidlist_ptr))
+ uidlist_ptr->next=NULL;
while ((ch = getopt(argc, argv, "-ad:f:l:w:")) != -1)
switch (ch) {
@@ -164,13 +177,16 @@
settime();
if (doall) {
- while ((pw = getpwent()) != NULL) {
+ while ((pw = getpwent()) != NULL)
+ {
+ if (!inuidlist(uidlist_ptr, pw->pw_uid)) {
(void)setegid(pw->pw_gid);
(void)seteuid(pw->pw_uid);
if (!chdir(pw->pw_dir))
cal();
(void)seteuid(0);
}
+ }
} else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {
if(!chdir(caldir))
cal();
@@ -180,6 +196,24 @@
exit(0);
}
+/* make list of uids to avoid doubles (see man getpwent) */
+static int
+inuidlist(uidlist_ptr, uid)
+ struct uidlist_s *uidlist_ptr;
+ uid_t uid;
+{
+ struct uidlist_s *p,*tmp;
+
+ for (p=uidlist_ptr; p->next && (p->uid > uid); p=p->next);
+ if ((p->uid==uid) && p->next) return (1);
+ if (tmp=malloc(sizeof *tmp)) {
+ *tmp=*p;
+ p->next=tmp;
+ p->uid=uid;
+ }
+ return (0);
+}
+
static void
cal(void)
{
@@ -199,10 +233,13 @@
free(line);
}
+
+ if (doall)
closecal(fp);
+ else
+ (void)fclose(fp);
}
-
static void
settime(void)
{
@@ -383,9 +420,6 @@
int nread, pdes[2], status;
char buf[1024];
- if (!doall)
- return;
-
(void)rewind(fp);
if (fstat(fileno(fp), &sbuf) || !sbuf.st_size)
goto done;
@@ -419,7 +453,7 @@
(void)close(pdes[1]);
done: (void)fclose(fp);
- (void)unlink(path);
+ (void)unlink(path); /* it should close descriptor first... */
while (wait(&status) >= 0)
continue;
}
>Release-Note:
>Audit-Trail:
>Unformatted: