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 } |
