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