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