1 /******************************************************************************
2 * HTICK --- FTN Ticker / Request Processor
3 ******************************************************************************
4 * clean.c : htick cleaning functionality
5 *
6 * Copyright (C) 2002 by
7 *
8 * Max Chernogor
9 *
10 * Fido: 2:464/108@fidonet
11 * Internet: <mihz@mail.ru>,<mihz@ua.fm>
12 *
13 * This file is part of HTICK
14 *
15 * This is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published
17 * by the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * HTICK is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with HTICK; see the file COPYING. If not, write to the Free Software
27 * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA
28 *
29 * See also http://www.gnu.org
30 *****************************************************************************
31 * $Id$
32 */
33
34 /* Functions call tree.
35
36 Purge()
37 +--- cleanPassthroughDir() +--- addFileToTree()
38 |
39 +--- purgeFileEchos()
40 |
41 +--- purgeOldTics()
42 */
43
44 #include <stdlib.h>
45 #include <string.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48
49
50 #include <huskylib/huskylib.h>
51
52 #include <huskylib/log.h>
53 #include <huskylib/xstr.h>
54 #include <fidoconf/common.h>
55 #include <huskylib/dirlayer.h>
56 #include <huskylib/tree.h>
57 #include <areafix/areafix.h>
58
59 #include "toss.h"
60 #include "htick.h"
61 #include "global.h"
62 #include "fcommon.h"
63
64
65 static tree *fileTree = NULL;
66
htick_compareEntries(char * p_e1,char * p_e2)67 int htick_compareEntries( char *p_e1, char *p_e2 )
68 {
69 if( p_e1 && p_e2 )
70 return stricmp( p_e1, p_e2 );
71
72 w_log( LL_CRIT,
73 __FILE__
74 ":: Parameter is NULL: htick_compareEntries(%s,%s). This is serious error in program, please report to developers.",
75 p_e1 ? "p_e1" : "NULL", p_e2 ? "p_e2" : "NULL" );
76 return -1;
77 }
78
htick_deleteEntry(char * p_e1)79 int htick_deleteEntry( char *p_e1 )
80 {
81 nfree( p_e1 );
82 return 1;
83 }
84
addFileToTree(char * dir,char * filename)85 void addFileToTree( char *dir, char *filename )
86 {
87 s_ticfile tic;
88
89 if( !dir || !filename )
90 {
91 w_log( LL_CRIT,
92 __FILE__
93 ":: Parameter is NULL: addFileToTree(%s,%s). This is serious error in program, please report to developers.",
94 dir ? "dir" : "NULL", filename ? "filename" : "NULL" );
95 return;
96 }
97
98 if( patimat( filename, "*.TIC" ) == 1 )
99 {
100 char *ticfile = NULL;
101 e_parseTic_result ticres;
102
103 xstrscat( &ticfile, dir, filename, NULL );
104 ticres = parseTic( ticfile, &tic );
105 if( ( ticres == parseTic_success ) && ( tic.file ) )
106 {
107 tree_add( &fileTree, htick_compareEntries, sstrdup( tic.file ), htick_deleteEntry );
108 }
109 if( ticres != parseTic_error )
110 disposeTic( &tic );
111 nfree( ticfile );
112 }
113 }
114
cleanPassthroughDir(void)115 void cleanPassthroughDir( void )
116 {
117 husky_DIR *dir;
118 char *filename;
119 char *ticfile = NULL;
120
121 w_log( LL_FUNC, "cleanPassthroughDir(): begin" );
122
123 tree_init( &fileTree, 1 );
124
125 /* check busyFileDir */
126 if( direxist( config->busyFileDir ) )
127 {
128 dir = husky_opendir( config->busyFileDir );
129 if( dir != NULL )
130 {
131 while( ( filename = husky_readdir( dir ) ) != NULL )
132 {
133 addFileToTree( config->busyFileDir, filename );
134 }
135 husky_closedir( dir );
136 }
137 }
138 /* check separateBundles dirs (does anybody use this?) */
139 if( config->separateBundles )
140 {
141 UINT i;
142 char tmpdir[256];
143 int pcnt;
144 hs_addr *aka;
145
146 for( i = 0; i < config->linkCount; i++ )
147 {
148 if( config->links[i]->hisPackAka.zone != 0 )
149 pcnt = 0;
150 else
151 pcnt = 1;
152 aka = &( config->links[i]->hisAka );
153 do
154 {
155 if( createOutboundFileNameAka( config->links[i], flNormal, FLOFILE, aka ) == 0 )
156 {
157 strcpy( tmpdir, config->links[i]->floFile );
158 sprintf( strrchr( tmpdir, '.' ), ".sep" );
159 if( direxist( tmpdir ) )
160 {
161 sprintf( tmpdir + strlen( tmpdir ), "%c", PATH_DELIM );
162 dir = husky_opendir( tmpdir );
163 if( dir == NULL )
164 continue;
165
166 while( ( filename = husky_readdir( dir ) ) != NULL )
167 {
168 addFileToTree( tmpdir, filename );
169 } /* while */
170 husky_closedir( dir );
171 if( config->links[i]->bsyFile )
172 {
173 remove( config->links[i]->bsyFile );
174 nfree( config->links[i]->bsyFile );
175 }
176 nfree( config->links[i]->floFile );
177 }
178 }
179 if( pcnt == 1 )
180 {
181 pcnt = 0;
182 aka = &( config->links[i]->hisPackAka );
183 }
184 } while( pcnt != 0 );
185 }
186 }
187 /* check ticOutbound */
188 dir = husky_opendir( config->ticOutbound );
189 if( dir != NULL )
190 {
191 while( ( filename = husky_readdir( dir ) ) != NULL )
192 {
193 addFileToTree( config->ticOutbound, filename );
194 }
195 husky_closedir( dir );
196 }
197 /* purge passFileAreaDir */
198 dir = husky_opendir( config->passFileAreaDir );
199 if( dir != NULL )
200 {
201 while( ( filename = husky_readdir( dir ) ) != NULL )
202 {
203 if( patimat( filename, "*.TIC" ) != 1 )
204 {
205 xstrscat( &ticfile, config->passFileAreaDir, filename, NULL );
206
207 if( direxist( ticfile ) )
208 { /* do not touch dirs */
209 nfree( ticfile );
210 continue;
211 }
212 if( !tree_srch( &fileTree, htick_compareEntries, filename ) )
213 {
214 w_log( LL_DEL, "Remove file %s from passthrough dir", ticfile );
215 remove( ticfile );
216 nfree( ticfile );
217 continue;
218 }
219 nfree( ticfile );
220 }
221 }
222 husky_closedir( dir );
223 }
224 tree_mung( &fileTree, htick_deleteEntry );
225
226 w_log( LL_FUNC, "cleanPassthroughDir(): end" );
227 }
228
purgeFileEchos()229 void purgeFileEchos( )
230 {
231 UINT i;
232 char *filename = NULL;
233 time_t tnow;
234
235 husky_DIR *dir;
236 char *file;
237 struct stat st;
238
239 w_log( LL_FUNC, "purgeFileEchos()" );
240
241 time( &tnow );
242
243 for( i = 0; i < config->fileAreaCount; i++ )
244 {
245 if( config->fileAreas[i].purge == 0 )
246 continue;
247 w_log( LL_INFO, "Cleaning %s ...", config->fileAreas[i].areaName );
248 dir = husky_opendir( config->fileAreas[i].fileName );
249 if( dir == NULL )
250 continue;
251
252 while( ( file = husky_readdir( dir ) ) != NULL )
253 {
254 if( patimat( file, "*.BBS" ) == 1 )
255 continue;
256
257 xstrscat( &filename, config->fileAreas[i].fileName, file, NULL );
258 if( direxist( filename ) )
259 { /* do not touch dirs */
260 nfree( filename );
261 continue;
262 }
263 memset( &st, 0, sizeof( st ) );
264 stat( filename, &st );
265 if( st.st_mtime + ( time_t ) ( config->fileAreas[i].purge * 86400 ) > tnow )
266 {
267 nfree( filename );
268 continue;
269 }
270 w_log( LL_INFO, "Deleting file %s that is %d days old", file,
271 ( tnow - st.st_mtime ) / 86400 );
272 removeFileMask( config->fileAreas[i].fileName, file );
273 nfree( filename );
274 }
275 husky_closedir( dir );
276 }
277
278 w_log( LL_FUNC, "purgeFileEchos(): end" );
279 }
280
purgeOldTics()281 void purgeOldTics( )
282 {
283 UINT i;
284 s_savetic *savetic;
285 char *filename = NULL;
286 time_t tnow;
287
288 husky_DIR *dir;
289 char *file;
290 struct stat st;
291
292 w_log( LL_FUNC, "purgeOldTics()" );
293
294 time( &tnow );
295
296 for( i = 0; i < config->saveTicCount; i++ )
297 {
298 savetic = &( config->saveTic[i] );
299 if( savetic->days2save == 0 )
300 {
301 continue;
302 }
303 w_log( LL_INFO, "Cleaning %s ...", savetic->pathName );
304 dir = husky_opendir( savetic->pathName );
305 if( dir == NULL )
306 {
307 continue;
308 }
309 while( ( file = husky_readdir( dir ) ) != NULL )
310 {
311 if( patimat( file, "*.TIC" ) == 0 )
312 continue;
313
314 xstrscat( &filename, savetic->pathName, file, NULL );
315 if( direxist( filename ) )
316 { /* do not touch dirs */
317 nfree( filename );
318 continue;
319 }
320 memset( &st, 0, sizeof( st ) );
321 stat( filename, &st );
322 if( st.st_mtime + ( time_t ) ( savetic->days2save * 86400 ) > tnow )
323 {
324 nfree( filename );
325 continue;
326 }
327 w_log( LL_INFO, "Deleting file %s that is %d days old", file,
328 ( tnow - st.st_mtime ) / 86400 );
329 removeFileMask( savetic->pathName, file );
330 nfree( filename );
331 }
332 husky_closedir( dir );
333 }
334 w_log( LL_FUNC, "purgeOldTics(): end" );
335 }
336
Purge(void)337 void Purge( void )
338 {
339 w_log( LL_INFO, "Clean (purging files in passthrough dir) ..." );
340 cleanPassthroughDir( );
341 w_log( LL_INFO, "Clean FileEchos" );
342 purgeFileEchos( );
343 w_log( LL_INFO, "Clean old tics in savetic dirs" );
344 purgeOldTics( );
345 }
346