1 /*:ts=8*/
2 /*****************************************************************************
3 * FIDOGATE --- Gateway UNIX Mail/News <-> FTN NetMail/EchoMail
4 *
5 *
6 * MSGID history functions and dupe checking
7 *
8 *****************************************************************************
9 * Copyright (C) 1990-2001
10 * _____ _____
11 * | |___ | Martin Junius FIDO: 2:2452/110
12 * | | | | | | Radiumstr. 18 Internet: mj@fido.de
13 * |_|_|_|@home| D-51069 Koeln, Germany
14 *
15 * This file is part of FIDOGATE.
16 *
17 * FIDOGATE is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2, or (at your option) any
20 * later version.
21 *
22 * FIDOGATE is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with FIDOGATE; see the file COPYING. If not, write to the Free
29 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
30 *****************************************************************************/
31
32 #include "fidogate.h"
33 #include "dbz.h"
34
35 /*
36 * History file
37 */
38 static FILE *hi_file = NULL;
39 short int hi_init(char *);
40
41 /*
42 * Get base name
43 */
44 #if defined(DBC_HISTORY) && defined(FIDO_STYLE_MSGID)
hi_init_dbc()45 short int hi_init_dbc()
46 {
47 char db_name[MAXPATH];
48
49 BUF_EXPAND(db_name, cf_p_dbc_history());
50
51 if (hi_init(db_name) == ERROR) {
52 return ERROR;
53 }
54 return OK;
55 }
56 #endif /* DBC_HISTORY && FIDO_STYLE_MSGID */
57
58 #ifdef TIC_HISTORY
hi_init_tic_history(void)59 void hi_init_tic_history(void)
60 {
61 char db_name[MAXPATH];
62
63 BUF_EXPAND(db_name, cf_p_tic_history());
64
65 if (hi_init(db_name) == ERROR) {
66 return;
67 }
68 return;
69 }
70 #endif /* TIC_HISTORY */
71
hi_init_history(void)72 void hi_init_history(void)
73 {
74 char db_name[MAXPATH];
75
76 BUF_EXPAND(db_name, cf_p_history());
77
78 hi_init(db_name);
79 }
80
81 /*
82 * Initialize MSGID history
83 */
hi_init(char * his_file)84 short int hi_init(char *his_file)
85 {
86 FILE *fp;
87
88 /* Test for history.dir, history.pag */
89 BUF_EXPAND(buffer, his_file);
90 BUF_APPEND(buffer, ".dir");
91 if (check_access(buffer, CHECK_FILE) != TRUE) {
92 /* Doesn't exist, create */
93 if ((fp = fopen(buffer, W_MODE)) == NULL) {
94 fglog("$ERROR: creating MSGID history %s failed", buffer);
95 return ERROR;
96 } else
97 debug(9, "creating MSGID history %s", buffer);
98 }
99 BUF_EXPAND(buffer, his_file);
100 BUF_APPEND(buffer, ".pag");
101 if (check_access(buffer, CHECK_FILE) != TRUE) {
102 /* Doesn't exist, create */
103 if ((fp = fopen(buffer, W_MODE)) == NULL) {
104 fglog("$ERROR: creating MSGID history %s failed", buffer);
105 return ERROR;
106 } else
107 fglog("creating MSGID history %s", buffer);
108 }
109 /* Open the history text file */
110 BUF_EXPAND(buffer, his_file);
111 if ((hi_file = fopen(buffer, A_MODE)) == NULL) {
112 fglog("$ERROR: open MSGID history %s failed", buffer);
113 if (check_access(buffer, CHECK_FILE) == ERROR) {
114 fglog("$ERROR: Premission denied %s", buffer);
115 return ERROR;
116 }
117 }
118 /* Open the DBZ file */
119 dbzincore(1);
120 /**dbzwritethrough(1);**/
121 if (dbminit(buffer) == -1) {
122 fglog("$ERROR: dbminit %s failed", buffer);
123 return ERROR;
124 }
125 return OK;
126 }
127
128 /*
129 * Close MSGID history
130 */
hi_close(void)131 void hi_close(void)
132 {
133
134 if (hi_file) {
135 if (fclose(hi_file) == ERROR)
136 fglog("$ERROR: close MSGID history failed");
137 if (dbzsync())
138 fglog("$ERROR: dbzsync MSGID history failed");
139 if (dbmclose() < 0)
140 fglog("$ERROR: dbmclose MSGID history failed");
141
142 hi_file = NULL;
143 }
144 }
145
146 /*
147 * Write record to DBC MSGID history
148 */
149 #if defined(DBC_HISTORY) && defined(FIDO_STYLE_MSGID)
hi_write_dbc(char * rfc_msgid,char * fido_msgid,short int dont_flush)150 short int hi_write_dbc(char *rfc_msgid, char *fido_msgid, short int dont_flush)
151 {
152 long offset;
153 int ret;
154 datum key, val;
155 TIMEINFO ti;
156
157 GetTimeInfo(&ti);
158 if (hi_file) {
159 /* Get offset in history text file */
160 if ((offset = ftell(hi_file)) == ERROR) {
161 fglog("$ERROR: ftell DBC MSGID history failed");
162 return ERROR;
163 }
164 } else {
165 fglog("$ERROR: can't open MSGID history file");
166 return ERROR;
167 }
168
169 /* Write MSGID line to history text file */
170 if (strchr(fido_msgid, ' '))
171 fido_msgid = strrchr(fido_msgid, ' ') + 1;
172 debug(7, "dbc history: offset=%ld: %s %s %ld", offset, fido_msgid,
173 rfc_msgid, (long)ti.time);
174 ret =
175 fprintf(hi_file, "%s\t%s\t%ld\n", fido_msgid, rfc_msgid, (long)ti.time);
176 if (ret == ERROR || (!dont_flush && fflush(hi_file) == ERROR)) {
177 fglog("$ERROR: write to DBC MSGID history failed");
178 return ERROR;
179 }
180
181 /* Write database record */
182 key.dptr = fido_msgid; /* Key */
183 key.dsize = strlen(fido_msgid) + 1;
184 val.dptr = (char *)&offset; /* Value */
185 val.dsize = sizeof offset;
186 if (dbzstore(key, val) < 0) {
187 fglog("ERROR: dbzstore of record for DBC MSGID history failed");
188 return ERROR;
189 }
190
191 /**FIXME: dbzsync() every n msgids */
192
193 return OK;
194 }
195 #endif /* DBC_HISTORY && FIDO_STYLE_MSGID */
196
197 /*
198 * Write record to MSGID history
199 */
hi_write_t(time_t t,time_t msgdate,char * msgid)200 short int hi_write_t(time_t t, time_t msgdate, char *msgid)
201 {
202 long offset;
203 int ret;
204 datum key, val;
205
206 if (hi_file) {
207 /* Get offset in history text file */
208 if ((offset = ftell(hi_file)) == ERROR) {
209 fglog("$ERROR: ftell MSGID history failed");
210 return ERROR;
211 }
212 } else {
213 fglog("$ERROR: can't open MSGID history file");
214 return ERROR;
215 }
216
217 /* Write MSGID line to history text file */
218 debug(7, "history: offset=%ld: %s %ld", offset, msgid, (long)t);
219 ret = fprintf(hi_file, "%s\t%ld\n", msgid, (long)t);
220 if (ret == ERROR || fflush(hi_file) == ERROR) {
221 fglog("$ERROR: write to MSGID history failed");
222 return ERROR;
223 }
224
225 /* Write database record */
226 key.dptr = msgid; /* Key */
227 key.dsize = strlen(msgid) + 1;
228 val.dptr = (char *)&offset; /* Value */
229 val.dsize = sizeof offset;
230 if (dbzstore(key, val) < 0) {
231 fglog("ERROR: dbzstore of record for MSGID history failed");
232 return ERROR;
233 }
234
235 /**FIXME: dbzsync() every n msgids */
236
237 return OK;
238 }
239
hi_write(time_t msgdate,char * msgid)240 short int hi_write(time_t msgdate, char *msgid)
241 /* msgdate currently not used */
242 {
243 TIMEINFO ti;
244
245 GetTimeInfo(&ti);
246
247 return hi_write_t(ti.time, msgdate, msgid);
248 }
249
250 /*
251 * Write record to DB
252 */
hi_write_avail(char * area,char * desc)253 short int hi_write_avail(char *area, char *desc)
254 {
255 long offset;
256 int ret;
257 datum key, val;
258
259 if (hi_file) {
260 /* Get offset in history text file */
261 if ((offset = ftell(hi_file)) == ERROR) {
262 fglog("$ERROR: ftell MSGID history failed");
263 return ERROR;
264 }
265 } else {
266 fglog("$ERROR: can't open MSGID history file");
267 return ERROR;
268 }
269
270 /* Write MSGID line to history text file */
271 debug(7, "history: offset=%ld: %s %s", offset, area, desc);
272 ret = fprintf(hi_file, "%s\t%s\n", area, desc);
273 if (ret == ERROR || fflush(hi_file) == ERROR) {
274 fglog("$ERROR: write to MSGID history failed");
275 return ERROR;
276 }
277
278 /* Write database record */
279 key.dptr = area; /* Key */
280 key.dsize = strlen(area) + 1;
281 val.dptr = (char *)&offset; /* Value */
282 val.dsize = sizeof offset;
283 if (dbzstore(key, val) < 0) {
284 fglog("ERROR: dbzstore of record for MSGID history failed");
285 return ERROR;
286 }
287
288 /**FIXME: dbzsync() every n msgids */
289
290 return OK;
291 }
292
293 /*
294 * Test if MSGID is already in database
295 */
hi_test(char * key_string)296 short int hi_test(char *key_string)
297 {
298 datum key, val;
299
300 key.dptr = key_string; /* Key */
301 key.dsize = strlen(key_string) + 1;
302 val = dbzfetch(key);
303 #ifdef DEBUG
304 debug(1, "hi_test() key = %s, returned %s", key_string, val.dptr);
305 #endif
306 return val.dptr != NULL;
307 }
308
309 /*
310 * Test if DB key is already in database
311 */
hi_fetch(char * key_string,int flag)312 char *hi_fetch(char *key_string, int flag)
313 {
314 datum key, val;
315 static char out[MAXPATH];
316
317 if (flag == 0)
318 key_string = strchr(key_string, ' ') + 1;
319 debug(7, "search key %s", key_string);
320 key.dptr = key_string; /* Key */
321 key.dsize = strlen(key_string) + 1;
322 val = dbcfetch(key);
323 if (val.dptr) {
324 BUF_COPY(out, xstrtok(val.dptr, " \t"));
325 debug(7, "found: %s", out);
326 return out;
327 } else {
328 debug(7, "not found");
329 return NULL;
330 }
331 }
332