annotate database.c @ 0:04124a4423d4 noffle

[svn] Initial revision
author enz
date Tue, 04 Jan 2000 11:35:42 +0000
parents
children 526a4c34ee2e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
1 /*
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
2 database.c
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
3
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
4 $Id: database.c 3 2000-01-04 11:35:42Z enz $
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
5
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
6 Uses GNU gdbm library. Using Berkeley db (included in libc6) was
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
7 cumbersome. It is based on Berkeley db 1.85, which has severe bugs
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
8 (e.g. it is not recommended to delete or overwrite entries with
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
9 overflow pages).
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
10 */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
11
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
12 #include "database.h"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
13 #include <ctype.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
14 #include <errno.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
15 #include <fcntl.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
16 #include <gdbm.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
17 #include <unistd.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
18 #include <sys/types.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
19 #include <sys/stat.h>
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
20 #include "config.h"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
21 #include "log.h"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
22 #include "protocol.h"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
23 #include "util.h"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
24
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
25 static struct Db
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
26 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
27 GDBM_FILE dbf;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
28
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
29 /* Start string for Xref header line: "Xref: <host>" */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
30 Str xrefHost;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
31
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
32 /* Msg Id of presently loaded article, empty if none loaded */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
33 Str msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
34
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
35 /* Status of loaded article */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
36 int stat; /* Flags */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
37 time_t lastAccess;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
38
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
39 /* Overview of loaded article */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
40 Str subj;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
41 Str from;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
42 Str date;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
43 Str ref;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
44 Str xref;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
45 size_t bytes;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
46 size_t lines;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
47
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
48 /* Article text (except for overview header lines) */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
49 DynStr *txt;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
50
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
51 } db = { NULL, "(unknown)", "", 0, 0, "", "", "", "", "", 0, 0, NULL };
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
52
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
53 static const char *
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
54 errMsg( void )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
55 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
56 if ( errno != 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
57 return strerror( errno );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
58 return gdbm_strerror( gdbm_errno );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
59 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
60
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
61 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
62 Db_open( void )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
63 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
64 Str name, host;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
65 int flags;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
66
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
67 ASSERT( db.dbf == NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
68 snprintf( name, MAXCHAR, "%s/data/articles.gdbm", Cfg_spoolDir() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
69 flags = GDBM_WRCREAT | GDBM_FAST;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
70
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
71 if ( ! ( db.dbf = gdbm_open( name, 512, flags, 0644, NULL ) ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
72 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
73 Log_err( "Error opening %s for r/w (%s)", name, errMsg() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
74 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
75 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
76 Log_dbg( "%s opened for r/w", name );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
77
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
78 if ( db.txt == NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
79 db.txt = new_DynStr( 5000 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
80
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
81 gethostname( host, MAXCHAR );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
82 snprintf( db.xrefHost, MAXCHAR, "Xref: %s", host );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
83
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
84 return TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
85 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
86
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
87 void
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
88 Db_close( void )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
89 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
90 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
91 Log_dbg( "Closing database" );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
92 gdbm_close( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
93 db.dbf = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
94 del_DynStr( db.txt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
95 db.txt = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
96 Utl_cpyStr( db.msgId, "" );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
97 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
98
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
99 static Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
100 loadArt( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
101 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
102 static void *dptr = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
103
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
104 datum key, val;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
105 Str t = "";
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
106 const char *p;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
107
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
108 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
109
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
110 if ( strcmp( msgId, db.msgId ) == 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
111 return TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
112
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
113 key.dptr = (void *)msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
114 key.dsize = strlen( msgId ) + 1;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
115 if ( dptr != NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
116 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
117 free( dptr );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
118 dptr = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
119 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
120 val = gdbm_fetch( db.dbf, key );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
121 dptr = val.dptr;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
122 if ( dptr == NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
123 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
124 Log_dbg( "database.c loadArt: gdbm_fetch found no entry" );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
125 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
126 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
127
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
128 Utl_cpyStr( db.msgId, msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
129 p = Utl_getLn( t, (char *)dptr );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
130 if ( ! p || sscanf( t, "%x", &db.stat ) != 1 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
131 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
132 Log_err( "Entry in database '%s' is corrupt (status)", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
133 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
134 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
135 p = Utl_getLn( t, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
136 if ( ! p || sscanf( t, "%lu", &db.lastAccess ) != 1 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
137 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
138 Log_err( "Entry in database '%s' is corrupt (lastAccess)", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
139 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
140 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
141 p = Utl_getLn( db.subj, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
142 p = Utl_getLn( db.from, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
143 p = Utl_getLn( db.date, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
144 p = Utl_getLn( db.ref, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
145 p = Utl_getLn( db.xref, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
146 if ( ! p )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
147 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
148 Log_err( "Entry in database '%s' is corrupt (overview)", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
149 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
150 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
151 p = Utl_getLn( t, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
152 if ( ! p || sscanf( t, "%u", &db.bytes ) != 1 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
153 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
154 Log_err( "Entry in database '%s' is corrupt (bytes)", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
155 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
156 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
157 p = Utl_getLn( t, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
158 if ( ! p || sscanf( t, "%u", &db.lines ) != 1 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
159 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
160 Log_err( "Entry in database '%s' is corrupt (lines)", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
161 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
162 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
163 DynStr_clear( db.txt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
164 DynStr_app( db.txt, p );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
165 return TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
166 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
167
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
168 static Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
169 saveArt( void )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
170 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
171 DynStr *s;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
172 Str t = "";
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
173 datum key, val;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
174
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
175 if ( strcmp( db.msgId, "" ) == 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
176 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
177 s = new_DynStr( 5000 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
178 snprintf( t, MAXCHAR, "%x", db.stat );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
179 DynStr_appLn( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
180 snprintf( t, MAXCHAR, "%lu", db.lastAccess );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
181 DynStr_appLn( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
182 DynStr_appLn( s, db.subj );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
183 DynStr_appLn( s, db.from );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
184 DynStr_appLn( s, db.date );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
185 DynStr_appLn( s, db.ref );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
186 DynStr_appLn( s, db.xref );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
187 snprintf( t, MAXCHAR, "%u", db.bytes );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
188 DynStr_appLn( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
189 snprintf( t, MAXCHAR, "%u", db.lines );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
190 DynStr_appLn( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
191 DynStr_appDynStr( s, db.txt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
192
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
193 key.dptr = (void *)db.msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
194 key.dsize = strlen( db.msgId ) + 1;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
195 val.dptr = (void *)DynStr_str( s );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
196 val.dsize = DynStr_len( s ) + 1;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
197 if ( gdbm_store( db.dbf, key, val, GDBM_REPLACE ) != 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
198 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
199 Log_err( "Could not store %s in database (%s)", errMsg() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
200 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
201 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
202
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
203 del_DynStr( s );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
204 return TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
205 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
206
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
207 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
208 Db_prepareEntry( const Over *ov, const char *grp, int numb )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
209 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
210 const char *msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
211
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
212 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
213 ASSERT( ov );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
214 ASSERT( grp );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
215
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
216 msgId = Ov_msgId( ov );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
217 Log_dbg( "Preparing entry %s", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
218 if ( Db_contains( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
219 Log_err( "Preparing article twice: %s", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
220
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
221 db.stat = DB_NOT_DOWNLOADED;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
222 db.lastAccess = time( NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
223
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
224 Utl_cpyStr( db.msgId, msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
225 Utl_cpyStr( db.subj, Ov_subj( ov ) );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
226 Utl_cpyStr( db.from, Ov_from( ov ) );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
227 Utl_cpyStr( db.date, Ov_date( ov ) );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
228 Utl_cpyStr( db.ref, Ov_ref( ov ) );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
229 snprintf( db.xref, MAXCHAR, "%s:%i", grp, numb );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
230 db.bytes = Ov_bytes( ov );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
231 db.lines = Ov_lines( ov );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
232
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
233 DynStr_clear( db.txt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
234
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
235 return saveArt();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
236 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
237
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
238 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
239 Db_storeArt( const char *msgId, const char *artTxt )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
240 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
241 Str line, lineEx, field, value;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
242 const char *startPos;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
243
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
244 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
245
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
246 Log_dbg( "Store article %s", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
247 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
248 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
249 Log_err( "Cannot find info about '%s' in database", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
250 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
251 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
252 if ( ! ( db.stat & DB_NOT_DOWNLOADED ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
253 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
254 Log_err( "Trying to store alrady retrieved article '%s'", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
255 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
256 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
257 db.stat &= ~DB_NOT_DOWNLOADED;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
258 db.stat &= ~DB_RETRIEVING_FAILED;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
259 db.lastAccess = time( NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
260
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
261 DynStr_clear( db.txt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
262
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
263 /* Read header */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
264 startPos = artTxt;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
265 while ( TRUE )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
266 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
267 artTxt = Utl_getLn( lineEx, artTxt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
268 if ( lineEx[ 0 ] == '\0' )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
269 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
270 DynStr_appLn( db.txt, lineEx );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
271 break;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
272 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
273 /* Get other lines if field is split over multiple lines */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
274 while ( ( artTxt = Utl_getLn( line, artTxt ) ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
275 if ( isspace( line[ 0 ] ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
276 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
277 strncat( lineEx, "\n", MAXCHAR );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
278 strncat( lineEx, line, MAXCHAR );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
279 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
280 else
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
281 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
282 artTxt = Utl_ungetLn( startPos, artTxt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
283 break;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
284 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
285 /* Remove fields already in overview and handle x-noffle
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
286 headers correctly in case of cascading NOFFLEs */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
287 if ( Prt_getField( field, value, lineEx ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
288 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
289 if ( strcmp( field, "x-noffle-status" ) == 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
290 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
291 if ( strstr( value, "NOT_DOWNLOADED" ) != 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
292 db.stat |= DB_NOT_DOWNLOADED;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
293 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
294 else if ( strcmp( field, "message-id" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
295 && strcmp( field, "xref" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
296 && strcmp( field, "references" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
297 && strcmp( field, "subject" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
298 && strcmp( field, "from" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
299 && strcmp( field, "date" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
300 && strcmp( field, "bytes" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
301 && strcmp( field, "lines" ) != 0
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
302 && strcmp( field, "x-noffle-lastaccess" ) != 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
303 DynStr_appLn( db.txt, lineEx );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
304 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
305 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
306
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
307 /* Read body */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
308 while ( ( artTxt = Utl_getLn( line, artTxt ) ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
309 if ( ! ( db.stat & DB_NOT_DOWNLOADED ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
310 DynStr_appLn( db.txt, line );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
311
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
312 return saveArt();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
313 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
314
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
315 void
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
316 Db_setStat( const char *msgId, int stat )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
317 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
318 if ( loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
319 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
320 db.stat = stat;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
321 saveArt();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
322 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
323 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
324
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
325 void
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
326 Db_updateLastAccess( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
327 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
328 if ( loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
329 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
330 db.lastAccess = time( NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
331 saveArt();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
332 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
333 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
334
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
335 void
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
336 Db_setXref( const char *msgId, const char *xref )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
337 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
338 if ( loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
339 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
340 Utl_cpyStr( db.xref, xref );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
341 saveArt();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
342 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
343 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
344
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
345 /* Search best position for breaking a line */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
346 static const char *
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
347 searchBreakPos( const char *line, int wantedLength )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
348 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
349 const char *lastSpace = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
350 Bool lastWasSpace = FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
351 int len = 0;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
352
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
353 while ( *line != '\0' )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
354 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
355 if ( isspace( *line ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
356 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
357 if ( len > wantedLength && lastSpace != NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
358 return lastSpace;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
359 if ( ! lastWasSpace )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
360 lastSpace = line;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
361 lastWasSpace = TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
362 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
363 else
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
364 lastWasSpace = FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
365 ++len;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
366 ++line;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
367 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
368 if ( len > wantedLength && lastSpace != NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
369 return lastSpace;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
370 return line;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
371 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
372
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
373 /* Append header line by breaking long line into multiple lines */
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
374 static void
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
375 appendLongHeader( DynStr *target, const char *field, const char *value )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
376 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
377 const int wantedLength = 78;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
378 const char *breakPos, *old;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
379 int len;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
380
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
381 len = strlen( field );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
382 DynStr_appN( target, field, len );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
383 DynStr_appN( target, " ", 1 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
384 old = value;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
385 while ( isspace( *old ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
386 ++old;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
387 breakPos = searchBreakPos( old, wantedLength - len - 1 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
388 DynStr_appN( target, old, breakPos - old );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
389 if ( *breakPos == '\0' )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
390 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
391 DynStr_appN( target, "\n", 1 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
392 return;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
393 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
394 DynStr_appN( target, "\n ", 2 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
395 while ( TRUE )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
396 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
397 old = breakPos;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
398 while ( isspace( *old ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
399 ++old;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
400 breakPos = searchBreakPos( old, wantedLength - 1 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
401 DynStr_appN( target, old, breakPos - old );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
402 if ( *breakPos == '\0' )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
403 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
404 DynStr_appN( target, "\n", 1 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
405 return;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
406 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
407 DynStr_appN( target, "\n ", 2 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
408 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
409 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
410
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
411 const char *
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
412 Db_header( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
413 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
414 static DynStr *s = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
415
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
416 Str date, t;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
417 int stat;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
418 const char *p;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
419
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
420 if ( s == NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
421 s = new_DynStr( 5000 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
422 else
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
423 DynStr_clear( s );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
424 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
425 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
426 return NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
427 strftime( date, MAXCHAR, "%Y-%m-%d %H:%M:%S",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
428 localtime( &db.lastAccess ) );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
429 stat = db.stat;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
430 snprintf( t, MAXCHAR,
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
431 "Message-ID: %s\n"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
432 "X-NOFFLE-Status:%s%s%s\n"
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
433 "X-NOFFLE-LastAccess: %s\n",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
434 msgId,
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
435 stat & DB_INTERESTING ? " INTERESTING" : "",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
436 stat & DB_NOT_DOWNLOADED ? " NOT_DOWNLOADED" : "",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
437 stat & DB_RETRIEVING_FAILED ? " RETRIEVING_FAILED" : "",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
438 date );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
439 DynStr_app( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
440 appendLongHeader( s, "Subject:", db.subj );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
441 appendLongHeader( s, "From:", db.from );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
442 appendLongHeader( s, "Date:", db.date );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
443 appendLongHeader( s, "References:", db.ref );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
444 DynStr_app( s, "Bytes: " );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
445 snprintf( t, MAXCHAR, "%u", db.bytes );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
446 DynStr_appLn( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
447 DynStr_app( s, "Lines: " );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
448 snprintf( t, MAXCHAR, "%u", db.lines );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
449 DynStr_appLn( s, t );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
450 appendLongHeader( s, db.xrefHost, db.xref );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
451 p = strstr( DynStr_str( db.txt ), "\n\n" );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
452 if ( ! p )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
453 DynStr_appDynStr( s, db.txt );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
454 else
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
455 DynStr_appN( s, DynStr_str( db.txt ), p - DynStr_str( db.txt ) + 1 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
456 return DynStr_str( s );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
457 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
458
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
459 const char *
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
460 Db_body( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
461 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
462 const char *p;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
463
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
464 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
465 return "";
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
466 p = strstr( DynStr_str( db.txt ), "\n\n" );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
467 if ( ! p )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
468 return "";
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
469 return ( p + 2 );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
470 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
471
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
472 int
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
473 Db_stat( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
474 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
475 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
476 return 0;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
477 return db.stat;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
478 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
479
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
480 time_t
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
481 Db_lastAccess( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
482 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
483 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
484 return -1;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
485 return db.lastAccess;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
486 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
487
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
488 const char *
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
489 Db_ref( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
490 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
491 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
492 return "";
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
493 return db.ref;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
494 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
495
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
496 const char *
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
497 Db_xref( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
498 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
499 if ( ! loadArt( msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
500 return "";
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
501 return db.xref;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
502 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
503
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
504 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
505 Db_contains( const char *msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
506 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
507 datum key;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
508
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
509 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
510 if ( strcmp( msgId, db.msgId ) == 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
511 return TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
512 key.dptr = (void*)msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
513 key.dsize = strlen( msgId ) + 1;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
514 return gdbm_exists( db.dbf, key );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
515 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
516
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
517 static datum cursor = { NULL, 0 };
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
518
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
519 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
520 Db_first( const char** msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
521 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
522 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
523 if ( cursor.dptr != NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
524 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
525 free( cursor.dptr );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
526 cursor.dptr = NULL;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
527 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
528 cursor = gdbm_firstkey( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
529 *msgId = cursor.dptr;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
530 return ( cursor.dptr != NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
531 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
532
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
533 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
534 Db_next( const char** msgId )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
535 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
536 void *oldDptr = cursor.dptr;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
537
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
538 ASSERT( db.dbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
539 if ( cursor.dptr == NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
540 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
541 cursor = gdbm_nextkey( db.dbf, cursor );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
542 free( oldDptr );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
543 *msgId = cursor.dptr;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
544 return ( cursor.dptr != NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
545 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
546
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
547 Bool
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
548 Db_expire( unsigned int days )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
549 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
550 double limit;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
551 int cntDel, cntLeft, flags;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
552 time_t nowTime, lastAccess;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
553 const char *msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
554 Str name, tmpName;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
555 GDBM_FILE tmpDbf;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
556 datum key, val;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
557
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
558 if ( ! Db_open() )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
559 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
560 snprintf( name, MAXCHAR, "%s/data/articles.gdbm", Cfg_spoolDir() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
561 snprintf( tmpName, MAXCHAR, "%s/data/articles.gdbm.new", Cfg_spoolDir() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
562 flags = GDBM_NEWDB | GDBM_FAST;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
563 if ( ! ( tmpDbf = gdbm_open( tmpName, 512, flags, 0644, NULL ) ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
564 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
565 Log_err( "Error opening %s for read/write (%s)", errMsg() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
566 Db_close();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
567 return FALSE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
568 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
569 Log_inf( "Expiring articles that have not been accessed for %u days",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
570 days );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
571 limit = days * 24. * 3600.;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
572 cntDel = 0;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
573 cntLeft = 0;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
574 nowTime = time( NULL );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
575 if ( Db_first( &msgId ) )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
576 do
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
577 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
578 lastAccess = Db_lastAccess( msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
579 if ( lastAccess == -1 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
580 Log_err( "Internal error: Getting lastAccess of %s failed",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
581 msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
582 else if ( difftime( nowTime, lastAccess ) > limit )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
583 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
584 Log_dbg( "Expiring %s", msgId );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
585 ++cntDel;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
586 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
587 else
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
588 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
589 ++cntLeft;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
590 key.dptr = (void *)msgId;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
591 key.dsize = strlen( msgId ) + 1;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
592
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
593 val = gdbm_fetch( db.dbf, key );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
594 if ( val.dptr != NULL )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
595 {
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
596 if ( gdbm_store( tmpDbf, key, val, GDBM_INSERT ) != 0 )
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
597 Log_err( "Could not store %s in new database (%s)",
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
598 errMsg() );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
599 free( val.dptr );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
600 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
601 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
602 }
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
603 while ( Db_next( &msgId ) );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
604 Log_inf( "%lu articles deleted, %lu left", cntDel, cntLeft );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
605 gdbm_close( tmpDbf );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
606 Db_close();
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
607 rename( tmpName, name );
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
608 return TRUE;
04124a4423d4 [svn] Initial revision
enz
parents:
diff changeset
609 }