Tue, 09 Jul 2013 17:16:26 +0200
replaced propfind parser with new libxml2 parser
/* * 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; } /* --------------------------- util_env_create ---------------------------- */ NSAPI_PUBLIC char **util_env_create(char **env, int n, int *pos) { int x; if(!env) { *pos = 0; return (char **) MALLOC((n + 1)*sizeof(char *)); } else { for(x = 0; (env[x]); x++); env = (char **) REALLOC(env, (n + x + 1)*(sizeof(char *))); *pos = x; return env; } } /* ---------------------------- util_env_free ----------------------------- */ NSAPI_PUBLIC void util_env_free(char **env) { register char **ep = env; for(ep = env; *ep; ep++) FREE(*ep); FREE(env); } /* ----------------------------- util_env_str ----------------------------- */ NSAPI_PUBLIC char *util_env_str(const char *name, const char *value) { char *t; t = (char *) MALLOC(strlen(name)+strlen(value)+2); /* 2: '=' and '\0' */ sprintf(t, "%s=%s", name, value); return t; } /* --------------------------- util_env_replace --------------------------- */ NSAPI_PUBLIC void util_env_replace(char **env, const char *name, const char *value) { int x, y, z; char *i; for(x = 0; env[x]; x++) { i = strchr(env[x], '='); *i = '\0'; if(!strcmp(env[x], name)) { y = strlen(env[x]); z = strlen(value); env[x] = (char *) REALLOC(env[x], y + z + 2); util_sprintf(&env[x][y], "=%s", value); return; } *i = '='; } } /* ---------------------------- util_env_find ----------------------------- */ NSAPI_PUBLIC char *util_env_find(char **env, const char *name) { char *i; int x, r; for(x = 0; env[x]; x++) { i = strchr(env[x], '='); *i = '\0'; r = !strcmp(env[x], name); *i = '='; if(r) return i + 1; } return NULL; } /* ---------------------------- util_env_copy ----------------------------- */ NSAPI_PUBLIC char **util_env_copy(char **src, char **dst) { char **src_ptr; int src_cnt; int index; if (!src) return NULL; for (src_cnt = 0, src_ptr = src; *src_ptr; src_ptr++, src_cnt++); if (!src_cnt) return NULL; dst = util_env_create(dst, src_cnt, &index); for (src_ptr = src; *src_ptr; index++, src_ptr++) dst[index] = STRDUP(*src_ptr); dst[index] = NULL; return dst; } /* ----------------------------- util_sprintf ----------------------------- */ NSAPI_PUBLIC int util_vsnprintf(char *s, int n, register const char *fmt, va_list args) { return vsnprintf(s, n, fmt, args); } NSAPI_PUBLIC int util_snprintf(char *s, int n, const char *fmt, ...) { va_list args; va_start(args, fmt); return vsnprintf(s, n, fmt, args); } NSAPI_PUBLIC int util_vsprintf(char *s, register const char *fmt, va_list args) { return vsprintf(s, fmt, args); } NSAPI_PUBLIC int util_sprintf(char *s, const char *fmt, ...) { va_list args; va_start(args, fmt); return vsprintf(s, fmt, args); } // TODO: asprintf /* -------------------------- util_uri_unescape --------------------------- */ NSAPI_PUBLIC void util_uri_unescape(char *s) { char *t, *u; for(t = s, u = s; *t; ++t, ++u) { if((*t == '%') && t[1] && t[2]) { *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; } /* * Same as util_uri_unescape, but returns success/failure */ 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 int util_uri_unescape_plus (const char *src, char *trg, int len) { const char *t = src; char *u = trg == NULL ? (char *)src : trg; int rlen = 0; if (len == -1) len = strlen (src); for( ; len && *t; ++t, ++u, len--, rlen++) { if((*t == '%') && t[1] && t[2]) { *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; len-= 2; } else if (*t == '+') *u = ' '; else *u = *t; } *u = 0; return rlen; } 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 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; } // new - code in parts from params.cpp NSAPI_PUBLIC pblock* util_parse_param(pool_handle_t *pool, char *query) { pblock *pb = pblock_create_pool(pool, 32); if(!pb) { return NULL; } if(!query || !(*query)) { return pb; } int loopFlag = 1; int nl = 0; // size of the name substring int vl = 0; // size of the value substring int state = 0; const char *np = query; const char *vp = NULL; while (loopFlag) { char delim = *query++; switch (delim) { case '&': case '\0': { if(!delim) { loopFlag = 0; } state = 0; if(nl > 0) { util_uri_unescape_plus(np, NULL, nl); util_uri_unescape_plus(vp, NULL, vl); pblock_nvlinsert(np, nl, vp, vl, pb); } nl = 0; vl = 0; vp = NULL; np = query; break; } case '=': { state = 1; vp = query; break; } default: { if(state) { vl++; } else { nl++; } } } /* switch */ } /* while */ return pb; }