# /* getpm.c * * Get all the personal computer mail usernames and mail file names from * the users file. Store them in a calloc'ed array. This is an efficiency * hack to avoid having to read through the entire users file each time * a message is delivered. To increase the speed, the array is * sorted by uname so binary searching will work. */ #include #include #include "rqfile.h" #include "extern.h" #define NOPMENT 256 /* max. user entries */ struct pment { /* saved contents of users file */ char *pm_name; /* user name */ char *pm_file; /* mail file */ } entries[NOPMENT]; char pmfile[] = "/pmail/users"; /* users file name */ int pmmod[2]; /* users file modified time */ int npment; /* number of user entries */ int pwcmp (); /* username compare routine */ getpmf () { register struct pment *pmp; /* ptr. to current user entry */ register char *cp; /* ptr. to current alloc. */ FILE *ufile; /* users file */ char line[NAMSIZ]; /* users file line */ char name[NAMSIZ]; /* current username */ char file[NAMSIZ]; /* his mail file */ int nsiz, fsiz; /* name & file lengths */ struct inode buf; /* buffer for stat call */ if ((stat (pmfile, &buf)) < 0) faterr ("can't find pmail users file\n"); pmmod[0] = buf.modtime[0]; pmmod[1] = buf.modtime[1]; if ( (ufile = fopen(pmfile,"r")) == NULL) faterr ("can't open pmail users file\n"); pmp = entries; npment = 0; while (fgets(line, sizeof(line), ufile) != NULL) { sscanf(line, "%32[^:]:%32[^:]:", name, file); nsiz = strlen (name); fsiz = strlen (file); if ((cp = alloc (nsiz + fsiz + 2)) == -1) faterr ("can't alloc for pmail user entry\n"); pmp->pm_name = cp; strcpy (cp, name); cp += nsiz + 1; pmp->pm_file = cp; strcpy (cp, file); if (++pmp >= &entries[NOPMENT]) faterr ("too many pmail users\n"); npment++; } fclose (ufile); qsort (entries, npment, sizeof (struct pment), &pwcmp); } /* Check if pmail users file was modified; if so, update saved entries. * Called each time the mail daemon is awakened. */ chkpmd () { struct inode buf; /* buf for stat call */ register struct pment *pmp; /* ptr. to current user entry */ register int i; /* index in entries array */ if ((stat (pmfile, &buf)) < 0) faterr ("can't find pmail users file\n"); if (pmmod[0] == buf.modtime[0] && pmmod[1] == buf.modtime[1]) return; for (pmp = entries, i = 0; i < npment; i++, pmp++) { free (pmp->pm_name); pmp->pm_name = NULL; pmp->pm_file = NULL; } getpmf (); } /* Find the users file entry for the specified user, if one exists. * Return that user's mail file name, or NULL if no such user exists. * Uses a binary search for speed. */ getpment (uname, file) char *uname; /* user name to be found */ char *file; /* user's mail file name */ { register int pmp; /* user entry index */ struct pment pe; /* temp entry for compares */ pe.pm_name = uname; pe.pm_file = file; if ((pmp = binsrch ((char *)&pe, (char *)entries, npment, sizeof (struct pment), &pwcmp)) == -1) return (NULL); strcpy (file, entries[pmp].pm_file); return (file); }