1 #ifndef lint
2 static char	sccsid[] = "@(#)active.c	1.12	(Berkeley) 1/11/88";
3 #endif
4 
5 #include "common.h"
6 
7 /*
8  * Routines to deal with the active file
9  */
10 
11 /*
12  * read_groups -- read the active file into memory, sort it,
13  *	and return the number of newsgroups read in.
14  *	If FASTFORK is true, this can be called by interrupt,
15  *	and may have to free up the old storage.  We decide
16  *	this by the fact that "num_groups" will be non-zero if
17  *	we're here on an interrupt.
18  *
19  *	Parameters:	None.
20  *
21  *	Returns:	Number of newsgroups read into
22  *			memory.
23  *			Zero on error.
24  *
25  *	Side effects:	Reads newsgroups into "group_array"
26  *			and sorts them.
27  */
28 
29 int
read_groups()30 read_groups()
31 {
32 	register int	i;
33 	register int	act_fd;
34 	register char	*cp, *end;
35 	struct stat	statbuf;
36 
37 	/*
38 	 * If we're here on an interrupt, free up all the
39 	 * previous groups.
40 	 */
41 
42 	if (num_groups != 0) {
43 		(void) free(actbuf);
44 		(void) free(group_array);
45 	}
46 
47 	act_fd = open(activefile, O_RDONLY);
48 	if (act_fd < 0) {
49 #ifdef SYSLOG
50 		syslog(LOG_ERR, "read_groups: open %s: %m", activefile);
51 #endif
52 		return (0);
53 	}
54 
55 	if (fstat(act_fd, &statbuf) < 0) {
56 #ifdef SYSLOG
57 		syslog(LOG_ERR, "read_groups: fstat: %m");
58 #endif
59 		(void) close(act_fd);
60 		return (0);
61 	}
62 
63 	actbuf = malloc(statbuf.st_size);
64 	if (actbuf == NULL) {
65 #ifdef SYSLOG
66 		syslog(LOG_ERR, "read_groups: malloc %lu bytes: %m",
67 			statbuf.st_size);
68 #endif
69 		(void) close(act_fd);
70 		return (0);
71 	}
72 
73 	if (read(act_fd, actbuf, (iolen_t)statbuf.st_size) != statbuf.st_size) {
74 #ifdef SYSLOG
75 		syslog(LOG_ERR, "read_groups: read %lu bytes: %m",
76 			statbuf.st_size);
77 #endif
78 		(void) close(act_fd);
79 		return (0);
80 	}
81 
82 	(void) close(act_fd);
83 
84 	for (i = 0, cp = actbuf, end = actbuf + statbuf.st_size; cp < end; cp++)
85 		if (*cp == '\n')
86 			i++;
87 
88 	group_array = (char **) malloc(i * (sizeof (char *)));
89 	if (group_array == NULL) {
90 #ifdef SYSLOG
91 		syslog(LOG_ERR, "read_groups: malloc %lu bytes: %m",
92 			i * sizeof (char **));
93 #endif
94 		(void) close(act_fd);
95 		return (0);
96 	}
97 
98 	cp = actbuf;
99 	i = 0;
100 	while (cp < end) {
101 		group_array[i++] = cp;
102 		cp = index(cp, '\n');
103 		if (cp == NULL)
104 			break;
105 		*cp = '\0';
106 		cp++;
107 	}
108 
109 	qsort((char *) group_array, i, sizeof (char *), act_cmp);
110 
111 	return (i);
112 }
113 
114 int
act_cmp(vptr1,vptr2)115 act_cmp(vptr1, vptr2)
116 	const void	*vptr1, *vptr2;
117 {
118 	char	**ptr1 = (char **)vptr1;
119         char	**ptr2 = (char **)vptr2;
120 	return(strcmp(*ptr1, *ptr2));
121 }
122 
123 
124 /*
125  * find_group -- find a given newsgroup and return
126  *	the low and high message numbers in the group
127  *	(space provided by user).
128  *
129  *	Parameters:	"group" is the name of the group
130  *			we're searching for.
131  *			"low_msg" and "high_msg" are
132  *			pointers to where we're supposed
133  *			to put the low and high message numbers.
134  *
135  *	Returns:	the index # in the group_array[] if all goes well;
136  *			-1 if we can't find the group.
137  *
138  *	Side effects:	None.
139  */
140 
141 int
find_group(group,low_msg,high_msg)142 find_group(group, low_msg, high_msg)
143 	const char	*group;
144 	int		*low_msg, *high_msg;
145 {
146 	char		kludgebuf[MAXBUFLEN];
147 	int		cond;
148 	register int	low, high, mid;
149 	int		length;
150 
151 	low = 0;
152 	(void) strcpy(kludgebuf, group);
153 	(void) strcat(kludgebuf, " ");
154 	length = strlen(kludgebuf);
155 
156 	read_again();	/* read active file if it has changed */
157 
158 	high = num_groups-1;
159 	while (low <= high) {
160 		mid = (low + high) / 2;
161 		if ((cond = strncmp(kludgebuf, group_array[mid], length)) < 0)
162 			high = mid - 1;
163 		else if (cond > 0)
164 			low = mid + 1;
165 		else {
166 			(void) sscanf(group_array[mid], "%s %d %d",
167 				kludgebuf, high_msg, low_msg);
168 			return(mid);
169 		}
170 	}
171 	return(-1);
172 }
173