NetBSD Problem Report #19121
Received: (qmail 16050 invoked by uid 605); 21 Nov 2002 14:06:42 -0000
Message-Id: <20021121150402.C63A1F4@evo.infnet.sa>
Date: Thu, 21 Nov 2002 15:04:02 +0000 (UTC)
From: joerg@gmx.net
Sender: gnats-bugs-owner@netbsd.org
Reply-To: joerg@gmx.net
To: gnats-bugs@gnats.netbsd.org
Subject: calendar patch (to support NIS)
X-Send-Pr-Version: 3.95
>Number: 19121
>Category: bin
>Synopsis: calendar patch (to support NIS)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: closed
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Nov 21 14:07:00 +0000 2002
>Closed-Date: Sat Aug 27 23:27:57 +0000 2016
>Last-Modified: Sat Aug 27 23:27:57 +0000 2016
>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:
Responsible-Changed-From-To: bin-bug-people->atatat
Responsible-Changed-By: fair
Responsible-Changed-When: Thu Jun 5 00:34:30 UTC 2003
Responsible-Changed-Why:
Andrew Brown said he'd try to deal with this.
Responsible-Changed-From-To: atatat->bin-bug-people
Responsible-Changed-By: wiz@NetBSD.org
Responsible-Changed-When: Sun, 21 Mar 2010 15:47:51 +0000
Responsible-Changed-Why:
Back to role account, atatat lost his commit bit.
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 27 Aug 2016 23:27:57 +0000
State-Changed-Why:
WONTFIX - duplicate account entries in an NIS environment are not a major
issue. (as in, if you have any, you have bigger problems than a few extra
calendar mails.)
also, this problem should be fixed in getpwent, maybe as an optional filter,
not in every caller; and a linked list using insertion sort is a pretty
awful way to keep track of what uids have been seen. NIS environments that
still exist often have thousands of users, so the method here would add a
lot of overhead and use a (comparatively) large amount of memory.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.