Subversion Repositories mdb

Rev

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;
        }
}