1: #ifndef lint 2: static char *sccsid = "%W% (Berkeley) %G%"; 3: #endif 4: 5: /* 6: * Make a list of newsgroups which are "new" in the file NGDATE_FILE. 7: * "New" means having an entry in the active file, and having 8: * a message numbered "1" in the appropriate news directory. 9: * Since this involves a stat of all the newsgroups, we try 10: * to be intelligent about things -- if the active file's size 11: * since we last ran -- stored in STAT_FILE -- hasn't changed 12: * since last time, we assume things are ok, and exit without 13: * doing anything. This could fail in extreme circumstances, 14: * but is "too painful to do right". 15: * 16: * Output in NGDATE_FILE is of the form 17: * 18: * date newsgroup 19: * 20: * where "date" is the date the newsgroup was created, expressed as 21: * the number of seconds since 000000 Jan 1, 1970, GMT. This file 22: * winds up sorted in cronological order. 23: * 24: * Phil Lapsley 25: * College of Engineering 26: * University of California, Berkeley 27: * (ARPA: phil@Berkeley.ARPA; UUCP: ...!ucbvax!phil) 28: */ 29: 30: #include <stdio.h> 31: #include <sys/types.h> 32: #include <sys/time.h> 33: #include <sys/stat.h> 34: #include "../common/conf.h" 35: 36: #define MODE 0644 /* Better be readable by nntpd! */ 37: 38: extern int linecmp(); 39: extern char *index(), *malloc(), *strcpy(), *strcat(); 40: 41: main(argc, argv) 42: int argc; 43: char *argv[]; 44: { 45: char *groups[MAX_GROUPS]; 46: char line[MAX_STRLEN], gr_name[MAX_STRLEN]; 47: char *cp; 48: int i, j; 49: long lastsize, crntsize; 50: long birthtime; 51: struct tm *tmptr; 52: FILE *stat_fp, *active_fp, *date_fp; 53: long birthof(); 54: 55: stat_fp = fopen(STAT_FILE, "r"); 56: 57: if (stat_fp != NULL) { 58: (void) fscanf(stat_fp, "%d", &lastsize); 59: (void) fclose(stat_fp); 60: } 61: 62: active_fp = fopen(ACTIVE_FILE, "r"); 63: if (active_fp == NULL) { 64: fprintf(stderr, "Can't read active file?\n"); 65: perror(ACTIVE_FILE); 66: exit(1); 67: } 68: 69: /* Check length; if it's the same as last time, quit */ 70: 71: (void) fseek(active_fp, (long) 0, 2); 72: crntsize = ftell(active_fp); 73: if (crntsize == lastsize) { 74: (void) fclose(active_fp); 75: exit(0); 76: } 77: 78: /* Ok, time to rebuild the date file */ 79: 80: date_fp = fopen(NGDATE_FILE, "w"); 81: 82: if (date_fp == NULL) { 83: perror(NGDATE_FILE); 84: (void) fclose(active_fp); 85: exit(1); 86: } 87: 88: rewind(active_fp); 89: 90: i = 0; 91: while (fgets(line, sizeof(line), active_fp) != NULL) { 92: if ((cp = index(line, ' ')) != NULL) 93: *cp = '\0'; 94: (void) strcpy(gr_name, line); 95: birthtime = birthof(line, atoi(cp + 1)); 96: 97: if (birthtime == 0) /* Skip ancient newsgroups */ 98: continue; 99: 100: (void) sprintf(line, "%ld %s", birthtime, gr_name); 101: groups[i] = malloc(strlen(line)+1); 102: if (groups[i] != NULL) 103: (void) strcpy(groups[i++], line); 104: else { 105: perror("malloc"); 106: exit(1); 107: } 108: } 109: 110: (void) fclose(active_fp); 111: 112: qsort((char *) groups, i, sizeof(char *), linecmp); 113: 114: for (j = 0; j < i; ++j) 115: fprintf(date_fp, "%s\n", groups[j]); 116: 117: (void) fclose(date_fp); 118: 119: (void) chmod(NGDATE_FILE, MODE); 120: 121: stat_fp = fopen(STAT_FILE, "w"); 122: if (stat_fp == NULL) { 123: perror(STAT_FILE); 124: exit(1); 125: } 126: 127: fprintf(stat_fp, "%d\n", crntsize); 128: 129: (void) fclose(stat_fp); 130: 131: (void) chmod(STAT_FILE, MODE); 132: 133: exit(0); 134: } 135: 136: linecmp(line1, line2) 137: char **line1, **line2; 138: { 139: return(0 - strcmp(*line1, *line2)); 140: } 141: 142: 143: /* return creation time of newsgroup */ 144: 145: long 146: birthof(group, highart) 147: char *group; 148: int highart; 149: { 150: char *cp, *index(); 151: char tst[128]; 152: struct stat statbuf; 153: 154: while ((cp = index(group, '.'))) 155: *cp = '/'; 156: 157: (void) strcpy(tst, SPOOLDIR); 158: (void) strcat(tst, group); 159: if (highart) 160: (void) strcat(tst, "/1"); 161: if (stat(tst, &statbuf) < 0) 162: return 0L; /* not there, assume ancient */ 163: else 164: return(statbuf.st_mtime); 165: }