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