source: trunk/third/nmh/uip/conflict.c @ 12455

Revision 12455, 10.2 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12454, which included commits to RCS files with non-trunk default branches.
Line 
1
2/*
3 * conflict.c -- check for conflicts in mail system
4 *
5 * $Id: conflict.c,v 1.1.1.1 1999-02-07 18:14:13 danw Exp $
6 */
7
8#include <h/mh.h>
9#include <fcntl.h>
10#include <h/aliasbr.h>
11#include <zotnet/mts/mts.h>
12#include <grp.h>
13#include <pwd.h>
14
15/*
16 * maximum number of directories that can
17 * be specified using -search switch.
18 */
19#define NDIRS   100
20
21/*
22 * Add space for group names, 100 at a time
23 */
24#define NGRPS   100
25
26static struct swit switches[] = {
27#define MAILSW         0
28    { "mail name", 0 },
29#define SERCHSW        1
30    { "search directory", 0 },
31#define VERSIONSW      2
32    { "version", 0 },
33#define HELPSW         3
34    { "help", 4 },
35    { NULL, 0 }
36};
37
38static char *mail = NULL;
39static char *dirs[NDIRS];
40static FILE *out = NULL;
41
42extern struct aka  *akahead;
43extern struct home *homehead;
44
45/*
46 * prototypes
47 */
48void alias_files (int, char **);
49void pwd_names (void);
50void grp_names (void);
51void grp_members (void);
52void grp_ids (void);
53void maildrops (void);
54void mdrop(char *);
55int check (char *);
56void setup (void);
57
58
59int
60main (int argc, char **argv)
61{
62    int akp = 0, dp = 0;
63    char *cp, **argp, **arguments;
64    char buf[BUFSIZ], *akv[50];
65
66#ifdef LOCALE
67    setlocale(LC_ALL, "");
68#endif
69    invo_name = r1bindex (argv[0], '/');
70
71    /* foil search of user profile/context */
72    if (context_foil (NULL) == -1)
73        done (1);
74
75    mts_init (invo_name);
76    arguments = getarguments (invo_name, argc, argv, 0);
77    argp = arguments;
78
79    while ((cp = *argp++)) {
80        if (*cp == '-') {
81            switch (smatch (++cp, switches)) {
82                case AMBIGSW:
83                    ambigsw (cp, switches);
84                    done (1);
85                case UNKWNSW:
86                    adios (NULL, "-%s unknown", cp);
87
88                case HELPSW:
89                    snprintf (buf, sizeof(buf), "%s [switches] [aliasfiles ...]",
90                        invo_name);
91                    print_help (buf, switches, 0);
92                    done (1);
93                case VERSIONSW:
94                    print_version(invo_name);
95                    done (1);
96
97                case MAILSW:
98                    if (!(cp = *argp++) || *cp == '-')
99                        adios (NULL, "missing argument to %s", argp[-2]);
100                    if (mail)
101                        adios (NULL, "mail to one address only");
102                    else
103                        mail = cp;
104                    continue;
105
106                case SERCHSW:
107                    if (!(cp = *argp++) || *cp == '-')
108                        adios (NULL, "missing argument to %s", argp[-2]);
109                    if (dp >= NDIRS)
110                        adios (NULL, "more than %d directories", NDIRS);
111                    dirs[dp++] = cp;
112                    continue;
113            }
114        }
115        akv[akp++] = cp;
116    }
117
118    if (akp == 0)
119        akv[akp++] = AliasFile;
120    if (!homehead)
121        init_pw ();
122    if (!mail)
123        out = stdout;
124    dirs[dp] = NULL;
125
126    alias_files (akp, akv);
127    pwd_names ();
128    grp_names ();
129    grp_members ();
130    grp_ids ();
131#ifdef  UCI
132    ldr_names ();
133    ldr_ship ();
134#endif  /* UCI */
135    maildrops ();
136
137    done (0);
138}
139
140
141void
142alias_files (int akp, char **akv)
143{
144    register int i, err;
145
146    for (i = 0; i < akp; i++)
147        if ((err = alias (akv[i])) != AK_OK) {
148            setup ();
149            fprintf (out, "aliasing error in %s - %s\n", akv[i], akerror (err));
150        }
151        else
152            if (out && !mail)
153                fprintf (out, "alias file %s is ok\n", akv[i]);
154}
155
156
157void
158pwd_names (void)
159{
160    int hit = 0;
161    register struct home *hm, *lm;
162
163    for (hm = homehead; hm; hm = hm->h_next)
164        for (lm = hm->h_next; lm; lm = lm->h_next)
165            if (strcmp (hm->h_name, lm->h_name) == 0) {
166                setup ();
167                fprintf (out, "duplicate user %s(uid=%d)\n",
168                        lm->h_name, (int) lm->h_uid);
169                hit++;
170            }
171
172    if (!hit && out && !mail)
173        fprintf (out, "no duplicate users\n");
174}
175
176
177void
178grp_names (void)
179{
180    int numgroups, maxgroups;
181    int i, hit = 0;
182    char **grps;
183    struct group *gr;
184
185    /* allocate space NGRPS at a time */
186    numgroups = 0;
187    maxgroups = NGRPS;
188    if (!(grps = (char **) malloc((size_t) (maxgroups * sizeof(*grps)))))
189        adios (NULL, "unable to allocate group name storage");
190
191    setgrent ();
192    while ((gr = getgrent ())) {
193        for (i = 0; i < numgroups; i++)
194            if (!strcmp (grps[i], gr->gr_name)) {
195                setup ();
196                fprintf (out, "duplicate group %s(gid=%d)\n",
197                        gr->gr_name, (int) gr->gr_gid);
198                hit++;
199                break;
200            }
201        if (i >= numgroups) {
202            if (numgroups >= maxgroups) {
203                maxgroups += NGRPS;
204                if (!(grps = (char **) realloc(grps,
205                        (size_t) (maxgroups * sizeof(*grps)))))
206                    adios (NULL, "unable to reallocate group name storage");
207            }
208            grps[numgroups++] = getcpy (gr->gr_name);
209        }
210    }
211    endgrent ();
212
213    for (i = 0; i < numgroups; i++)
214        free (grps[i]);
215    free (grps);
216
217    if (!hit && out && !mail)
218        fprintf (out, "no duplicate groups\n");
219}
220
221
222void
223grp_members (void)
224{
225    register int hit = 0;
226    register char **cp, **dp;
227    register struct group *gr;
228    register struct home  *hm;
229
230    setgrent ();
231    while ((gr = getgrent ())) {
232        for (cp = gr->gr_mem; *cp; cp++) {
233            for (hm = homehead; hm; hm = hm->h_next)
234                if (!strcmp (*cp, hm->h_name))
235                    break;
236            if (hm == NULL) {
237                setup ();
238                fprintf (out, "group %s(gid=%d) has unknown member %s\n",
239                        gr->gr_name, (int) gr->gr_gid, *cp);
240                hit++;
241            } else {
242                hm->h_ngrps++;
243            }
244
245            for (dp = cp + 1; *dp; dp++)
246                if (strcmp (*cp, *dp) == 0) {
247                    setup ();
248                    fprintf (out, "group %s(gid=%d) has duplicate member %s\n",
249                            gr->gr_name, (int) gr->gr_gid, *cp);
250                    hit++;
251                }
252        }
253    }
254    endgrent ();
255
256    for (hm = homehead; hm; hm = hm->h_next)
257        if (hm->h_ngrps > NGROUPS_MAX) {
258            setup ();
259            fprintf (out, "user %s is a member of %d groups (max %d)\n",
260                    hm->h_name, hm->h_ngrps, NGROUPS_MAX);
261            hit++;
262        }
263
264    if (!hit && out && !mail)
265        fprintf (out, "all group members accounted for\n");
266}
267
268
269void
270grp_ids (void)
271{               /* -DRAND not implemented at most places */
272    register int hit = 0;
273    register struct home *hm;
274
275    for (hm = homehead; hm; hm = hm->h_next)
276        if (getgrgid (hm->h_gid) == NULL) {
277            setup ();
278            fprintf (out, "user %s(uid=%d) has unknown group-id %d\n",
279                    hm->h_name, (int) hm->h_uid, (int) hm->h_gid);
280            hit++;
281        }
282
283    if (!hit && out && !mail)
284        fprintf (out, "all group-id users accounted for\n");
285}
286
287
288void
289maildrops (void)
290{
291    register int i;
292
293    if (mmdfldir && *mmdfldir)
294        mdrop (mmdfldir);
295    if (uucpldir && *uucpldir)
296        mdrop (uucpldir);
297    for (i = 0; dirs[i]; i++)
298        mdrop (dirs[i]);
299}
300
301
302void
303mdrop(char *drop)
304{
305    register int hit = 0;
306    register struct dirent *dp;
307    register DIR *dd = opendir (drop);
308
309    if (!dd) {
310        setup ();
311        fprintf (out, "unable to open maildrop area %s\n", drop);
312        return;
313    }
314
315    while ((dp = readdir (dd)))
316        if (dp->d_name[0] != '.' && !check (dp->d_name)) {
317            setup ();
318            fprintf (out,
319                    "there is a maildrop for the unknown user %s in %s\n",
320                    dp->d_name, drop);
321            hit++;
322        }
323
324    closedir (dd);
325    if (!hit && out && !mail)
326        fprintf (out, "all maildrops accounted for in %s\n", drop);
327}
328
329
330int
331check (char *s)
332{
333    register struct home *hm;
334
335    for (hm = homehead; hm; hm = hm->h_next)
336        if (!strcmp (s, hm->h_name))
337            return 1;
338    return 0;
339}
340
341void
342setup (void)
343{
344    int fd, pd[2];
345
346    if (out)
347        return;
348
349    if (mail) {
350        if (pipe (pd) == NOTOK)
351            adios ("pipe", "unable to");
352
353        switch (fork ()) {
354            case NOTOK:
355                adios ("fork", "unable to");
356
357            case OK:
358                close (pd[1]);
359                if (pd[0] != 0) {
360                    dup2 (pd[0], 0);
361                    close (pd[0]);
362                }
363                if ((fd = open ("/dev/null", O_WRONLY)) != NOTOK)
364                    if (fd != 1) {
365                        dup2 (fd, 1);
366                        close (fd);
367                    }
368                execlp (mailproc, r1bindex (mailproc, '/'),
369                        mail, "-subject", invo_name, NULL);
370                adios (mailproc, "unable to exec ");
371
372            default:
373                close (pd[0]);
374                out = fdopen (pd[1], "w");
375                fprintf (out, "%s: the following is suspicious\n\n",
376                        invo_name);
377        }
378    }
379}
380
381#ifdef UCI
382/*
383 * UCI specific stuff for conflict
384 */
385
386/* taken from <grpldr.h> */
387
388#define GLDRS   "/admin/etc/GroupLeaders"
389
390struct grpldr {
391    char *gl_name;
392    char **gl_ldr;
393};
394
395int setglent (), endglent ();
396struct grpldr *getglent (), *getglnam ();
397
398
399/* taken from the getglent() routines */
400
401#define MAXGLS  100
402
403static FILE *glp = NULL;
404static char line[BUFSIZ+1];
405static struct grpldr grpldr;
406static char *gl_ldr[MAXGLS + 1];
407
408
409setglent() {
410    if (glp == NULL)
411        glp = fopen (GLDRS, "r");
412    else
413        rewind (glp);
414
415    return (glp != NULL);
416}
417
418
419endglent() {
420    if (glp != NULL) {
421        fclose (glp);
422        glp = NULL;
423    }
424
425    return 1;
426}
427
428struct grpldr  *getglent () {
429    register char  *cp,
430                  **q;
431
432    if (glp == NULL && !setglent ())
433        return NULL;
434    if ((cp = fgets (line, BUFSIZ, glp)) == NULL)
435        return NULL;
436
437    grpldr.gl_name = cp;
438    grpldr.gl_ldr = q = gl_ldr;
439
440    while (*cp) {
441        while (*cp && !isspace (*cp))
442            cp++;
443        while (*cp && isspace (*cp))
444            *cp++ = '\0';
445        if (*cp == '\0')
446            break;
447        if (q < gl_ldr + MAXGLS)
448            *q++ = cp;
449        else
450            break;
451    }
452    *q = NULL;
453
454    return (&grpldr);
455}
456
457struct grpldr  *getglnam (name)
458char   *name;
459{
460    register struct grpldr  *gl = NULL;
461
462    setglent ();
463    while (gl = getglent ())
464        if (strcmp (name, gl->gl_name) == 0)
465            break;
466    endglent ();
467
468    return gl;
469}
470
471ldr_names () {
472    register int     gp,
473                     hit = 0;
474    char   *gldrs[NGRPS];
475    register struct grpldr  *gl;
476
477    gldrs[0] = NULL;
478    setglent ();
479    while (gl = getglent ()) {
480        if (getgrnam (gl->gl_name) == NULL) {
481            setup ();
482            fprintf (out, "unknown group %s in group leaders file\n",
483                    gl->gl_name);
484            hit++;
485        }
486        for (gp = 0; gldrs[gp]; gp++)
487            if (strcmp (gldrs[gp], gl->gl_name) == 0) {
488                setup ();
489                fprintf (out, "duplicate group %s in group leaders file\n",
490                        gl->gl_name);
491                hit++;
492                break;
493            }
494        if (gldrs[gp] == NULL)
495            if (gp < NGRPS) {
496                gldrs[gp++] = getcpy (gl->gl_name);
497                gldrs[gp] = NULL;
498            }
499            else {
500                setup ();
501                fprintf (out, "more than %d groups in group leaders file%s\n",
502                        " (time to recompile)", NGRPS - 1);
503                hit++;
504            }
505    }
506    endglent ();
507
508    for (gp = 0; gldrs[gp]; gp++)
509        free (gldrs[gp]);
510
511    if (!hit && out && !mail)
512        fprintf (out, "all groups in group leaders file accounted for\n");
513}
514
515
516ldr_ship () {
517    register int     hit = 0;
518    register char  **cp,
519                   **dp;
520    register struct grpldr  *gl;
521
522    setglent ();
523    while (gl = getglent ())
524        for (cp = gl->gl_ldr; *cp; cp++) {
525            if (!check (*cp)) {
526                setup ();
527                fprintf (out, "group %s has unknown leader %s\n",
528                        gl->gl_name, *cp);
529                hit++;
530            }
531
532            for (dp = cp + 1; *dp; dp++)
533                if (strcmp (*cp, *dp) == 0) {
534                    setup ();
535                    fprintf (out, "group %s had duplicate leader %s\n",
536                            gl->gl_name, *cp);
537                    hit++;
538                }
539        }
540    endglent ();
541
542    if (!hit && out && !mail)
543        fprintf (out, "all group leaders accounted for\n");
544}
545#endif  /* UCI */
Note: See TracBrowser for help on using the repository browser.