1 /*
2 * binkleyforce -- unix FTN mailer project
3 *
4 * Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * $Id: u_misc.c,v 1.1.1.1 2004/09/09 09:52:39 kstepanenkov Exp $
12 */
13
14 #include "includes.h"
15 #include "confread.h"
16 #include "logger.h"
17 #include "util.h"
18
19 /*
20 * Array of mask aliases, you may add new values if you need
21 */
22 struct magfname {
23 const char *alias;
24 const char *masks;
25 } magfname[] = {
26 { "netmail", "*.pkt *.out *.cut *.hut *.dut *.iut" },
27 { "arcmail", "*.su? *.mo? *.tu? *.we? *.th? *.fr? *.sa?" },
28 { "ticfile", "*.tic" },
29 { "archive", "*.tgz *.bz2 *.zip *.rar *.arj *.lha *.ha" },
30 { NULL, NULL }
31 };
32
33 /*****************************************************************************
34 * Allocate memory, check for errors
35 *
36 * Arguments:
37 * size number of bytes to allocate
38 *
39 * Return value:
40 * Pointer to the allocated memory
41 */
xmalloc(size_t size)42 void *xmalloc(size_t size)
43 {
44 char *tmp;
45
46 if( size <= 0 )
47 {
48 bf_log("requested to allocate %ld bytes", (long)size);
49 size = 1;
50 }
51
52 if( (tmp = (char *)malloc(size)) == NULL )
53 {
54 bf_log("failed to allocate %ld bytes -> abort", (long)size);
55 abort();
56 }
57
58 return tmp;
59 }
60
61 /*****************************************************************************
62 * Change the size of allready allocated memory
63 *
64 * Arguments:
65 * buf pointer to the memory block which size we want change
66 * size new block size
67 *
68 * Return value:
69 * Pointer to the reallocated memory
70 */
xrealloc(void * buf,size_t size)71 void *xrealloc(void *buf, size_t size)
72 {
73 char *tmp;
74
75 if( size <= 0 )
76 {
77 tmp = NULL;
78 bf_log("requested to reallocate %ld bytes", (long)size);
79 if( buf ) free(buf);
80 }
81 else if( (tmp = (char*)(buf ? realloc(buf, size) : malloc(size))) == NULL )
82 {
83 bf_log("failed to reallocate %ld bytes -> abort", size);
84 abort();
85 }
86
87 return tmp;
88 }
89
90 /*****************************************************************************
91 * Make copy of memory block
92 *
93 * Arguments:
94 * buffer pointer to the memory block which we want to duplicate
95 * size memory block size
96 *
97 * Return value:
98 * Pointer to the memory block copy (must be freed)
99 */
xmemcpy(const void * buffer,size_t buflen)100 void *xmemcpy(const void *buffer, size_t buflen)
101 {
102 void *ptr = xmalloc(buflen);
103
104 memcpy(ptr, buffer, buflen);
105
106 return ptr;
107 }
108
109 /*****************************************************************************
110 * Compare string for matching to the mask. Special characters for the mask:
111 * '?' - any one chracter (except '\0');
112 * '*' - any group of chracters (including '\0');
113 * '\' - next chracter will be compared directly (including '?' and '*')
114 *
115 * Arguments:
116 * str pointer to the null-terminated string
117 * mask pointer to the null-terminated mask
118 *
119 * Return value:
120 * zero value if string matchs pattern, and non-zero if not
121 */
strcasemask(const char * str,const char * mask)122 int strcasemask(const char *str, const char *mask)
123 {
124 const char *s, *m;
125 char c;
126
127 ASSERT(str != NULL && mask != NULL);
128
129 s = str;
130 m = mask;
131
132 while( *s )
133 {
134 switch( c = *m++ ) {
135 case '\0':
136 return 1;
137
138 case '\\':
139 if( *m )
140 {
141 if( toupper(*m++) != toupper(*s++) )
142 return 1;
143 }
144 else if( *s++ == '\\' && *s == '\0' )
145 return 0;
146 else
147 return 1;
148 break;
149
150 case '?':
151 ++s;
152 break;
153
154 case '*':
155 if( *m )
156 {
157 do {
158 /* anti stack overflow */
159 while( *m == '*' ) m++;
160
161 if( *m != '\\' && *m != '?' )
162 while( *s && toupper(*s) != toupper(*m) ) ++s;
163
164 if( *s && !strcasemask(s, m) )
165 return 0;
166 } while( *s++ );
167
168 return 1;
169 }
170 return 0;
171
172 default:
173 if( toupper(c) != toupper(*s++) )
174 return 1;
175 }
176 }
177
178 return( *s != '\0' || *m != '\0' );
179 }
180
181 /*****************************************************************************
182 * Check whether masks list (e.g. "*.zip *.rar *.tic") conforms to the file
183 * name. For the masks description look string_pattern() info.
184 *
185 * Arguments:
186 * masks pointer to the null-terminated masks list
187 * str pointer to the null-terminated file name
188 *
189 * Return value:
190 * non-zero value if file name match masks, and zero if not
191 */
checkmasks(const char * masks,const char * str)192 int checkmasks(const char *masks, const char *str)
193 {
194 int i = 0, not = 0;
195 char *p = NULL;
196 char *n = NULL;
197 char *strs;
198 int yield = 1;
199
200 ASSERT(masks != NULL && str != NULL);
201
202 strs = xstrcpy(masks);
203
204 for( p = string_token(strs, &n, NULL, 1); p;
205 p = string_token(NULL, &n, NULL, 1) )
206 {
207 DEB((D_INFO, "checkmasks: checking \"%s\" in \"%s\"", str, p));
208
209 not = ( p[0] == '!' );
210
211 if( not )
212 ++p;
213
214 if( p[0] == '%' )
215 {
216 for( i = 0; magfname[i].alias; i++ )
217 if( strcasecmp(p+1, magfname[i].alias) == 0 )
218 {
219 if( !checkmasks(magfname[i].masks, str) )
220 {
221 free(strs);
222 return not;
223 }
224 else if( not )
225 yield = 0;
226
227 break;
228 }
229 }
230 else if( !strcasemask(str, p) )
231 {
232 free(strs);
233 return not;
234 }
235 else if( not )
236 yield = 0;
237 }
238
239 free(strs);
240 return yield;
241 }
242
243 /*****************************************************************************
244 * Put long integer (4 bytes) to the buffer
245 *
246 * Arguments:
247 * buffer pointer to the destination buffer
248 * val value that we want put to the buffer
249 *
250 * Return value:
251 * Pointer to the specified buffer
252 */
buffer_putlong(char * buffer,long val)253 char *buffer_putlong(char *buffer, long val)
254 {
255 buffer[0] = ( ((unsigned long) val) ) & 0xff;
256 buffer[1] = ( ((unsigned long) val) >> 8 ) & 0xff;
257 buffer[2] = ( ((unsigned long) val) >> 16 ) & 0xff;
258 buffer[3] = ( ((unsigned long) val) >> 24 ) & 0xff;
259
260 return buffer;
261 }
262
263 /*****************************************************************************
264 * Put integer (2 bytes) to the buffer
265 *
266 * Arguments:
267 * buffer pointer to the destination buffer
268 * val value that we want put to the buffer
269 *
270 * Return value:
271 * Pointer to the specified buffer
272 */
buffer_putint(char * buffer,int val)273 char *buffer_putint(char *buffer, int val)
274 {
275 buffer[0] = ( ((unsigned int) val) ) & 0xff;
276 buffer[1] = ( ((unsigned int) val) >> 8 ) & 0xff;
277
278 return buffer;
279 }
280
281 /*****************************************************************************
282 * Get long integer (4 bytes) from the buffer
283 *
284 * Arguments:
285 * buffer pointer to the buffer
286 *
287 * Return value:
288 * Extracted value
289 */
buffer_getlong(const char * buffer)290 long buffer_getlong(const char *buffer)
291 {
292 return ( (unsigned long) ((unsigned char) buffer[0]) )
293 | ( (unsigned long) ((unsigned char) buffer[1]) << 8 )
294 | ( (unsigned long) ((unsigned char) buffer[2]) << 16 )
295 | ( (unsigned long) ((unsigned char) buffer[3]) << 24 );
296 }
297
298 /*****************************************************************************
299 * Get integer (2 bytes) from the buffer
300 *
301 * Arguments:
302 * buffer pointer to the buffer
303 *
304 * Return value:
305 * Extracted value
306 */
buffer_getint(const char * buffer)307 int buffer_getint(const char *buffer)
308 {
309 return ( (unsigned int) ((unsigned char) buffer[0]) )
310 | ( (unsigned int) ((unsigned char) buffer[1]) << 8 );
311 }
312
printf_usage(const char * ident,const char * fmt,...)313 void printf_usage(const char *ident, const char *fmt, ...)
314 {
315 va_list args;
316
317 if( ident )
318 printf("%s %s %s\n\n", BF_BANNERVER, ident, BF_COPYRIGHT);
319 else
320 printf("%s %s\n\n", BF_BANNERVER, BF_COPYRIGHT);
321
322 if( fmt )
323 {
324 va_start(args, fmt);
325 vprintf(fmt, args);
326 va_end(args);
327 }
328 else
329 printf("Sorry, no usage information available\n\n");
330
331 printf("Mail bug reports to <adb@newmail.ru>\n");
332
333 fflush(stdout);
334 }
335
336 /* end of u_misc.c */
337