Mercurial > noffle
comparison content.c @ 0:04124a4423d4 noffle
[svn] Initial revision
author | enz |
---|---|
date | Tue, 04 Jan 2000 11:35:42 +0000 |
parents | |
children | 912123d43a87 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:04124a4423d4 |
---|---|
1 /* | |
2 content.c | |
3 | |
4 $Id: content.c 3 2000-01-04 11:35:42Z enz $ | |
5 */ | |
6 | |
7 #include <dirent.h> | |
8 #include <fcntl.h> | |
9 #include <sys/types.h> | |
10 #include <sys/stat.h> | |
11 #include <unistd.h> | |
12 #include "common.h" | |
13 #include "config.h" | |
14 #include "log.h" | |
15 #include "over.h" | |
16 #include "pseudo.h" | |
17 #include "util.h" | |
18 | |
19 struct | |
20 { | |
21 DIR *dir; /* Directory for browsing through all | |
22 groups */ | |
23 int first; | |
24 int last; | |
25 unsigned int size; /* Number of overviews. */ | |
26 unsigned int max; /* Size of elem. */ | |
27 Over **elem; /* Ptr to array with ptrs to overviews. | |
28 NULL entries for non-existing article numbers | |
29 in group. */ | |
30 Str name; | |
31 Str file; | |
32 } cont = { NULL, 1, 0, 0, 0, NULL, "", "" }; | |
33 | |
34 void | |
35 Cont_app( Over *ov ) | |
36 { | |
37 if ( cont.max < cont.size + 1 ) | |
38 { | |
39 if ( ! ( cont.elem = realloc( cont.elem, | |
40 ( cont.max + 500 ) | |
41 * sizeof( cont.elem[ 0 ] ) ) ) ) | |
42 { | |
43 Log_err( "Could not realloc overview list" ); | |
44 exit( EXIT_FAILURE ); | |
45 } | |
46 cont.max += 500; | |
47 } | |
48 if ( cont.first == 0 ) | |
49 cont.first = 1; | |
50 if ( ov ) | |
51 Ov_setNumb( ov, cont.first + cont.size ); | |
52 cont.elem[ cont.size++ ] = ov; | |
53 cont.last = cont.first + cont.size - 1; | |
54 } | |
55 | |
56 Bool | |
57 Cont_validNumb( int n ) | |
58 { | |
59 return ( n != 0 && n >= cont.first && n <= cont.last | |
60 && cont.elem[ n - cont.first ] ); | |
61 } | |
62 | |
63 void | |
64 Cont_delete( int n ) | |
65 { | |
66 Over **ov; | |
67 | |
68 if ( ! Cont_validNumb( n ) ) | |
69 return; | |
70 ov = &cont.elem[ n - cont.first ]; | |
71 free( *ov ); | |
72 *ov = NULL; | |
73 } | |
74 | |
75 /* Remove all overviews from content. */ | |
76 static void | |
77 clearCont() | |
78 { | |
79 int i; | |
80 | |
81 for ( i = 0; i < cont.size; ++i ) | |
82 del_Over( cont.elem[ i ] ); | |
83 cont.size = 0; | |
84 } | |
85 | |
86 /* Extend content list to size "cnt" and append NULL entries. */ | |
87 static void | |
88 extendCont( int cnt ) | |
89 { | |
90 int i, n; | |
91 | |
92 if ( cont.size < cnt ) | |
93 { | |
94 n = cnt - cont.size; | |
95 for ( i = 0; i < n; ++i ) | |
96 Cont_app( NULL ); | |
97 } | |
98 } | |
99 | |
100 /* Discard all cached overviews, and read in the overviews of a new group | |
101 from its overviews file. */ | |
102 void | |
103 Cont_read( const char *name ) | |
104 { | |
105 FILE *f; | |
106 Over *ov; | |
107 int cnt, numb; | |
108 Str line; | |
109 | |
110 /* Delete old overviews and make room for new ones. */ | |
111 cont.first = 0; | |
112 cont.last = 0; | |
113 Utl_cpyStr( cont.name, name ); | |
114 clearCont(); | |
115 | |
116 /* read overviews from overview file and store them in the overviews | |
117 list */ | |
118 snprintf( cont.file, MAXCHAR, "%s/overview/%s", Cfg_spoolDir(), name ); | |
119 if ( cnt == 0 ) | |
120 return; | |
121 f = fopen( cont.file, "r" ); | |
122 if ( ! f ) | |
123 { | |
124 Log_dbg( "No group overview file: %s", cont.file ); | |
125 return; | |
126 } | |
127 Log_dbg( "Reading %s", cont.file ); | |
128 while ( fgets( line, MAXCHAR, f ) ) | |
129 { | |
130 if ( ! ( ov = Ov_read( line ) ) ) | |
131 { | |
132 Log_err( "Overview corrupted in %s: %s", name, line ); | |
133 continue; | |
134 } | |
135 numb = Ov_numb( ov ); | |
136 if ( numb < cont.first ) | |
137 { | |
138 Log_err( "Wrong ordering in %s: %s", name, line ); | |
139 continue; | |
140 } | |
141 if ( cont.first == 0 ) | |
142 cont.first = numb; | |
143 cont.last = numb; | |
144 extendCont( numb - cont.first + 1 ); | |
145 cont.elem[ numb - cont.first ] = ov; | |
146 } | |
147 fclose( f ); | |
148 } | |
149 | |
150 void | |
151 Cont_write( void ) | |
152 { | |
153 Bool anythingWritten; | |
154 int i, first; | |
155 FILE *f; | |
156 const Over *ov; | |
157 | |
158 first = cont.first; | |
159 while ( ! Cont_validNumb( first ) && first <= cont.last ) | |
160 ++first; | |
161 if ( ! ( f = fopen( cont.file, "w" ) ) ) | |
162 { | |
163 Log_err( "Could not open %s for writing", cont.file ); | |
164 return; | |
165 } | |
166 Log_dbg( "Writing %s (%lu)", cont.file, cont.size ); | |
167 anythingWritten = FALSE; | |
168 for ( i = 0; i < cont.size; ++i ) | |
169 { | |
170 if ( ( ov = cont.elem[ i ] ) ) | |
171 { | |
172 if ( ! Pseudo_isGeneralInfo( Ov_msgId( ov ) ) ) | |
173 { | |
174 if ( ! Ov_write( ov, f ) ) | |
175 { | |
176 Log_err( "Writing of overview line failed" ); | |
177 break; | |
178 } | |
179 else | |
180 anythingWritten = TRUE; | |
181 } | |
182 } | |
183 } | |
184 fclose( f ); | |
185 if ( ! anythingWritten ) | |
186 unlink( cont.file ); | |
187 } | |
188 | |
189 const Over * | |
190 Cont_get( int numb ) | |
191 { | |
192 if ( ! Cont_validNumb( numb ) ) | |
193 return NULL; | |
194 return cont.elem[ numb - cont.first ]; | |
195 } | |
196 | |
197 int | |
198 Cont_first( void ) { return cont.first; } | |
199 | |
200 int | |
201 Cont_last( void ) { return cont.last; } | |
202 | |
203 const char * | |
204 Cont_grp( void ) { return cont.name; } | |
205 | |
206 Bool | |
207 Cont_nextGrp( Str result ) | |
208 { | |
209 struct dirent *d; | |
210 | |
211 ASSERT( cont.dir ); | |
212 if ( ! ( d = readdir( cont.dir ) ) ) | |
213 { | |
214 cont.dir = NULL; | |
215 return FALSE; | |
216 } | |
217 if ( ! d->d_name ) | |
218 return FALSE; | |
219 Utl_cpyStr( result, d->d_name ); | |
220 result[ MAXCHAR - 1 ] = '\0'; | |
221 return TRUE; | |
222 } | |
223 | |
224 Bool | |
225 Cont_firstGrp( Str result ) | |
226 { | |
227 Str name; | |
228 | |
229 snprintf( name, MAXCHAR, "%s/overview", Cfg_spoolDir() ); | |
230 if ( ! ( cont.dir = opendir( name ) ) ) | |
231 { | |
232 Log_err( "Cannot open %s", name ); | |
233 return FALSE; | |
234 } | |
235 Cont_nextGrp( result ); /* "." */ | |
236 Cont_nextGrp( result ); /* ".." */ | |
237 return Cont_nextGrp( result ); | |
238 } |