src/server/util/util.c

Fri, 21 Jun 2013 12:10:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 21 Jun 2013 12:10:44 +0200
changeset 71
069c152f6272
parent 69
4a10bc0ee80d
child 77
f1cff81e425a
permissions
-rw-r--r--

ucx update

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
 *
 * THE BSD LICENSE
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer. 
 * Redistributions in binary form must reproduce the above copyright notice, 
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution. 
 *
 * Neither the name of the  nor the names of its contributors may be
 * used to endorse or promote products derived from this software without 
 * specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * util.c: A hodge podge of utility functions and standard functions which 
 *         are unavailable on certain systems
 * 
 * Rob McCool
 */

#ifdef XP_UNIX
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include "prthread.h"
#endif /* XP_UNIX */


//include "nspr.h"
#include <errno.h>

#include "../daemon/netsite.h"
#include "../public/nsapi.h"

#include "util.h"



/* ------------------------------ _uudecode ------------------------------- */

static const unsigned char pr2six[256] = {
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,62,64,64,64,63,
    52,53,54,55,56,57,58,59,60,61,64,64,64,64,64,64,64,0,1,2,3,4,5,6,7,8,9,
    10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,64,64,64,64,64,64,26,27,
    28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
    64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
    64,64,64,64,64,64,64,64,64,64,64,64,64
};

/** you MUST reserve at least 2 additional bytes for bufout */
size_t util_base64decode(char *bufcoded, size_t codedbytes, char *bufout) {
    register char *bufin = bufcoded;
    register int nprbytes;
    size_t nbytesdecoded;

    /* Find the length */
    nprbytes = (int) codedbytes;
    while(pr2six[(int)(bufin[nprbytes-1])] >= 64) {
      nprbytes--;
    }
    nbytesdecoded = ((nprbytes+3)/4) * 3;

    while (nprbytes > 0) {
        *(bufout++) = (unsigned char)
            (pr2six[(int)(*bufin)] << 2 | pr2six[(int)bufin[1]] >> 4);
        *(bufout++) = (unsigned char)
            (pr2six[(int)bufin[1]] << 4 | pr2six[(int)bufin[2]] >> 2);
        *(bufout++) = (unsigned char)
            (pr2six[(int)bufin[2]] << 6 | pr2six[(int)bufin[3]]);
        bufin += 4;
        nprbytes -= 4;
    }

    if(nprbytes & 03) {
        if(pr2six[(int)bufin[-2]] > 63)
            nbytesdecoded -= 2;
        else
            nbytesdecoded -= 1;
    }

    return nbytesdecoded;
}

/*
NSAPI_PUBLIC int util_getboolean(const char *v, int def) {
    if(v[0] == 'T' || v[0] == 't') {
        return 1;
    }
    if(v[0] == 'F' || v[0] == 'f') {
        return 0;
    }
    return def;
}
*/

NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def) {
    if(v[0] == 'T' || v[0] == 't') {
        return 1;
    }
    if(v[0] == 'F' || v[0] == 'f') {
        return 0;
    }
    return def;
}


/* ------------------------------ util_itoa ------------------------------- */
/*
NSAPI_PUBLIC int util_itoa(int i, char *a)
{
    int len = util_i64toa(i, a);

    PR_ASSERT(len < UTIL_ITOA_SIZE);

    return len;
}
*/
NSAPI_PUBLIC int INTutil_itoa(int i, char *a) {
    return INTutil_i64toa(i, a);
}


/* ----------------------------- util_i64toa ------------------------------ */

/*
 * Assumption: Reversing the digits will be faster in the general case
 * than doing a log10 or some nasty trick to find the # of digits.
 */

NSAPI_PUBLIC int INTutil_i64toa(int64_t i, char *a)
{
    register int x, y, p;
    register char c;
    int negative;

    negative = 0;
    if(i < 0) {
        *a++ = '-';
        negative = 1;
        i = -i;
    }
    p = 0;
    while(i > 9) {
        a[p++] = (i%10) + '0';
        i /= 10;
    }
    a[p++] = i + '0';

    if(p > 1) {
        for(x = 0, y = p - 1; x < y; ++x, --y) {
            c = a[x];
            a[x] = a[y];
            a[y] = c;
        }
    }
    a[p] = '\0';

    //PR_ASSERT(p + negative < UTIL_I64TOA_SIZE);

    return p + negative;
}



#ifndef XP_WIN32
NSAPI_PUBLIC struct passwd *
util_getpwnam(const char *name, struct passwd *result, char *buffer, 
	int buflen)
{
    struct passwd *rv;

#if defined(AIX) || defined(LINUX) || defined(HPUX) || defined(OSX)
    errno = getpwnam_r(name, result, buffer, buflen, &rv);
    if (errno != 0)
        rv = NULL;
#else
    rv = getpwnam_r(name, result, buffer, buflen);
#endif

    return rv;
}
#endif


#ifndef XP_WIN32
NSAPI_PUBLIC struct passwd *
util_getpwuid(uid_t uid, struct passwd *result, char *buffer, int buflen)
{
    struct passwd *rv;

#if defined(AIX) || defined(LINUX) || defined(HPUX) || defined(OSX)
    errno = getpwuid_r(uid, result, buffer, buflen, &rv);
    if (errno != 0)
        rv = NULL;
#else
    rv = getpwuid_r(uid, result, buffer, buflen);
#endif

    return rv;
}
#endif


NSAPI_PUBLIC int util_errno2status(int errno_value) {
    switch(errno_value) {
        case 0: {
            return 200;
        }
        case EACCES: {
            return 403;
        }
        case ENOENT: {
            return 404;
            break;
        }
    }
    return 500;
}

NSAPI_PUBLIC int util_uri_unescape_strict(char *s)
{
    char *t, *u, t1, t2;
    int rv = 1;

    for(t = s, u = s; *t; ++t, ++u) {
        if (*t == '%') {
            t1 = t[1] & 0xdf; /* [a-f] -> [A-F] */
            if ((t1 < 'A' || t1 > 'F') && (t[1] < '0' || t[1] > '9'))
                rv = 0;

            t2 = t[2] & 0xdf; /* [a-f] -> [A-F] */
            if ((t2 < 'A' || t2 > 'F') && (t[2] < '0' || t[2] > '9'))
                rv = 0;

            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
            t += 2;
        }
        else if (u != t)
            *u = *t;
    }
    *u = *t;

    return rv;
}

NSAPI_PUBLIC
sstr_t util_path_append(pool_handle_t *pool, char *path, char *ch) {
    sstr_t parent = sstr(path);
    sstr_t child = sstr(ch);
    sstr_t newstr;
    sstr_t s;
    
    s.length = 0;
    s.ptr = NULL;
    newstr.length = parent.length + child.length;
    if(parent.ptr[parent.length - 1] != '/') {
        s = sstrn("/", 1);
        newstr.length++;
    }
    
    newstr.ptr = pool_malloc(pool, newstr.length + 1);
    if(!newstr.ptr) {
        // TODO: error
        newstr.length = 0;
        return newstr;
    }
    if(s.length == 1) {
        newstr = sstrncat(3, newstr, parent, s, child);
    } else {
        newstr = sstrncat(2, newstr, parent, child);
    }
    newstr.ptr[newstr.length] = '\0';
    
    return newstr;
}

sstr_t util_path_remove_last(sstr_t path) {
    int i;
    for(i=path.length-1;i>=0;i--) {
        char c = path.ptr[i];
        if(c == '/') {
            path.ptr[i] = 0;
            path.length = i;
            break;
        }
    }
    if(i < 0) {
        path.ptr = NULL;
        path.length = 0;
    }
    return path;
}

mercurial