1 /*
2 * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
3 * Copyright (c) 1996-2005 Michael T Pins. All rights reserved.
4 *
5 * read/update incore copy of active file
6 */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include "config.h"
12 #include "global.h"
13 #include "active.h"
14 #include "db.h"
15 #include "master.h"
16 #include "newsrc.h"
17
18 void
read_active_file(FILE * act,FILE * copy)19 read_active_file(FILE * act, FILE * copy)
20 {
21 char line[512];
22 register char *cp, *name;
23 register group_header *gh, *gh1;
24 int must_update;
25 register flag_type old_flag;
26
27 Loop_Groups_Header(gh) {
28 gh->master_flag &= ~M_VALID;
29 gh->first_a_article = 0;
30 gh->last_a_article = 0;
31 }
32
33 while (fgets(line, 512, act)) {
34 if (copy != NULL)
35 fputs(line, copy);
36 must_update = 0;
37
38 cp = line;
39 while (*cp && isspace(*cp))
40 cp++; /* eat blank lines */
41 if (*cp == NUL || *cp == '#')
42 continue;
43
44 /* cp -> NAME space 00888 ... nl */
45 name = cp;
46 while (*cp != ' ')
47 cp++;
48 *cp++ = NUL;
49
50 gh = lookup_no_alias(name);
51 if (gh == NULL) {
52 /* new group */
53 gh = add_new_group(name);
54 if (gh == NULL)
55 continue;
56 must_update = 1;
57 }
58 while (*cp && isspace(*cp))
59 cp++;
60 gh->last_a_article = atol(cp);
61
62 while (*cp && isdigit(*cp))
63 cp++;
64 while (*cp && isspace(*cp))
65 cp++;
66
67 if (*cp == NUL) {
68 log_entry('E', "Error in active file for entry %s", name);
69 continue;
70 }
71 gh->first_a_article = atol(cp);
72 if (gh->first_a_article == 0)
73 gh->first_a_article = 1;
74 while (*cp && isdigit(*cp))
75 cp++;
76 while (*cp && isspace(*cp))
77 cp++;
78
79 gh->master_flag |= M_VALID;
80 if (gh->master_flag & M_IGNORE_G)
81 continue;
82
83 old_flag = gh->master_flag &
84 (M_IGNORE_A | M_MODERATED | M_NOPOST | M_ALIASED);
85 gh->master_flag &=
86 ~(M_IGNORE_A | M_MODERATED | M_NOPOST | M_ALIASED);
87
88 switch (*cp) {
89 default:
90 break;
91
92 case 'x':
93 gh->master_flag |= M_IGNORE_A;
94 if ((old_flag & (M_IGNORE_A | M_ALIASED)) == M_IGNORE_A)
95 continue;
96 must_update++;
97 break;
98
99 case 'm':
100 gh->master_flag |= M_MODERATED;
101 if (old_flag & M_MODERATED)
102 continue;
103 must_update++;
104 break;
105
106 case 'n':
107 gh->master_flag |= M_NOPOST;
108 if (old_flag & M_NOPOST)
109 continue;
110 must_update++;
111 break;
112
113 case '=':
114 while (*++cp && isspace(*cp))
115 cp++;
116 name = cp;
117 while (*cp && !isspace(*cp))
118 cp++;
119 *cp = NUL;
120 if (old_flag & M_ALIASED) {
121 /* quick check: has the alias changed */
122 int32 n = (int32) gh->data_write_offset;
123 if (n >= 0 && n < master.number_of_groups) {
124 gh1 = ACTIVE_GROUP(n);
125 if (strcmp(gh1->group_name, name) == 0) {
126 gh->master_flag |= M_ALIASED | M_IGNORE_A;
127 continue;
128 }
129 }
130 }
131 gh1 = lookup_no_alias(name);
132 if (gh1 == NULL) {
133 /* '=unknown.group' is treated just like 'x' */
134 if ((old_flag & M_IGNORE_A) == 0)
135 log_entry('R', "Group %s aliased to unknown group (%s)",
136 gh->group_name, name);
137 gh->master_flag |= M_IGNORE_A;
138 if ((old_flag & (M_IGNORE_A | M_ALIASED)) == M_IGNORE_A)
139 continue;
140 } else {
141 gh->master_flag |= M_ALIASED | M_IGNORE_A;
142 gh->data_write_offset = (long) gh1->group_num;
143 }
144 must_update = 1;
145 break;
146 }
147
148 if ((old_flag & M_ALIASED) && (gh->master_flag & M_ALIASED) == 0) {
149 gh->data_write_offset = 0;
150 gh->master_flag |= M_MUST_CLEAN;
151 continue;
152 }
153 if (must_update && who_am_i == I_AM_MASTER)
154 db_write_group(gh);
155 }
156 }
157