home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *sccsid = "@(#)active.c 1.12 (Berkeley) 1/11/88";
- #endif
-
- #include "common.h"
-
- /*
- * Routines to deal with the active file
- */
-
- int act_cmp();
-
- /*
- * read_groups -- read the active file into memory, sort it,
- * and return the number of newsgroups read in.
- * If FASTFORK is true, this can be called by interrupt,
- * and may have to free up the old storage. We decide
- * this by the fact that "num_groups" will be non-zero if
- * we're here on an interrupt.
- *
- * Parameters: None.
- *
- * Returns: Number of newsgroups read into
- * memory.
- * Zero on error.
- *
- * Side effects: Reads newsgroups into "group_array"
- * and sorts them.
- */
-
- read_groups()
- {
- register int i;
- register int act_fd;
- register char *cp, *end;
- char *malloc();
- struct stat statbuf;
-
- /*
- * If we're here on an interrupt, free up all the
- * previous groups.
- */
-
- if (num_groups != 0) {
- (void) free(actbuf);
- (void) free(group_array);
- }
-
- act_fd = open(activefile, O_RDONLY);
- if (act_fd < 0) {
- #ifdef SYSLOG
- syslog(LOG_ERR, "read_groups: open %s: %m", activefile);
- #endif
- return (0);
- }
-
- if (fstat(act_fd, &statbuf) < 0) {
- #ifdef SYSLOG
- syslog(LOG_ERR, "read_groups: fstat: %m");
- #endif
- (void) close(act_fd);
- return (0);
- }
-
- actbuf = malloc(statbuf.st_size);
- if (actbuf == NULL) {
- #ifdef SYSLOG
- syslog(LOG_ERR, "read_groups: malloc %d bytes: %m",
- statbuf.st_size);
- #endif
- (void) close(act_fd);
- return (0);
- }
-
- if (read(act_fd, actbuf, (iolen_t)statbuf.st_size) != statbuf.st_size) {
- #ifdef SYSLOG
- syslog(LOG_ERR, "read_groups: read %d bytes: %m",
- statbuf.st_size);
- #endif
- (void) close(act_fd);
- return (0);
- }
-
- (void) close(act_fd);
-
- for (i = 0, cp = actbuf, end = actbuf + statbuf.st_size; cp < end; cp++)
- if (*cp == '\n')
- i++;
-
- group_array = (char **) malloc(i * (sizeof (char *)));
- if (group_array == NULL) {
- #ifdef SYSLOG
- syslog(LOG_ERR, "read_groups: malloc %d bytes: %m",
- i * sizeof (char **));
- #endif
- (void) close(act_fd);
- return (0);
- }
-
- cp = actbuf;
- i = 0;
- while (cp < end) {
- group_array[i++] = cp;
- cp = index(cp, '\n');
- if (cp == NULL)
- break;
- *cp = '\0';
- cp++;
- }
-
- qsort((char *) group_array, i, sizeof (char *), act_cmp);
-
- return (i);
- }
-
-
- act_cmp(ptr1, ptr2)
- char **ptr1, **ptr2;
- {
- return(strcmp(*ptr1, *ptr2));
- }
-
-
- /*
- * find_group -- find a given newsgroup and return
- * the low and high message numbers in the group
- * (space provided by user).
- *
- * Parameters: "group" is the name of the group
- * we're searching for.
- * "num_groups" is the total number
- * of groups in the group array.
- * "low_msg" and "high_msg" are
- * pointers to where we're supposed
- * to put the low and high message numbers.
- *
- * Returns: 0 if all goes well,
- * -1 if we can't find the group.
- *
- * Side effects: None.
- */
-
- find_group(group, num_groups, low_msg, high_msg)
- char *group;
- int num_groups;
- int *low_msg, *high_msg;
- {
- char kludgebuf[MAXBUFLEN];
- int cond;
- register int low, high, mid;
- int length;
-
- low = 0;
- high = num_groups-1;
- (void) strcpy(kludgebuf, group);
- (void) strcat(kludgebuf, " ");
- length = strlen(kludgebuf);
-
- while (low <= high) {
- mid = (low + high) / 2;
- if ((cond = strncmp(kludgebuf, group_array[mid], length)) < 0)
- high = mid - 1;
- else if (cond > 0)
- low = mid + 1;
- else {
- (void) sscanf(group_array[mid], "%s %d %d",
- kludgebuf, high_msg, low_msg);
- return(0);
- }
- }
- return(-1);
- }
-