1 /* $Id$
2 Written 1999 by Tobias Ernst and released do the Public Domain.
3 This file is part of NLTOOLS, the nodelist processor of the Husky fidonet
4 software project.
5
6 Seek nodelist matching a mask
7 */
8 #include <stdlib.h>
9 #include <ctype.h>
10 #include <string.h>
11 #include <errno.h>
12
13 #include <huskylib/compiler.h>
14
15 #include <huskylib/dirlayer.h>
16
17 #include <fidoconf/fidoconf.h>
18 #include <huskylib/log.h>
19 #include "nlstring.h"
20 #include "julian.h"
21 #include "nlfind.h"
22 #include "nldate.h"
23
free_nlist(nlist * pnl)24 void free_nlist( nlist * pnl )
25 {
26 int i;
27
28 if( pnl )
29 {
30 for( i = 0; i < pnl->n; i++ )
31 {
32 free( pnl->matches[i] );
33 }
34 if( pnl->matches != NULL )
35 {
36 free( pnl->matches );
37 }
38 if( pnl->julians != NULL )
39 {
40 free( pnl->julians );
41 }
42 if( pnl->applied != NULL )
43 {
44 free( pnl->applied );
45 }
46 free( pnl );
47 }
48 }
49
make_nlist(void)50 static nlist *make_nlist( void )
51 {
52 nlist *res = malloc( sizeof( nlist ) );
53
54 if( res == NULL )
55 {
56 w_log( LL_CRIT, "Out of memory." );
57 return NULL;
58 }
59
60 res->n = 0;
61 res->nmax = 5;
62 res->matches = malloc( res->nmax * sizeof( char * ) );
63 res->julians = malloc( res->nmax * sizeof( long ) );
64 res->applied = malloc( res->nmax * sizeof( int ) );
65
66 if( res->matches == NULL || res->julians == NULL || res->applied == NULL )
67 {
68 w_log( LL_CRIT, "Out of memory." );
69 if( res->julians )
70 free( res->julians );
71 if( res->matches )
72 free( res->matches );
73 if( res->applied )
74 free( res->applied );
75 free( res );
76 return NULL;
77 }
78
79 return res;
80 }
81
add_match(nlist * pnl,char * match)82 int add_match( nlist * pnl, char *match )
83 {
84 char *cp = malloc( strlen( match ) + 1 );
85 char **newm;
86 int *newa;
87 long *newj;
88
89 /* w_log( 'X', "add_match()" ); */
90
91 if( cp == NULL )
92 {
93 w_log( LL_CRIT, "Out of memory." );
94 return 0;
95 }
96 if( pnl == NULL && ( pnl = make_nlist( ) ) == NULL )
97 return 0;
98
99 if( pnl->n == pnl->nmax )
100 {
101 newm = realloc( pnl->matches, ( ( pnl->nmax + 1 ) * 2 ) * sizeof( char * ) );
102 newj = realloc( pnl->julians, ( ( pnl->nmax + 1 ) * 2 ) * sizeof( long ) );
103 newa = realloc( pnl->applied, ( ( pnl->nmax + 1 ) * 2 ) * sizeof( int ) );
104
105 if( newm == NULL || newj == NULL )
106 {
107 w_log( LL_CRIT, "Out of memory." );
108 return 0;
109 }
110 pnl->matches = newm;
111 pnl->julians = newj;
112 pnl->applied = newa;
113 pnl->nmax = ( ( pnl->nmax + 1 ) * 2 );
114 }
115
116 strcpy( cp, match );
117 pnl->matches[pnl->n] = cp;
118 pnl->julians[pnl->n] = 0; /* 0 means: not yet known */
119 pnl->applied[pnl->n] = 0;
120 pnl->n++;
121 return 1;
122 }
123
find_nodelistfiles(char * path,char * base,int allowarc)124 nlist *find_nodelistfiles( char *path, char *base, int allowarc )
125 {
126 char *dfile;
127 husky_DIR *hdir;
128 nlist *pnl = make_nlist( );
129 size_t l, l2;
130
131 w_log( LL_FUNC, "find_nodelistfiles()" );
132
133 if( pnl == NULL )
134 {
135 w_log( LL_FUNC, "find_nodelistfiles() failed " );
136 return NULL;
137 }
138
139 hdir = husky_opendir( path );
140
141 if( hdir == NULL )
142 {
143 w_log( LL_ERROR, "Cannot read directory '%s': %s", path, strerror( errno ) );
144 free_nlist( pnl );
145 w_log( LL_FUNC, "find_nodelistfiles() failed " );
146 return NULL;
147 }
148
149 w_log( LL_DIR, "Scan directory %s for %s", path, base );
150
151 l = strlen( base );
152
153 while( ( dfile = husky_readdir( hdir ) ) != NULL )
154 {
155 l2 = strlen( dfile );
156 if( l2 == l + 4 &&
157 !ncasecmp( base, dfile, l ) &&
158 dfile[l] == '.' &&
159 ( allowarc || isdigit( dfile[l + 1] ) ) &&
160 isdigit( dfile[l + 2] ) && isdigit( dfile[l + 3] ) )
161 {
162 if( !add_match( pnl, dfile ) )
163 {
164 free_nlist( pnl );
165 husky_closedir( hdir );
166 w_log( LL_FUNC, "find_nodelistfiles() failed (not found)" );
167 return NULL;
168 }
169 else
170 w_log( LL_DEBUG, "Found: %s", dfile );
171
172 }
173 }
174
175 husky_closedir( hdir );
176
177 if( !pnl->n )
178 {
179 free_nlist( pnl );
180 w_log( LL_FUNC, "find_nodelistfiles() failed" );
181 return NULL;
182 }
183
184 w_log( LL_FUNC, "find_nodelistfiles() OK" );
185 return pnl;
186 }
187
findNodelist(s_fidoconfig * config,unsigned int i)188 char *findNodelist( s_fidoconfig * config, unsigned int i )
189 {
190 char *nl;
191 nlist *pnl;
192 int j;
193 long lastjul = -1, tmp;
194 int lastmatch = -1;
195 int l;
196
197 w_log( LL_FUNC, "findNodelist()" );
198
199 pnl = find_nodelistfiles( config->nodelistDir, config->nodelists[i].nodelistName, 0 );
200
201 if( pnl == NULL )
202 {
203 w_log( LL_FUNC, "findNodelist() failed (not found)" );
204 return NULL;
205 }
206 nl = malloc( ( l = strlen( config->nodelistDir ) ) +
207 strlen( config->nodelists[i].nodelistName ) + 5 );
208
209 if( nl == NULL )
210 {
211 w_log( LL_CRIT, "Out of memory." );
212 free_nlist( pnl );
213 w_log( LL_FUNC, "findNodelist() failed" );
214 return NULL;
215 }
216
217 memcpy( nl, config->nodelistDir, l );
218
219 for( j = 0; j < pnl->n; j++ )
220 {
221 strcpy( nl + l, pnl->matches[j] );
222
223 tmp = parse_nodelist_date( nl );
224
225 if( tmp > lastjul )
226 {
227 lastjul = tmp;
228 lastmatch = j;
229 }
230 }
231
232 if( lastmatch == -1 )
233 {
234 free_nlist( pnl );
235 free( nl );
236 w_log( LL_FUNC, "findNodelist() failed (don't match)" );
237 return NULL;
238 }
239
240 strcpy( nl + l, pnl->matches[lastmatch] );
241
242 free_nlist( pnl );
243 w_log( LL_FUNC, "findNodelist() OK" );
244 return nl;
245 }
246