1 #ifndef lint
2 static	char	sccsid[] = "@(#)ngmatch.c	1.3	(Berkeley) 2/6/88";
3 #endif
4 
5 #include "common.h"
6 
7 /*
8  * nntpngmatch -- match a list of newsgroup specifiers with a list of
9  * given newsgroups.  A pointer to the routine which determines a match is
10  * also given.  This allows us to do regular expression handling for RFC
11  * 977's NEWNEWS, and more efficient "strncmps" for the access file, which
12  * must be checked often.
13  *
14  * This is NOT the same routine as ngmatch in the news software.  Pity.
15  *
16  *	Parameters:	"nglist" is the list of group specifiers (limited
17  *			regexp) to match against.
18  *			"ngcount" is the number of groups in nglist.
19  *			"matchlist" is the list of newsgroups to match against.
20  *			"matchcount" is number of groups in matchlist.
21  *
22  *	Returns:	1 if the named newsgroup is in the list.
23  *			0 otherwise.
24  */
25 
26 int
27 ngmatch(func, dflt, ngspec, ngspeccount, matchlist, matchcount)
28 	int		(*func)();
29 	int		dflt;
30 	char		**ngspec;
31 	int		ngspeccount;
32 	char		**matchlist;
33 	int		matchcount;
34 {
35 	register int	i, j;
36 	register int	match;
37 	register char	*cp;
38 
39 	if (ngspeccount == 0)
40 		return (1);
41 
42 	match = dflt;
43 
44 	for (i = 0; i < matchcount; ++i) {
45 		if ((cp = index(matchlist[i], '/')))
46 			*cp = '\0';
47 		for (j = 0; j < ngspeccount; ++j) {
48 			if (ngspec[j][0] == '!') {	/* Handle negation */
49 				if ((*func)(ngspec[j]+1, matchlist[i])) {
50 					match = 0;
51 				}
52 			} else {
53 				if ((*func)(ngspec[j], matchlist[i])) {
54 					match = 1;
55 				}
56 			}
57 		}
58 	}
59 
60 	return (match);
61 }
62 
63 
64 /*
65  * restreql -- A small regular expression string equivalnce routine.
66  * Thanks and a tip of the hat to Nick Lai, <lai@shadow.berkeley.edu>
67  * for this time saving device.
68  *
69  *	Parameters:	"w" is an asterisk-broadened regexp,
70  *			"s" is a non-regexp string.
71  *	Returns:	1 if match, 0 otherwise.
72  *
73  *	Side effects:	None.
74  */
75 
76 int
restreql(w,s)77 restreql(w, s)
78 	register char *w;
79 	register char *s;
80 {
81 
82 	while (*s && *w) {
83 		switch (*w) {
84 			case '*':
85 				for (w++; *s; s++)
86 					if (restreql(w, s))
87 						return 1;
88 				break;
89 			default:
90 				if (*w != *s)
91 					return 0;
92 				w++, s++;
93 				break;
94 		}
95 	}
96 	if (*s)
97 		return 0;
98 	while (*w)
99 		if (*w++ != '*')
100 			return 0;
101 
102 	return 1;
103 }
104 
105 
106 /*
107  * s1strneql -- see if s1 is equivalent to s2 up to the length of s1.
108  * Return non-zero if so, 0 otherwise.
109  */
110 
111 int
s1strneql(s1,s2)112 s1strneql(s1, s2)
113 	register char	*s1;
114 	register char	*s2;
115 {
116 	register int	slen;
117 
118   	if (!strcmp(s1,"all"))
119 		return(1);
120 	if ((slen = strlen(s1)) > 4) {
121 		if (!strcmp(s1+slen-4,".all"))
122 			return(!strncmp(s1, s2, slen-3));
123 	}
124 	return (!strncmp(s1, s2, slen));
125 }
126 
127 
128 
129