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: int act_cmp(); 12: 13: /* 14: * read_groups -- read the active file into memory, sort it, 15: * and return the number of newsgroups read in. 16: * If FASTFORK is true, this can be called by interrupt, 17: * and may have to free up the old storage. We decide 18: * this by the fact that "num_groups" will be non-zero if 19: * we're here on an interrupt. 20: * 21: * Parameters: None. 22: * 23: * Returns: Number of newsgroups read into 24: * memory. 25: * Zero on error. 26: * 27: * Side effects: Reads newsgroups into "group_array" 28: * and sorts them. 29: */ 30: 31: read_groups() 32: { 33: register int i; 34: register int act_fd; 35: register char *actbuf, *cp, *end; 36: char *malloc(); 37: struct stat statbuf; 38: 39: /* 40: * If we're here on an interrupt, free up all the 41: * previous groups. 42: */ 43: 44: if (num_groups != 0) { 45: (void) free(group_array[0]); /* Assume [0] -> actbuf */ 46: (void) free(group_array); 47: } 48: 49: act_fd = open(activefile, O_RDONLY); 50: if (act_fd < 0) { 51: #ifdef SYSLOG 52: syslog(LOG_ERR, "read_groups: open %s: %m", activefile); 53: #endif 54: return (0); 55: } 56: 57: if (fstat(act_fd, &statbuf) < 0) { 58: #ifdef SYSLOG 59: syslog(LOG_ERR, "read_groups: fstat: %m"); 60: #endif 61: (void) close(act_fd); 62: return (0); 63: } 64: 65: actbuf = malloc(statbuf.st_size); 66: if (actbuf == NULL) { 67: #ifdef SYSLOG 68: syslog(LOG_ERR, "read_groups: malloc %d bytes: %m", 69: statbuf.st_size); 70: #endif 71: (void) close(act_fd); 72: return (0); 73: } 74: 75: if (read(act_fd, actbuf, (int)statbuf.st_size) != statbuf.st_size) { 76: #ifdef SYSLOG 77: syslog(LOG_ERR, "read_groups: read %d bytes: %m", 78: statbuf.st_size); 79: #endif 80: (void) close(act_fd); 81: return (0); 82: } 83: 84: (void) close(act_fd); 85: 86: for (i = 0, cp = actbuf, end = actbuf + statbuf.st_size; cp < end; cp++) 87: if (*cp == '\n') 88: i++; 89: 90: group_array = (char **) malloc(i * (sizeof (char *))); 91: if (group_array == NULL) { 92: #ifdef SYSLOG 93: syslog(LOG_ERR, "read_groups: malloc %d bytes: %m", 94: i * sizeof (char **)); 95: #endif 96: (void) close(act_fd); 97: return (0); 98: } 99: 100: cp = actbuf; 101: i = 0; 102: while (cp < end) { 103: group_array[i++] = cp; 104: cp = index(cp, '\n'); 105: if (cp == NULL) 106: break; 107: *cp = '\0'; 108: cp++; 109: } 110: 111: qsort((char *) group_array, i, sizeof (char *), act_cmp); 112: 113: return (i); 114: } 115: 116: 117: act_cmp(ptr1, ptr2) 118: char **ptr1, **ptr2; 119: { 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: * "num_groups" is the total number 132: * of groups in the group array. 133: * "low_msg" and "high_msg" are 134: * pointers to where we're supposed 135: * to put the low and high message numbers. 136: * 137: * Returns: 0 if all goes well, 138: * -1 if we can't find the group. 139: * 140: * Side effects: None. 141: */ 142: 143: find_group(group, num_groups, low_msg, high_msg) 144: char *group; 145: int num_groups; 146: int *low_msg, *high_msg; 147: { 148: char kludgebuf[MAXBUFLEN]; 149: int cond; 150: register int low, high, mid; 151: int length; 152: 153: low = 0; 154: high = num_groups-1; 155: (void) strcpy(kludgebuf, group); 156: (void) strcat(kludgebuf, " "); 157: length = strlen(kludgebuf); 158: 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(0); 169: } 170: } 171: return(-1); 172: }