comparison src/content.c @ 43:2842f50feb55 noffle

[svn] * client.c, client.h, common.h, config.c, config.h, content.c, content.h, control.c, control.h, database.c, database.h, dynamicstring.c, dynamicstring.h, fetch.c, fetch.h, fetchlist.c, fetchlist.h, group.c, group.h, itemlist.c, itemlist.h, lock.c, lock.h, log.c, log.h, noffle.c, online.c, online.h, outgoing.c, outgoing.h, over.c, over.h, post.c, post.h, protocol.c, protocol.h, pseudo.c, pseudo.h, request.c, request.h, server.c, server.h, util.c, util.h, wildmat.c, wildmat.h: Moved files to the subdirectory src/ * Makefile.am, acconfig.h, configure.in, docs/Makefile.am, src/Makefile.am, Makefile.in, aclocal.m4, config.h.in, configure, install-sh, missing, mkinstalldirs, stamp-h.in, docs/Makefile.in, src/Makefile.in: Added files. They are used by aclocal, autoheader, autoconf and automake. * src/config.c, src/config.h: Renamed to configfile.c and configfile.h, because configure will generate a config.h file itself. * src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c, src/group.c, src/lock.c, src/noffle.c, src/online.c, src/outgoing.c, src/over.c, src/pseudo.c, src/request.c, src/server.c, src/util.c: Changed '#include "config.h"' to '#include "configfile.h"'. * src/client.c, src/content.c, src/database.c, src/fetch.c, src/fetchlist.c, src/group.c, src/lock.c, src/online.c, src/outgoing.c, src/post.c, src/protocol.c, src/request.c, src/server.c: Files now #include <config.h>. Added missing <stdio.h>. This removes the warnings about snprintf() not being declared. * Makefile: Removed. This is now generated by configure.
author uh1763
date Fri, 05 May 2000 22:45:56 +0100
parents
children 32ba1198c6fa
comparison
equal deleted inserted replaced
42:2467ff423c15 43:2842f50feb55
1 /*
2 content.c
3
4 $Id: content.c 49 2000-05-05 21:45:56Z uh1763 $
5 */
6
7 #if HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdio.h>
12 #include <dirent.h>
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include "common.h"
18 #include "configfile.h"
19 #include "group.h"
20 #include "log.h"
21 #include "over.h"
22 #include "pseudo.h"
23 #include "util.h"
24
25 struct
26 {
27 DIR *dir; /* Directory for browsing through all
28 groups */
29 int vecFirst; /* First article number in vector */
30 int first; /* First live article number */
31 int last; /* Last article number */
32 unsigned int size; /* Number of overviews. */
33 unsigned int max; /* Size of elem. */
34 Over **elem; /* Ptr to array with ptrs to overviews.
35 NULL entries for non-existing article numbers
36 in group. */
37 Str name;
38 Str file;
39 } cont = { NULL, 1, 1, 0, 0, 0, NULL, "", "" };
40
41 void
42 Cont_app( Over *ov )
43 {
44 if ( cont.max < cont.size + 1 )
45 {
46 if ( ! ( cont.elem = realloc( cont.elem,
47 ( cont.max + 500 )
48 * sizeof( cont.elem[ 0 ] ) ) ) )
49 {
50 Log_err( "Could not realloc overview list" );
51 exit( EXIT_FAILURE );
52 }
53 cont.max += 500;
54 }
55 ASSERT( cont.vecFirst > 0 );
56 if ( ov )
57 Ov_setNumb( ov, cont.vecFirst + cont.size );
58 cont.elem[ cont.size++ ] = ov;
59 cont.last = cont.vecFirst + cont.size - 1;
60 }
61
62 Bool
63 Cont_validNumb( int n )
64 {
65 return ( n != 0 && n >= cont.first && n <= cont.last
66 && cont.elem[ n - cont.vecFirst ] );
67 }
68
69 void
70 Cont_delete( int n )
71 {
72 Over **ov;
73
74 if ( ! Cont_validNumb( n ) )
75 return;
76 ov = &cont.elem[ n - cont.vecFirst ];
77 free( *ov );
78 *ov = NULL;
79 }
80
81 /* Remove all overviews from content. */
82 static void
83 clearCont()
84 {
85 int i;
86
87 for ( i = 0; i < cont.size; ++i )
88 del_Over( cont.elem[ i ] );
89 cont.size = 0;
90 }
91
92 static void
93 setupEmpty( const char *name )
94 {
95 cont.last = Grp_last( name );
96 cont.first = cont.vecFirst = cont.last + 1;
97 ASSERT( cont.first > 0 );
98 }
99
100 /* Extend content list to size "cnt" and append NULL entries. */
101 static void
102 extendCont( int cnt )
103 {
104 int i, n;
105
106 if ( cont.size < cnt )
107 {
108 n = cnt - cont.size;
109 for ( i = 0; i < n; ++i )
110 Cont_app( NULL );
111 }
112 }
113
114 /* Discard all cached overviews, and read in the overviews of a new group
115 from its overviews file. */
116 void
117 Cont_read( const char *name )
118 {
119 FILE *f;
120 Over *ov;
121 int numb;
122 Str line;
123
124 /* Delete old overviews and make room for new ones. */
125 cont.vecFirst = 0;
126 cont.first = 0;
127 cont.last = 0;
128 Utl_cpyStr( cont.name, name );
129 clearCont();
130
131 /* read overviews from overview file and store them in the overviews
132 list */
133 snprintf( cont.file, MAXCHAR, "%s/overview/%s", Cfg_spoolDir(), name );
134 f = fopen( cont.file, "r" );
135 if ( ! f )
136 {
137 Log_dbg( "No group overview file: %s", cont.file );
138 setupEmpty( name );
139 return;
140 }
141 Log_dbg( "Reading %s", cont.file );
142 while ( fgets( line, MAXCHAR, f ) )
143 {
144 if ( ! ( ov = Ov_read( line ) ) )
145 {
146 Log_err( "Overview corrupted in %s: %s", name, line );
147 continue;
148 }
149 numb = Ov_numb( ov );
150 if ( numb < cont.first )
151 {
152 Log_err( "Wrong ordering in %s: %s", name, line );
153 continue;
154 }
155 if ( cont.first == 0 )
156 cont.first = cont.vecFirst = numb;
157 cont.last = numb;
158 extendCont( numb - cont.first + 1 );
159 cont.elem[ numb - cont.first ] = ov;
160 }
161 fclose( f );
162
163 if ( cont.first == 0 )
164 setupEmpty( name ); /* Corrupt overview file recovery */
165 }
166
167 void
168 Cont_write( void )
169 {
170 Bool anythingWritten;
171 int i;
172 FILE *f;
173 const Over *ov;
174
175
176 /* Move the first article no. to the first active article */
177 while ( ! Cont_validNumb( cont.first ) && cont.first <= cont.last )
178 ++cont.first;
179
180 /* Save the overview */
181 if ( ! ( f = fopen( cont.file, "w" ) ) )
182 {
183 Log_err( "Could not open %s for writing", cont.file );
184 return;
185 }
186 Log_dbg( "Writing %s (%lu)", cont.file, cont.size );
187 anythingWritten = FALSE;
188 for ( i = 0; i < cont.size; ++i )
189 {
190 if ( ( ov = cont.elem[ i ] ) )
191 {
192 if ( ! Pseudo_isGeneralInfo( Ov_msgId( ov ) ) )
193 {
194 if ( ! Ov_write( ov, f ) )
195 {
196 Log_err( "Writing of overview line failed" );
197 break;
198 }
199 else
200 anythingWritten = TRUE;
201 }
202 }
203 }
204 fclose( f );
205
206 /*
207 If empty, remove the overview file and set set first to one
208 beyond last to flag said emptiness.
209 */
210 if ( ! anythingWritten )
211 {
212 unlink( cont.file );
213 cont.first = cont.last + 1;
214 }
215 }
216
217 const Over *
218 Cont_get( int numb )
219 {
220 if ( ! Cont_validNumb( numb ) )
221 return NULL;
222 return cont.elem[ numb - cont.vecFirst ];
223 }
224
225 int
226 Cont_first( void ) { return cont.first; }
227
228 int
229 Cont_last( void ) { return cont.last; }
230
231 const char *
232 Cont_grp( void ) { return cont.name; }
233
234 Bool
235 Cont_nextGrp( Str result )
236 {
237 struct dirent *d;
238
239 ASSERT( cont.dir );
240 if ( ! ( d = readdir( cont.dir ) ) )
241 {
242 cont.dir = NULL;
243 return FALSE;
244 }
245 if ( ! d->d_name )
246 return FALSE;
247 Utl_cpyStr( result, d->d_name );
248 result[ MAXCHAR - 1 ] = '\0';
249 return TRUE;
250 }
251
252 Bool
253 Cont_firstGrp( Str result )
254 {
255 Str name;
256
257 snprintf( name, MAXCHAR, "%s/overview", Cfg_spoolDir() );
258 if ( ! ( cont.dir = opendir( name ) ) )
259 {
260 Log_err( "Cannot open %s", name );
261 return FALSE;
262 }
263 Cont_nextGrp( result ); /* "." */
264 Cont_nextGrp( result ); /* ".." */
265 return Cont_nextGrp( result );
266 }