Subversion Repositories mdb

Rev

Rev 30 | Rev 49 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 andreas 1
/*
2
 * Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
3
 *
4
 * All rights reserved. No warranty, explicit or implicit, provided.
5
 *
6
 * NOTICE:  All information contained herein is, and remains
7
 * the property of Andreas Theofilu and his suppliers, if any.
8
 * The intellectual and technical concepts contained
9
 * herein are proprietary to Andreas Theofilu and its suppliers and
10
 * may be covered by European and Foreign Patents, patents in process,
11
 * and are protected by trade secret or copyright law.
12
 * Dissemination of this information or reproduction of this material
13
 * is strictly forbidden unless prior written permission is obtained
14
 * from Andreas Theofilu.
15
 */
16
#include <stdio.h>
17
#include <string.h>
18
#include <unistd.h>
19
#include <stdlib.h>
20
#include <syslog.h>
21
#include <errno.h>
4 andreas 22
#include <ctype.h>
5 andreas 23
#include <iconv.h>
2 andreas 24
#include "helplib.h"
22 andreas 25
#include "lookup3.h"
2 andreas 26
 
5 andreas 27
iconv_t initialize (void);
28
char *conv2utf8 (iconv_t conv_desc, const char *euc);
29
void finalize (iconv_t conv_desc);
30
 
4 andreas 31
char *urlencode(char *str)
32
{
33
	char *p, *buf;
34
	unsigned int size;
35
 
36
	if (str == NULL || strlen(str) == 0)
37
		return NULL;
38
 
5 andreas 39
	/* calculate the number of characters to replace */
4 andreas 40
	size = strlen(str);
5 andreas 41
	p = str;
4 andreas 42
 
5 andreas 43
	while (*p)
44
	{
45
		if (isblank(*p) || !isalnum(*p))
46
			size += 3;
47
 
48
		p++;
49
	}
50
 
4 andreas 51
	if ((buf = (char *)malloc(size)) == NULL)
52
	{
5 andreas 53
		syslog(LOG_DAEMON, "Error allocating %d bytes of memory for URL encoding!", size);
4 andreas 54
		return NULL;
55
	}
56
 
57
	memset(buf, 0, size);
58
	p = str;
59
 
5 andreas 60
	while (*p)
4 andreas 61
	{
62
		if (isblank(*p))
63
			strcat(buf, "%20");
64
		else if (!isalnum(*p))
65
		{
66
			char hv0[32];
5 andreas 67
 
14 andreas 68
			sprintf(hv0, "%%%02X", (int)*p & 0x000000ff);
4 andreas 69
			strcat(buf, hv0);
70
		}
5 andreas 71
		else
72
		{
73
			int pos;
4 andreas 74
 
5 andreas 75
			pos = strlen(buf);
76
			*(buf+pos) = *p;
77
			*(buf+pos+1) = 0;
78
		}
79
 
4 andreas 80
		p++;
81
	}
82
 
83
	return buf;
84
}
85
 
86
char *urldecode(char *str)
87
{
88
	char *buf, *p, *pb;
89
	int i;
90
 
91
	if (str == NULL || strlen(str) == 0)
92
		return NULL;
93
 
94
	if ((buf = strdup(str)) == NULL)
95
	{
96
		syslog(LOG_DAEMON, "Error allocating memory for URL decode!");
97
		return NULL;
98
	}
99
 
100
	memset(buf, 0, strlen(str));
101
	p = str;
102
	pb = buf;
103
 
104
	for (i = 0; i < (int)strlen(str); i++)
105
	{
106
		if (*p == '%' && isdigit(*(p+1)))
107
		{
108
			char hv0[8];
109
 
110
			p++;
111
			strncpy(hv0, p, 2);
112
			hv0[2] = 0;
12 andreas 113
			*pb = (char)strtol(hv0, NULL, 16);
4 andreas 114
			p++;
115
		}
116
		else
117
			*pb = *p;
118
 
119
		pb++;
120
		p++;
121
	}
122
 
123
	return buf;
124
}
125
 
5 andreas 126
char *ASCIItoUTF8(char *str)
127
{
128
	char *out_string;
129
	iconv_t conv_desc;
130
 
131
	if ((conv_desc = initialize()) == (iconv_t)-1)
132
		return NULL;
133
 
134
	out_string = conv2utf8 (conv_desc, str);
135
	finalize(conv_desc);
136
	return out_string;
137
}
138
 
139
/* Initialize the library. */
140
 
141
iconv_t initialize (void)
142
{
143
	iconv_t conv_desc;
144
	char *toCode = "UTF8";
145
	char *fromCode = "ISO-8859-1";
146
 
147
	conv_desc = iconv_open (toCode, fromCode);
148
 
149
	if (conv_desc == (iconv_t)-1)
150
	{
151
		/* Initialization failure. */
152
		if (errno == EINVAL)
153
			syslog(LOG_WARNING, "Conversion from '%s' to '%s' is not supported.", fromCode, toCode);
154
		else
155
			syslog(LOG_WARNING, "Initialization failure: %s", strerror (errno));
156
	}
157
 
158
	return conv_desc;
159
}
160
 
161
 
162
/* Convert ASCII into UTF-8 using the iconv library. */
163
 
164
char *conv2utf8 (iconv_t conv_desc, const char *euc)
165
{
166
	size_t iconv_value;
167
	char *utf8;
168
	size_t len;
169
	size_t utf8len;
170
	/* The variables with "start" in their name are solely for display
171
	 *       of what the function is doing. As iconv runs, it alters the
172
	 *       values of the variables, so these are for keeping track of the
173
	 *       start points and start lengths.
174
	 */
175
	char *utf8start;
176
	const char *euc_start;
177
	int len_start;
178
	int utf8len_start;
179
 
180
	len = strlen (euc);
181
 
182
	if (!len)
183
		return NULL;
184
 
185
	/* Assign enough space to put the UTF-8. */
186
	utf8len = 2 * len;
187
	utf8 = calloc(utf8len, 1);
188
	/* Keep track of the variables. */
189
	len_start = len;
190
	utf8len_start = utf8len;
191
	utf8start = utf8;
192
	euc_start = euc;
193
	iconv_value = iconv (conv_desc, (char **)&euc, &len, &utf8, &utf8len);
194
	/* Handle failures. */
195
	if (iconv_value == (size_t)-1)
196
	{
8 andreas 197
		syslog(LOG_WARNING, "iconv failed: in string '%s', length %d, out string '%s', length %d: %s", euc, (int)len, utf8start, (int)utf8len, strerror(errno));
5 andreas 198
		return NULL;
199
	}
200
 
201
	return utf8start;
202
}
203
 
204
/* Close the connection with the library. */
205
 
206
void finalize (iconv_t conv_desc)
207
{
208
	int v;
209
 
210
	v = iconv_close (conv_desc);
211
 
212
	if (v != 0)
213
		syslog (LOG_WARNING, "iconv_close failed: %s", strerror (errno));
214
}
215
 
7 andreas 216
char *secondsToString(double seconds, char *buf)
217
{
218
	int hour, min, sec, flag;
219
 
220
	if (buf == NULL)
221
		return NULL;
222
 
223
	hour = min = sec = flag = 0;
224
	min = (int)(seconds / 60.0);
225
 
226
	if (min > 60)
227
	{
228
		flag = 1;
229
		hour = (int)(seconds / (60.0 * 60.0));
230
		min = (int)((seconds - ((double)hour * 60.0 * 60.0)) / 60.0);
231
		sec = (int)(seconds - (((double)hour * 60.0 * 60.0) + ((double)min * 60.0)));
232
	}
233
	else
234
		sec = (int)(seconds - (double)min * 60.0);
235
 
236
	if (flag)
237
		sprintf(buf, "%02d%%3A%02d%%3A%02d", hour, min, sec);
238
	else
239
		sprintf(buf, "%02d%%3A%02d", min, sec);
240
 
241
	return buf;
242
}
243
 
5 andreas 244
/*
245
 * Search and replace a string with another string , in a string
246
 */
247
char *str_replace(char *in, char *pattern, char *by)
248
{
249
	size_t outsize;
250
	char *res;
251
	size_t resoffset = 0;
252
	char *needle, *oriptr, *patloc;
14 andreas 253
	int patcnt;
5 andreas 254
 
255
	if (in == NULL || pattern == NULL || by == NULL)
256
		return NULL;
257
 
258
	if (strlen(in) == 0 || strlen(pattern) == 0)
259
		return NULL;
260
 
261
	/* calculate outsize */
262
	patcnt = 0;
263
 
14 andreas 264
	for (oriptr = in; (patloc = strstr(oriptr, pattern)) != NULL; oriptr = patloc + strlen(pattern))
5 andreas 265
		patcnt++;
266
 
267
	outsize = strlen(in) + patcnt * (strlen(by) - strlen(pattern));
268
 
269
	if ((res = malloc(outsize)) == NULL)
270
	{
8 andreas 271
		syslog(LOG_WARNING, "Error allocating %d bytes of memory for string replace!", (int)outsize);
5 andreas 272
		return NULL;
273
	}
274
 
14 andreas 275
	while ((needle = strstr(in, pattern)) != NULL)
5 andreas 276
	{
277
		/* copy everything up to the pattern */
278
		memcpy(res + resoffset, in, needle - in);
279
		resoffset += needle - in;
280
 
281
		/* skip the pattern in the input-string */
282
		in = needle + strlen(pattern);
283
 
284
		/* adjust space for replacement */
285
		outsize = outsize - strlen(pattern) + strlen(by);
286
		res = realloc(res, outsize);
287
 
288
		/* copy the pattern */
289
		memcpy(res + resoffset, by, strlen(by));
290
		resoffset += strlen(by);
291
	}
292
 
293
    /* copy the remaining input */
294
	strcpy(res + resoffset, in);
295
	return res;
296
}
297
 
298
char *char_replace(char *in, char needle, char by)
299
{
300
	char *p;
301
 
302
	if (in == NULL || strlen(in) == 0)
303
		return NULL;
304
 
305
	p = in;
306
 
307
	while (*p)
308
	{
309
		if (*p == needle)
310
			*p = by;
311
 
312
		p++;
313
	}
314
 
315
	return in;
316
}
317
 
2 andreas 318
char *readLine(int fd, char *buf, int bufLen)
319
{
320
	int i, end;
321
	char ch, *p;
7 andreas 322
 
2 andreas 323
	if (fd <= 0)
324
	{
325
		syslog(LOG_DAEMON,"Function readLine was called with an invalid file descriptor of %d!", fd);
326
		return NULL;
327
	}
7 andreas 328
 
2 andreas 329
	i = end = 0;
330
	p = buf;
7 andreas 331
 
2 andreas 332
	while (read(fd, &ch, 1) > 0)
333
	{
334
		end = 1;
7 andreas 335
 
2 andreas 336
		if (ch == 0x0a)
337
		{
338
			*p = 0;
339
			return buf;
340
		}
7 andreas 341
 
4 andreas 342
		if (ch == 0x0d)      /* ignore this! */
2 andreas 343
			continue;
7 andreas 344
 
2 andreas 345
		if (i < (bufLen - 1))
346
		{
347
			*p = ch;
348
			p++;
349
			i++;
350
		}
351
	}
7 andreas 352
 
2 andreas 353
	*p = 0;
7 andreas 354
 
2 andreas 355
	if (end)
356
		return buf;
357
	else
358
		return NULL;
359
}
360
 
361
char *trim(char *str)
362
{
363
	char *p1, *p2, *p;
364
 
365
	if (!str)
366
		return NULL;
367
 
368
	if (!strlen(str))
369
		return str;
370
 
371
	p = str;
372
	p1 = p2 = NULL;
373
 
374
	while (*p)
375
	{
376
		if (!p1 && *p != ' ')
377
		{
378
			p1 = p;
379
			break;
380
		}
381
 
382
		p++;
383
	}
384
 
385
	p2 = str + (strlen(str) - 1);
386
 
387
	while (p2 > str && *p2 == ' ')
388
		p2--;
389
 
390
	if (p2)
391
		*(p2+1) = 0;
392
 
393
	if (p1)
394
	{
395
		char *buf = strdup (p1);
396
		strcpy (str, buf);
397
		free (buf);
398
	}
399
 
400
	return str;
401
}
402
 
403
char *remove_string(char *str, char *search, char *ret)
404
{
405
	char *p;
406
 
407
	if (!strlen(str) || !strlen(search))
408
		return NULL;
409
 
410
	if ((p = strstr(str, search)) != NULL)
411
	{
412
		int len = strlen(search);
413
 
414
		strncpy(ret, str, p - str + len);
415
		ret[p - str + len] = 0;
416
		memmove(str, p + len, strlen(p+len));
417
		str[strlen(p+len)] = 0;
418
		return ret;
419
	}
420
 
421
	return NULL;
422
}
6 andreas 423
 
30 andreas 424
char *strsplitt(char *str, char tok)
425
{
426
	static char *start, *end;
427
 
428
	if (str != NULL)
429
	{
430
		start = str;
431
		end = NULL;
432
	}
433
	else if (end)
434
		end = NULL;
435
	else
436
		return NULL;
437
 
438
	if ((end = strchr(start, tok)) != NULL)
439
	{
440
		char *p;
441
 
442
		*end = 0;
443
		p = start;
444
		start = end + 1;
445
		return p;
446
	}
447
	else
448
	{
449
		char *p;
450
 
451
		p = start;
452
		start = NULL;
453
		end = NULL;
454
		return p;
455
	}
456
 
457
	return NULL;
458
}
459
 
6 andreas 460
int isnumeric(char *str)
461
{
462
	char *p;
463
 
464
	if (str == NULL)
465
		return FALSE;
466
 
467
	p = str;
468
 
469
	while (*p)
470
	{
471
		if (!isdigit(*p))
472
			return FALSE;
473
 
474
		p++;
475
	}
476
 
477
	return TRUE;
478
}
11 andreas 479
 
480
/*
481
 * Assumes 0 <= max <= RAND_MAX
482
 * Returns in the half-open interval [0, max]
483
 */
484
long random_at_most (long max)
485
{
486
	unsigned long num_bins, num_rand, bin_size, defect;
487
	long x;
488
	/* max <= RAND_MAX < ULONG_MAX, so this is okay. */
489
	num_bins = (unsigned long) max + 1,
490
	num_rand = (unsigned long) RAND_MAX + 1,
491
	bin_size = num_rand / num_bins,
492
	defect   = num_rand % num_bins;
493
 
494
	do
495
	{
496
		x = random();
497
	}
498
	while (num_rand - defect <= (unsigned long)x);	/* This is carefully written not to overflow */
499
 
500
	/* Truncated division is intentional */
501
	return x / bin_size;
502
}
14 andreas 503
 
22 andreas 504
char *str2hash(const char *str, int length)
14 andreas 505
{
22 andreas 506
	uint32_t a, b;
507
	char *out, digest1[9], digest2[9];
14 andreas 508
 
22 andreas 509
	if ((out = (char *)malloc(17)) == NULL)
14 andreas 510
	{
511
		syslog(LOG_DAEMON, "Error allocating 33 Bytes for MD5 calculation: %s", strerror(errno));
512
		return NULL;
513
	}
514
 
22 andreas 515
	memset(out, 0, 17);
516
	a = 0x2e96a73d; b = 0x130f36db;			/* Individual seeds to be able to reproduse the hashes */
517
	hashlittle2(str, length, &a, &b);
518
	sprintf(out, "%.8lx%.8lx", a, b);
14 andreas 519
 
520
	return out;
521
}
32 andreas 522
 
523
char *getFileExtension(const char *file)
524
{
525
char *ret, *p1, *p2;
526
 
527
	if ((p1 = strrchr(file, '.')) == NULL)
528
		return NULL;
529
 
530
	if (strrchr(p1, '/') != NULL)
531
		return NULL;
532
 
533
	ret = p1 + 1;
534
	return ret;
535
}