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 }