Rev 59 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*
* Copyright (C) 2015 by Andreas Theofilu <andreas@theosys.at>
*
* All rights reserved. No warranty, explicit or implicit, provided.
*
* NOTICE: All information contained herein is, and remains
* the property of Andreas Theofilu and his suppliers, if any.
* The intellectual and technical concepts contained
* herein are proprietary to Andreas Theofilu and its suppliers and
* may be covered by European and Foreign Patents, patents in process,
* and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Andreas Theofilu.
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <syslog.h>
#include <errno.h>
#include <ctype.h>
#include <iconv.h>
#include <pthread.h>
#include "helplib.h"
#include "lookup3.h"
iconv_t initialize (void);
char *conv2utf8 (iconv_t conv_desc, const char *euc);
void finalize (iconv_t conv_desc);
static pthread_t pthr_wait;
char *urlencode(char *str)
{
char *p, *buf;
unsigned int size;
if (str == NULL || strlen(str) == 0)
return NULL;
/* calculate the number of characters to replace */
size = strlen(str);
p = str;
while (*p)
{
if (isblank(*p) || !isalnum(*p))
size += 3;
p++;
}
if ((buf = (char *)malloc(size)) == NULL)
{
syslog(LOG_DAEMON, "Error allocating %d bytes of memory for URL encoding!", size);
return NULL;
}
memset(buf, 0, size);
p = str;
while (*p)
{
if (isblank(*p))
strcat(buf, "%20");
else if (!isalnum(*p))
{
char hv0[32];
sprintf(hv0, "%%%02X", (int)*p & 0x000000ff);
strcat(buf, hv0);
}
else
{
int pos;
pos = strlen(buf);
*(buf+pos) = *p;
*(buf+pos+1) = 0;
}
p++;
}
return buf;
}
char *urldecode(char *str)
{
char *buf, *p, *pb;
int i;
if (str == NULL || strlen(str) == 0)
return NULL;
if ((buf = strdup(str)) == NULL)
{
syslog(LOG_DAEMON, "Error allocating memory for URL decode!");
return NULL;
}
memset(buf, 0, strlen(str));
p = str;
pb = buf;
for (i = 0; i < (int)strlen(str); i++)
{
if (*p == '%' && isdigit(*(p+1)))
{
char hv0[8];
p++;
strncpy(hv0, p, 2);
hv0[2] = 0;
*pb = (char)strtol(hv0, NULL, 16);
p++;
}
else
*pb = *p;
pb++;
p++;
}
return buf;
}
char *ASCIItoUTF8(char *str)
{
char *out_string;
iconv_t conv_desc;
if ((conv_desc = initialize()) == (iconv_t)-1)
return NULL;
out_string = conv2utf8 (conv_desc, str);
finalize(conv_desc);
return out_string;
}
/* Initialize the library. */
iconv_t initialize (void)
{
iconv_t conv_desc;
char *toCode = "UTF8";
char *fromCode = "ISO-8859-1";
conv_desc = iconv_open (toCode, fromCode);
if (conv_desc == (iconv_t)-1)
{
/* Initialization failure. */
if (errno == EINVAL)
syslog(LOG_WARNING, "Conversion from '%s' to '%s' is not supported.", fromCode, toCode);
else
syslog(LOG_WARNING, "Initialization failure: %s", strerror (errno));
}
return conv_desc;
}
/* Convert ASCII into UTF-8 using the iconv library. */
char *conv2utf8 (iconv_t conv_desc, const char *euc)
{
size_t iconv_value;
char *utf8;
size_t len;
size_t utf8len;
/* The variables with "start" in their name are solely for display
* of what the function is doing. As iconv runs, it alters the
* values of the variables, so these are for keeping track of the
* start points and start lengths.
*/
char *utf8start;
const char *euc_start;
int len_start;
int utf8len_start;
len = strlen (euc);
if (!len)
return NULL;
/* Assign enough space to put the UTF-8. */
utf8len = 2 * len;
utf8 = calloc(utf8len, 1);
/* Keep track of the variables. */
len_start = len;
utf8len_start = utf8len;
utf8start = utf8;
euc_start = euc;
iconv_value = iconv (conv_desc, (char **)&euc, &len, &utf8, &utf8len);
/* Handle failures. */
if (iconv_value == (size_t)-1)
{
syslog(LOG_WARNING, "iconv failed: in string '%s', length %d, out string '%s', length %d: %s", euc, (int)len, utf8start, (int)utf8len, strerror(errno));
return NULL;
}
return utf8start;
}
/* Close the connection with the library. */
void finalize (iconv_t conv_desc)
{
int v;
v = iconv_close (conv_desc);
if (v != 0)
syslog (LOG_WARNING, "iconv_close failed: %s", strerror (errno));
}
char *secondsToString(double seconds, char *buf)
{
int hour, min, sec, flag;
if (buf == NULL)
return NULL;
hour = min = sec = flag = 0;
min = (int)(seconds / 60.0);
if (min > 60)
{
flag = 1;
hour = (int)(seconds / (60.0 * 60.0));
min = (int)((seconds - ((double)hour * 60.0 * 60.0)) / 60.0);
sec = (int)(seconds - (((double)hour * 60.0 * 60.0) + ((double)min * 60.0)));
}
else
sec = (int)(seconds - (double)min * 60.0);
if (flag)
sprintf(buf, "%02d%%3A%02d%%3A%02d", hour, min, sec);
else
sprintf(buf, "%02d%%3A%02d", min, sec);
return buf;
}
/*
* Search and replace a string with another string , in a string
*/
char *str_replace(char *in, char *pattern, char *by)
{
size_t outsize;
char *res;
size_t resoffset = 0;
char *needle, *oriptr, *patloc;
int patcnt;
if (in == NULL || pattern == NULL || by == NULL)
return NULL;
if (strlen(in) == 0 || strlen(pattern) == 0)
return NULL;
/* calculate outsize */
patcnt = 0;
for (oriptr = in; (patloc = strstr(oriptr, pattern)) != NULL; oriptr = patloc + strlen(pattern))
patcnt++;
outsize = strlen(in) + patcnt * (strlen(by) - strlen(pattern));
if ((res = malloc(outsize)) == NULL)
{
syslog(LOG_WARNING, "Error allocating %d bytes of memory for string replace!", (int)outsize);
return NULL;
}
while ((needle = strstr(in, pattern)) != NULL)
{
/* copy everything up to the pattern */
memcpy(res + resoffset, in, needle - in);
resoffset += needle - in;
/* skip the pattern in the input-string */
in = needle + strlen(pattern);
/* adjust space for replacement */
outsize = outsize - strlen(pattern) + strlen(by);
res = realloc(res, outsize);
/* copy the pattern */
memcpy(res + resoffset, by, strlen(by));
resoffset += strlen(by);
}
/* copy the remaining input */
strcpy(res + resoffset, in);
return res;
}
char *char_replace(char *in, char needle, char by)
{
char *p;
if (in == NULL || strlen(in) == 0)
return NULL;
p = in;
while (*p)
{
if (*p == needle)
*p = by;
p++;
}
return in;
}
char *readLine(int fd, char *buf, int bufLen)
{
int i, end;
char ch, *p;
if (fd <= 0)
{
syslog(LOG_DAEMON,"Function readLine was called with an invalid file descriptor of %d!", fd);
return NULL;
}
i = end = 0;
p = buf;
while (read(fd, &ch, 1) > 0)
{
end = 1;
if (ch == 0x0a)
{
*p = 0;
return buf;
}
if (ch == 0x0d) /* ignore this! */
continue;
if (i < (bufLen - 1))
{
*p = ch;
p++;
i++;
}
}
*p = 0;
if (end)
return buf;
else
return NULL;
}
char *trim(char *str)
{
char *p1, *p2, *p;
if (!str)
return NULL;
if (!strlen(str))
return str;
p = str;
p1 = p2 = NULL;
while (*p)
{
if (!p1 && *p != ' ')
{
p1 = p;
break;
}
p++;
}
p2 = str + (strlen(str) - 1);
while (p2 > str && *p2 == ' ')
p2--;
if (p2)
*(p2+1) = 0;
if (p1)
{
char *buf = strdup (p1);
strcpy (str, buf);
free (buf);
}
return str;
}
char *remove_string(char *str, char *search, char *ret)
{
char *p;
if (!strlen(str) || !strlen(search))
return NULL;
if ((p = strstr(str, search)) != NULL)
{
int len = strlen(search);
strncpy(ret, str, p - str + len);
ret[p - str + len] = 0;
memmove(str, p + len, strlen(p+len));
str[strlen(p+len)] = 0;
return ret;
}
return NULL;
}
char *strsplitt(char *str, char tok)
{
static char *start, *end;
if (str != NULL)
{
start = str;
end = NULL;
}
else if (end)
end = NULL;
else
return NULL;
if ((end = strchr(start, tok)) != NULL)
{
char *p;
*end = 0;
p = start;
start = end + 1;
return p;
}
else
{
char *p;
p = start;
start = NULL;
end = NULL;
return p;
}
return NULL;
}
int isnumeric(char *str)
{
char *p;
if (str == NULL)
return FALSE;
p = str;
while (*p)
{
if (!isdigit(*p))
return FALSE;
p++;
}
return TRUE;
}
/*
* Assumes 0 <= max <= RAND_MAX
* Returns in the half-open interval [0, max]
*/
long random_at_most (long max)
{
unsigned long num_bins, num_rand, bin_size, defect;
long x;
/* max <= RAND_MAX < ULONG_MAX, so this is okay. */
num_bins = (unsigned long) max + 1,
num_rand = (unsigned long) RAND_MAX + 1,
bin_size = num_rand / num_bins,
defect = num_rand % num_bins;
do
{
x = random();
}
while (num_rand - defect <= (unsigned long)x); /* This is carefully written not to overflow */
/* Truncated division is intentional */
return x / bin_size;
}
char *str2hash(const char *str, int length)
{
uint32_t a, b;
char *out;
if ((out = (char *)malloc(17)) == NULL)
{
syslog(LOG_DAEMON, "Error allocating 33 Bytes for MD5 calculation: %s", strerror(errno));
return NULL;
}
memset(out, 0, 17);
a = 0x2e96a73d; b = 0x130f36db; /* Individual seeds to be able to reproduse the hashes */
hashlittle2(str, length, &a, &b);
#ifdef __APPLE__
sprintf(out, "%.8x%.8x", a, b);
#else
sprintf(out, "%.8lx%.8lx", a, b);
#endif
return out;
}
char *getFileExtension(const char *file)
{
char *ret, *p1;
if ((p1 = strrchr(file, '.')) == NULL)
return NULL;
if (strrchr(p1, '/') != NULL)
return NULL;
ret = p1 + 1;
return ret;
}
void delay (useconds_t ms)
{
if (ms != 0)
usleep(ms);
}
void waiting(useconds_t ms, waitcall callback, void *data)
{
pthread_attr_t attr;
if (ms == 0 || callback == NULL)
return;
/* Start a thread and call the callback function after the waiting time
* is over.
*/
usleep(ms);
/* Prepare the thread attributes */
if (pthread_attr_init(&attr) != 0)
{
syslog(LOG_DAEMON,"Error getting thread attributes.");
return;
}
if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
{
syslog(LOG_DAEMON,"Error setting thread attributes.");
return;
}
if (pthread_create(&pthr_wait, &attr, callback, data) != 0)
{
syslog (LOG_DAEMON,"Creation of thread \"pthr_wait\" failed!");
return;
}
}