File: prune.c

package info (click to toggle)
gup 0.5.13
  • links: PTS
  • area: main
  • in suites: lenny, squeeze, wheezy
  • size: 188 kB
  • ctags: 168
  • sloc: ansic: 1,609; sh: 213; makefile: 57
file content (98 lines) | stat: -rw-r--r-- 2,326 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
 * This routine does an exhaustive check on the groups file.
 * It weeds out:
 *
 * all redundant additions.
 * all !groups that don't filter anything.
 * all groups that don't match any of the actives.
 *
 * Any such groups are deleted.
 *
 * CP is not considered an issue...
 */

#include "gup.h"

/* Remove all superfluous groups */
void prune(LIST *active_l, LIST *group_l)
{
    GROUP *gp;
    GROUP *ap;
    int groupcount;

    groupcount = 0;
    /* tag the active list */
    TRAVERSE(active_l, ap) {
	ap->u.tag = NULL;

	TRAVERSE(group_l, gp) {
	    if (wildmat(ap->name, gp->name)) {
		TAG *t = (TAG *) malloc(sizeof(TAG));
		if (!t) {
		    logit(L_BOTH, "WARNING: insufficient memory to prune!");
		    return;
		}
		/* add the group to the front of this ap's tag list */
		t->group = gp;
		t->next = ap->u.tag;
		ap->u.tag = t;
	    }
	}
	if (ap && ap->u.tag && ap->u.tag->group)
	    if (ap->u.tag->group->u.not == GUP_INCLUDE)
		groupcount++;
    }

    /* see if too many groups in the list */
    if (groupcount > maxgroups)
	gupout(1, "Too many groups (%d, only %d allowed)",
		groupcount, maxgroups);

    /* iterate the groups list to see if each group any effect on the active */
    TRAVERSE(group_l, gp) {
	int effect = FALSE;

	TRAVERSE(active_l, ap) {
	    TAG *tag = ap->u.tag;

	    /* does gp affect ap? */
	    if (tag && tag->group == gp && ((!tag->next && !gp->u.not) ||
		(tag->next && tag->next->group->u.not != gp->u.not))) {
		effect = TRUE;
		break;
	    }
	}

	if (!effect && gp->u.not != GUP_POISON) {
	    /* group doesn't do anything - clobber it */

	    /*
	     * remove it from any tags in which it appears - makes the
	     * tag-check faster.  We *could* have done an active tag list
	     * for each group to speed this, but it at the expense of the
	     * initial tagging process.  As implemented here, we assume
	     * pruning is a relatively rare occurrence.
	     */
	    TRAVERSE(active_l, ap) {
		TAG *t, *prev;

		for (prev = NULL, t = ap->u.tag; t; prev = t, t = t->next) {
		    if (t->group == gp) {
			if (!prev)
			    ap->u.tag = t->next;
			else
			    prev->next = t->next;
			free(t);

			break;
		    }
		}
	    }

	    remove_group(group_l, gp);

	    logit(L_BOTH, "PRUNED: %s %s subsumed",
		    gp->u.not ? "exclude" : "include", gp->name);
	}
    }
}