, tech-userlevel <tech-userlevel@netbsd.org>
From: Joerg Klemenz <joerg@gmx.net>
List: tech-userlevel
Date: 11/06/2002 21:17:33
David Laight wrote:
> I'd use a static array of pointers to malloc()ed buffers and set
> bits. Say 16k pointers each to 32k data, 2^14 * 2^15 * 2^3 = 2^32. Ok
> provided the UIDs are in dense blocks... (or you need 512Mbytes).
> Alternatively some kind of sorted data. Actually this code doesn't
> scale very well at all if there are many thousand users!
Uhh... that sounds complicated. How about that (it's kinda lame, but
should work for all cases)
--- calendar.c_org Tue Nov 5 09:32:36 2002
+++ calendar.c Wed Nov 6 21:06:13 2002
@@ -108,8 +108,16 @@
"jul", "aug", "sep", "oct", "nov", "dec", NULL,
};
+struct uidlist_s
+{
+ struct uidlist_s *next;
+ uid_t uid;
+};
+
+
int main(int, char **);
+static int checkForDoubleUID(struct uidlist_s *, uid_t);
static void atodays(int, char *, unsigned short *);
static void cal(void);
static void closecal(FILE *);
@@ -121,6 +129,8 @@
static FILE *opencal(void);
static void settime(void);
static void usage(void) __attribute__((__noreturn__));
+static void malloc_panic(void) __attribute__((__noreturn__));
+
int
main(argc, argv)
@@ -129,6 +139,12 @@
{
int ch;
const char *caldir;
+ struct uidlist_s *uidlist_ptr;
+
+ /* create the tail of the linked list */
+ uidlist_ptr=(struct uidlist_s*)malloc(sizeof(struct uidlist_s));
+ if (uidlist_ptr==NULL) malloc_panic;
+ uidlist_ptr->next=NULL;
while ((ch = getopt(argc, argv, "-ad:f:l:w:")) != -1)
switch (ch) {
@@ -165,12 +181,16 @@
settime();
if (doall) {
while ((pw = getpwent()) != NULL) {
+ /* avoid double mail when using NIS etc.
+ (see man getpwent) */
+ if (!checkForDoubleUID(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 +200,32 @@
exit(0);
}
+static int
+checkForDoubleUID(uidlist_ptr,uid)
+ /* return values
+ * 1 uid already in list
+ * 0 uid not in list (added)
+ */
+ struct uidlist_s *uidlist_ptr;
+ uid_t uid;
+{
+ struct uidlist_s *working_uidlist_ptr;
+
+ while (working_uidlist_ptr->next != NULL)
+ {
+ if (working_uidlist_ptr->uid == uid) return 1;
+ working_uidlist_ptr=working_uidlist_ptr->next;
+ }
+
+ /* working pointer points on tail now */
+ working_uidlist_ptr->next=(struct uidlist_s*)malloc(sizeof(struct uidlist_s));
+ if (working_uidlist_ptr->next==NULL) malloc_panic;
+ working_uidlist_ptr->uid=uid;
+ working_uidlist_ptr->next->next=NULL;
+
+ return 0;
+}
+
static void
cal(void)
{
@@ -518,4 +564,11 @@
(void)fprintf(stderr, "Usage: %s [-a] [-d MMDD[[YY]YY]"
" [-f fname] [-l days] [-w days]\n", getprogname());
exit(1);
+}
+
+static void
+malloc_panic(void)
+{
+ (void)fprintf(stderr, "%s: malloc panic\n", getprogname());
+ exit(2);
}
joerg <joerg@gmx.net>