dav/db.c

Fri, 13 Jun 2014 13:52:59 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 13 Jun 2014 13:52:59 +0200
changeset 46
0542668d0f26
child 47
fbbbeed4ba8f
permissions
-rw-r--r--

added new sync tool

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2014 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. 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.
 *
 * 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 HOLDER 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.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "db.h"

#include <libidav/utils.h>


#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)

#ifdef _WIN32
#define ENV_HOME getenv("USERPROFILE")
#else
#define ENV_HOME getenv("HOME")
#endif /* _WIN32 */

UcxMap* load_db(char *name) {
    char *dav_dir = util_concat_path(ENV_HOME, ".dav");
    char *db_file = util_concat_path(dav_dir, name);
    free(dav_dir);
    
    xmlTextReaderPtr reader = xmlReaderForFile(db_file, NULL, 0);
    if(!reader) {
        fprintf(stderr, "Cannot open database file: %s\n", db_file);
        free(db_file);
        return NULL;
    }
    free(db_file);
    
    UcxMap *map = ucx_map_new(2048);
    int error = 0;
    while(xmlTextReaderRead(reader)) {
        int type = xmlTextReaderNodeType(reader);
        const xmlChar *name = xmlTextReaderConstName(reader);
        
        if(type == XML_READER_TYPE_ELEMENT) {
            if(xstreq(name, "resource")) {
                LocalResource *res = process_resource(reader);
                if(res) {
                    ucx_map_cstr_put(map, res->path, res);
                } else {
                    error = 1;
                    break;
                }
            }
        }
    }
    
    xmlFreeTextReader(reader);
    if(error) {
        // TODO: free resources and map
        return NULL;
    } else {
        return map;
    }
}

LocalResource* process_resource(xmlTextReaderPtr reader) {
    LocalResource *res = calloc(1, sizeof(LocalResource));
    
    int field = -1;
    while(xmlTextReaderRead(reader)) {
        int type = xmlTextReaderNodeType(reader);
        const xmlChar *name = xmlTextReaderConstName(reader);
        
        if(type == XML_READER_TYPE_ELEMENT) {
            if(xstreq(name, "path")) {
                field = 0;
            } else if(xstreq(name, "etag")) {
                field = 1;
            } else if(xstreq(name, "lastmodified")) {
                field = 2;
            } else if(xstreq(name, "size")) {
                field = 3;
            }
        } else if(type == XML_READER_TYPE_TEXT) {
            const xmlChar *value = xmlTextReaderConstValue(reader);
            int b = 0;
            switch(field) {
                case 0: {
                    res->name = strdup((char*)value);
                    break;
                }
                case 1: {
                    res->etag = strdup((char*)value);
                    break;
                }
                case 2: {
                    res->last_modified = util_parse_lastmodified((char*)value);
                    break;
                }
                case 3: {
                    res->size = atoi((char*)value);
                    break;
                }
            }
        } else if(XML_READER_TYPE_END_ELEMENT) {
            if(xstreq(name, "resource")) {
                break;
            } else {
                field = -1;
            }
        }
    }
    
    if(!res->name || !res->path || res->last_modified == 0) {
        // TODO: free res
        return NULL;
    } else {
        return res;
    }
}

int store_db(UcxMap *db, char *name) {
    // TODO:
    
}

mercurial