Subversion Repositories mdb

Rev

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