test/ctestfile.c

Tue, 21 Apr 2015 09:47:52 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 21 Apr 2015 09:47:52 +0200
changeset 25
f82aa7afe872
child 31
50ae611a785c
permissions
-rw-r--r--

more and better test cases + fixed memory leak introduced by changeset e43dee5892f4

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2015 Olaf Wintermann. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    29 #include <time.h>
    30 #include <stdio.h>
    31 #include <stdlib.h>
    32 #include <string.h>
    33 #include <ucx/string.h>
    34 #include <ucx/buffer.h>
    35 #include <ucx/utils.h>
    36 #include <libxml/tree.h>
    37 #include <curl/curl.h>
    39 #include <openssl/sha.h>
    40 #include <openssl/hmac.h>
    41 #include <openssl/evp.h>
    42 #include <openssl/bio.h>
    43 #include <openssl/buffer.h>
    44 #include <openssl/rand.h>
    46 #include "utils.h"
    47 #include "crypto.h"
    48 #include "webdav.h"
    51 time_t util_parse_creationdate(char *str) {
    52     // example: 2012-11-29T21:35:35Z
    53     if(!str) {
    54         return 0;
    55     }
    56     // TODO
    57     return 0;
    58 }
    60 time_t util_parse_lastmodified(char *str) {
    61     // example: Thu, 29 Nov 2012 21:35:35 GMT
    62     if(!str) {
    63         return 0;
    64     } else {
    65         return curl_getdate(str, NULL);
    66     }
    67 }
    69 int util_getboolean(char *v) {
    70     if(v[0] == 'T' || v[0] == 't') {
    71         return 1;
    72     }
    73     return 0;
    74 }
    76 int util_strtoint(char *str, int64_t *value) {
    77     char *end;
    78     int64_t val = strtoll(str, &end, 0);
    79     if(strlen(end) == 0) {
    80         *value = val;
    81         return 1;
    82     } else {
    83         return 0;
    84     }
    85 }
    87 char* util_url_path(char *url) { 
    88     char *path = NULL;
    89     size_t len = strlen(url);
    90     int slashcount = 0;
    91     int slmax;
    92     if(len > 7 && !strncasecmp(url, "http://", 7)) {
    93         slmax = 3;
    94     } else if(len > 8 && !strncasecmp(url, "https://", 8)) {
    95         slmax = 3;
    96     } else {
    97         slmax = 1;
    98     }
    99     char c;
   100     for(int i=0;i<len;i++) {
   101         c = url[i];
   102         if(c == '/') {
   103             slashcount++;
   104             if(slashcount == slmax) {
   105                 path = url + i;
   106                 break;
   107             }
   108         }
   109     } 
   110     return path;
   111 }
   113 char* util_url_decode(DavSession *sn, char *url) {
   114     char *unesc = curl_easy_unescape(sn->handle, url, strlen(url), NULL);
   115     char *ret = strdup(unesc);
   116     curl_free(unesc);
   117     return ret;
   118 }
   120 char* util_resource_name(char *url) {
   121     int si = 0;
   122     int osi = 0;
   123     int i = 0;
   124     int p = 0;
   125     char c;
   126     while((c = url[i]) != 0) {
   127         if(c == '/') {
   128             osi = si;
   129             si = i;
   130             p = 1;
   131         }
   132         i++;
   133     }
   135     char *name = url + si + p;
   136     if(name[0] == 0) {
   137         name = url + osi + p;
   138         if(name[0] == 0) {
   139             return url;
   140         }
   141     }
   143     return name;
   144 }
   146 int util_mkdir(char *path, mode_t mode) {
   147 #ifdef _WIN32
   148     return mkdir(path);
   149 #else
   150     return mkdir(path, mode);
   151 #endif
   152 }
   154 char* util_concat_path(char *url_base, char *p) {
   155     sstr_t base = sstr(url_base);
   156     sstr_t path;
   157     if(p) {
   158         path = sstr(p);
   159     } else {
   160         path = sstrn("", 0);
   161     }
   163     int add_separator = 0;
   164     if(base.ptr[base.length-1] == '/') {
   165         if(path.ptr[0] == '/') {
   166             base.length--;
   167         }
   168     } else {
   169         if(path.length == 0 || path.ptr[0] != '/') {
   170             add_separator = 1;
   171         }
   172     }
   174     sstr_t url;
   175     if(add_separator) {
   176         url = sstrcat(3, base, sstr("/"), path);
   177     } else {
   178         url = sstrcat(2, base, path);
   179     }
   181     return url.ptr;
   182 }
   184 void util_set_url(DavSession *sn, char *href) {
   185     sstr_t base = sstr(sn->base_url);
   186     sstr_t href_str = sstr(href);
   188     char *base_path = util_url_path(sn->base_url);
   189     base.length -= strlen(base_path);
   191     sstr_t url = sstrcat(2, base, href_str);
   193     curl_easy_setopt(sn->handle, CURLOPT_URL, url.ptr);
   194     free(url.ptr);
   195 }
   197 char* util_path_to_url(DavSession *sn, char *path) {
   198     char *space = malloc(256);
   199     UcxBuffer *url = ucx_buffer_new(space, 256, UCX_BUFFER_AUTOEXTEND);
   201     // add base url
   202     ucx_buffer_write(sn->base_url, 1, strlen(sn->base_url), url);
   203     // remove trailing slash
   204     ucx_buffer_seek(url, -1, SEEK_CUR);
   206     sstr_t p = sstr(path);
   207     ssize_t ntk = 0;
   208     sstr_t *tks = sstrsplit(p, S("/"), &ntk);
   210     for(int i=0;i<ntk;i++) {
   211         sstr_t node = tks[i];
   212         if(node.length > 0) {
   213             char *esc = curl_easy_escape(sn->handle, node.ptr, node.length);
   214             ucx_buffer_putc(url, '/');
   215             ucx_buffer_write(esc, 1, strlen(esc), url);
   216             curl_free(esc);
   217         }
   218         free(node.ptr);
   219     }
   220     free(tks);
   221     if(path[p.length-1] == '/') {
   222         ucx_buffer_putc(url, '/');
   223     }
   224     ucx_buffer_putc(url, 0);
   226     space = url->space;
   227     ucx_buffer_free(url);
   229     return space;
   230 }
   232 char* util_parent_path(char *path) {
   233     char *name = util_resource_name(path);
   234     size_t namelen = strlen(name);
   235     size_t pathlen = strlen(path);
   236     size_t parentlen = pathlen - namelen;
   237     char *parent = malloc(parentlen + 1);
   238     memcpy(parent, path, parentlen);
   239     parent[parentlen] = '\0';
   240     return parent;
   241 }
   244 char* util_xml_get_text(xmlNode *elm) {
   245     xmlNode *node = elm->children;
   246     while(node) {
   247         if(node->type == XML_TEXT_NODE) {
   248             return (char*)node->content;
   249         }
   250         node = node->next;
   251     }
   252     return NULL;
   253 }
   256 char* util_base64decode(char *in) {
   257     int len = 0;
   258     return util_base64decode_len(in, &len);
   259 }
   261 char* util_base64decode_len(char* in, int *outlen) {
   262     size_t len = strlen(in);
   263     char *out = calloc(1, len);
   265     BIO* b = BIO_new_mem_buf(in, len);
   266     BIO *d = BIO_new(BIO_f_base64());
   267     BIO_set_flags(d, BIO_FLAGS_BASE64_NO_NL);
   268     b = BIO_push(d, b);
   270     *outlen = BIO_read(b, out, len);
   271     BIO_free_all(b);
   273     return out;
   274 }
   276 char* util_base64encode(char *in, size_t len) { 
   277     BIO *b;
   278     BIO *e;
   279     BUF_MEM *mem;
   281     e = BIO_new(BIO_f_base64());
   282     b = BIO_new(BIO_s_mem());
   284     e = BIO_push(e, b);
   285     BIO_write(e, in, len);
   286     BIO_flush(e);
   288     BIO_get_mem_ptr(e, &mem);
   289     char *out = malloc(mem->length);
   290     memcpy(out, mem->data, mem->length -1);
   291     out[mem->length - 1] = '\0';
   293     BIO_free_all(e);
   295     return out;
   296 }
   298 char* util_encrypt_str(DavSession *sn, char *str, char *key) {
   299     DavKey *k = dav_context_get_key(sn->context, key);
   300     if(!k) {
   301         // TODO: session error
   302         return NULL;
   303     }
   305     char *enc_str = aes_encrypt(str, k);
   306     char *ret_str = dav_session_strdup(sn, enc_str);
   307     free(enc_str);
   308     return ret_str;
   309 }
   311 char* util_decrypt_str(DavSession *sn, char *str, char *key) {
   312     DavKey *k = dav_context_get_key(sn->context, key);
   313     if(!k) {
   314         // TODO: session error
   315         return NULL;
   316     }
   318     char *dec_str = aes_decrypt(str, k);
   319     char *ret_str = dav_session_strdup(sn, dec_str);
   320     free(dec_str);
   321     return ret_str;
   322 }
   324 char* util_random_str() {
   325     unsigned char *str = malloc(25);
   326     str[24] = '\0';
   328     sstr_t t = S(
   329             "01234567890"
   330             "abcdefghijklmnopqrstuvwxyz"
   331             "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
   332     const unsigned char *table = (const unsigned char*)t.ptr;
   334     RAND_pseudo_bytes(str, 24);
   335     for(int i=0;i<24;i++) {
   336         int c = str[i] % t.length;
   337         str[i] = table[c];
   338     }
   340     return (char*)str;
   341 }
   343 /*
   344  * gets a substring from 0 to the appearance of the token
   345  * tokens are separated by space
   346  * sets sub to the substring and returns the remaining string
   347  */
   348 sstr_t util_getsubstr_until_token(sstr_t str, sstr_t token, sstr_t *sub) {  
   349     int i;
   350     int token_start = -1;
   351     int token_end = -1;
   352     for(i=0;i<=str.length;i++) {
   353         int c;
   354         if(i == str.length) {
   355             c = ' ';
   356         } else {
   357             c = str.ptr[i];
   358         }
   359         if(c < 33) {
   360             if(token_start != -1) {
   361                 token_end = i;
   362                 size_t len = token_end - token_start;
   363                 sstr_t tk = sstrsubsl(str, token_start, len);
   364                 //printf("token: {%.*s}\n", token.length, token.ptr);
   365                 if(!sstrcmp(tk, token)) {
   366                     *sub = sstrtrim(sstrsubsl(str, 0, token_start));
   367                     break;
   368                 }
   369                 token_start = -1;
   370                 token_end = -1;
   371             }
   372         } else {
   373             if(token_start == -1) {
   374                 token_start = i;
   375             }
   376         }
   377     }
   379     if(i < str.length) {
   380         return sstrtrim(sstrsubs(str, i));
   381     } else {
   382         str.ptr = NULL;
   383         str.length = 0;
   384         return str;
   385     }
   386 }

mercurial