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