Beispiel #1
0
/* Replace element in the array */
int ref_array_replace(struct ref_array *ra,
                      uint32_t idx,
                      void *element)
{
    int error = EOK;

    TRACE_FLOW_ENTRY();

    if ((!ra) || (!element)) {
        TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
        return EINVAL;
    }

    if (idx > ra->len) {
        TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
        return ERANGE;
    }

    /* Clear old element */
    if (ra->cb)
        ra->cb((unsigned char *)(ra->storage) + idx * ra->elsize,
               REF_ARRAY_DELETE, ra->cb_data);

    /* Overwrite element */
    memcpy((unsigned char *)(ra->storage) + idx * ra->elsize,
           element,
           ra->elsize);


    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #2
0
/* Change boundary */
int value_set_boundary(struct value_obj *vo, uint32_t boundary)
{
    int error = EOK;
    TRACE_FLOW_ENTRY();

    if (!vo) {
        TRACE_ERROR_NUMBER("Invalid object", EINVAL);
        return EINVAL;
    }

    vo->boundary = boundary;

    /* Fold in new value */
    error = value_fold(vo->unfolded,
                       vo->keylen,
                       vo->boundary,
                       vo->raw_lines,
                       vo->raw_lengths);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to fold", error);
        /* In this case nothing to free here but
         * the object might be unusable */
        return error;
    }

    TRACE_FLOW_EXIT();
    return EOK;
}
Beispiel #3
0
/* Remove element from the array */
int ref_array_remove(struct ref_array *ra,
                     uint32_t idx)
{
    int error = EOK;
    uint32_t i;

    TRACE_FLOW_ENTRY();

    if (!ra) {
        TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
        return EINVAL;
    }

    if (idx >= ra->len) {
        TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
        return ERANGE;
    }

    /* Clear old element */
    if (ra->cb)
        ra->cb((unsigned char *)(ra->storage) + idx * ra->elsize,
               REF_ARRAY_DELETE, ra->cb_data);

    /* Shift elements left */
    for (i = idx + 1; i < ra->len; i++) {
        memcpy((unsigned char *)(ra->storage) + (i - 1) * ra->elsize,
               (unsigned char *)(ra->storage) +  i * ra->elsize,
               ra->elsize);
    }

    ra->len--;

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #4
0
/* Add a raw string to the arrays */
int value_add_to_arrays(const char *strvalue,
                        uint32_t len,
                        struct ref_array *raw_lines,
                        struct ref_array *raw_lengths)
{
    int error = EOK;

    TRACE_FLOW_ENTRY();

    error = ref_array_append(raw_lines, (void *)(&strvalue));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add to lines array", error);
        return error;

    }

    error = ref_array_append(raw_lengths, (void *)(&len));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add to lengths array", error);
        return error;

    }

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #5
0
/* Set the folding boundary for multiline values.
 * Use before serializing and saving to a file if the
 * default boundary of 80 characters does not work for you.
 */
int ini_config_set_wrap(struct ini_cfgobj *ini_config,
                        uint32_t boundary)
{
    int error = EOK;

    TRACE_FLOW_ENTRY();

    if (!ini_config) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    ini_config->boundary = boundary;
    error = col_traverse_collection(ini_config->cfg,
                                    COL_TRAVERSE_DEFAULT,
                                    ini_boundary_cb,
                                    (void *)(&(ini_config->boundary)));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to set wrapping boundary", error);
        return error;
    }


    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #6
0
/* Add new element to the array */
int ref_array_append(struct ref_array *ra, void *element)
{
    int error = EOK;

    TRACE_FLOW_ENTRY();

    if ((!ra) || (!element)) {
        TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
        return EINVAL;
    }

    /* Do we have enough room for a new element? */
    if (ra->size == ra->len) {
        error = ref_array_grow(ra);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to grow array.", error);
            return error;
        }
    }

    /* Copy element */
    memcpy((unsigned char *)(ra->storage) + ra->len * ra->elsize,
           element,
           ra->elsize);

    ra->len++;

    TRACE_INFO_NUMBER("Length after append: ", ra->len);

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #7
0
static int save_portion(struct ref_array *raw_lines,
                        struct ref_array *raw_lengths,
                        const char* buf,
                        uint32_t len)
{
    int error = EOK;
    char *copy = NULL;
    uint32_t adj = 0;

    TRACE_FLOW_ENTRY();

    /* Add leading space only if there is
     * a) no space
     * b) it is not an empty line
     * c) it is now a first line
     */

    if ((buf[0] != ' ') &&
        (buf[0] != '\t') &&
        (len != 0) &&
        (ref_array_len(raw_lines) != 0)) adj = 1;

    copy = malloc(len + adj + 1);
    if (!copy) {
        TRACE_ERROR_NUMBER("Failed to allocate memory", ENOMEM);
        return ENOMEM;
    }

    memcpy(copy + adj, buf, len);
    len += adj;
    copy[len] = 0;

    /* If the section being saved is not starting
     * with space add a space.
     */
    if (adj) copy[0] = ' ';

    error = ref_array_append(raw_lines, (void *)(&copy));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to append line",
                            error);
        free(copy);
        return error;
    }

    error = ref_array_append(raw_lengths, (void *)(&len));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to append length",
                            error);
        return error;
    }

    TRACE_INFO_STRING("Added string:", (char *)copy);
    TRACE_INFO_NUMBER("Added number:", len);


    TRACE_FLOW_EXIT();
    return EOK;
}
Beispiel #8
0
/* Print the collection using iterator */
int col_print_collection2(struct collection_item *handle)
{
    struct collection_iterator *iterator = NULL;
    int error = EOK;
    struct collection_item *item = NULL;
    int nest_level = 0;
    int dummy = 0;
    int line = 1;

    TRACE_FLOW_STRING("col_print_collection2", "Entry");

    /* If we have something to print print it */
    if (handle == NULL) {
        TRACE_ERROR_STRING("No error list", "");
        return EINVAL;
    }

    /* Bind iterator */
    error = col_bind_iterator(&iterator, handle,
                              COL_TRAVERSE_DEFAULT |
                              COL_TRAVERSE_END |
                              COL_TRAVERSE_SHOWSUB);
    if (error) {
        TRACE_ERROR_NUMBER("Error (bind):", error);
        return error;
    }

    do {
        /* Loop through a collection */
        error = col_iterate_collection(iterator, &item);
        if (error) {
            TRACE_ERROR_NUMBER("Error (iterate):", error);
            col_unbind_iterator(iterator);
            return error;
        }

        /* Are we done ? */
        if (item == NULL) break;

        if (item->type != COL_TYPE_END) printf("%05d", line);

        col_debug_handle(item->property,
                         item->property_len,
                         item->type,
                         item->data,
                         item->length,
                         (void *)(&nest_level),
                         &dummy);
        line++;
    }
    while(1);

    /* Do not forget to unbind iterator - otherwise there will be a leak */
    col_unbind_iterator(iterator);

    TRACE_INFO_STRING("col_print_collection2", "Exit");
    return EOK;
}
Beispiel #9
0
/* Inspect the line */
static int parser_inspect(struct parser_obj *po)
{
    int error = EOK;
    uint32_t action = PARSE_DONE;

    TRACE_FLOW_ENTRY();

    TRACE_INFO_STRING("Buffer:", po->last_read);
    TRACE_INFO_NUMBER("In comment:", po->inside_comment);

    if (check_for_comment(po->last_read,
                          po->last_read_len,
                          !(po->parse_flags & INI_PARSE_NO_C_COMMENTS),
                          &(po->inside_comment))) {

        error = handle_comment(po, &action);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to process comment", error);
            return error;
        }
    }
    else if (isspace(*(po->last_read))) {

        error = handle_space(po, &action);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to process line wrapping", error);
            return error;
        }
    }
    else if (*(po->last_read) == '[') {

        error = handle_section(po, &action);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to save section", error);
            return error;
        }
    }
    else {

        error = handle_kvp(po, &action);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to save kvp", error);
            return error;
        }
    }

    /* Move to the next action */
    error = col_enqueue_unsigned_property(po->queue,
                                          PARSE_ACTION,
                                          action);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to schedule an action", error);
        return error;
    }

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #10
0
/* Complete file processing */
static int parser_post(struct parser_obj *po)
{
    int error = EOK;

    TRACE_FLOW_ENTRY();

    /* If there was just a comment at the bottom
     * put it directly into the config object
     */
    if((po->ic) && (!(po->key))) {
        if (po->co->last_comment) {
            error = ini_comment_add(po->ic, po->co->last_comment);
            if (error) {
                TRACE_ERROR_NUMBER("Failed to merge comment", error);
                return error;
            }
        }
        else {
            error = ini_comment_copy(po->ic, &(po->co->last_comment));
            if (error) {
                TRACE_ERROR_NUMBER("Failed to copy comment", error);
                return error;
            }
        }

        ini_comment_destroy(po->ic);
        po->ic = NULL;
    }

    /* If there is a key being processed add it */
    if (po->key) {
        error = complete_value_processing(po);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to complete value processing", error);
            return error;
        }
    }

    /* If we are done save the section */
    error = parser_save_section(po);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to save section", error);
        return error;
    }

    /* Move to the next action */
    error = col_enqueue_unsigned_property(po->queue,
                                          PARSE_ACTION,
                                          PARSE_DONE);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to schedule an action", error);
        return error;
    }

    TRACE_FLOW_EXIT();
    return EOK;
}
Beispiel #11
0
/* Create value from a referenced array */
int value_create_from_refarray(struct ref_array *raw_lines,
                               struct ref_array *raw_lengths,
                               uint32_t line,
                               uint32_t origin,
                               uint32_t key_len,
                               uint32_t boundary,
                               struct ini_comment *ic,
                               struct value_obj **vo)
{
    int error = EOK;
    struct value_obj *new_vo = NULL;

    TRACE_FLOW_ENTRY();

    if ((!raw_lines) || (!raw_lengths) || (!vo)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    new_vo = malloc(sizeof(struct value_obj));
    if (!new_vo) {
        TRACE_ERROR_NUMBER("No memory", ENOMEM);
        return ENOMEM;
    }

    /* We are not using references here since
     * it will be inconsistent with the way
     * how comment is handled.
     * We could have added references here and make
     * comment keep references but it seems to be
     * and overhead in this case.
     */
    new_vo->raw_lines = raw_lines;
    new_vo->raw_lengths = raw_lengths;
    new_vo->origin = origin;
    new_vo->line = line;
    new_vo->keylen = key_len;
    new_vo->boundary = boundary;
    new_vo->ic = ic;

    error = value_unfold(new_vo->raw_lines,
                         new_vo->raw_lengths,
                         &(new_vo->unfolded));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to unfold", error);
        value_destroy(new_vo);
        return error;
    }

    TRACE_INFO_STRING("Unfolded:",
                      (const char *)simplebuffer_get_buf(new_vo->unfolded));
    *vo = new_vo;

    TRACE_FLOW_EXIT();

    return error;
}
Beispiel #12
0
/* Update value */
int value_update(struct value_obj *vo,
                 const char *value,
                 uint32_t length,
                 uint32_t origin,
                 uint32_t boundary)
{
    int error = EOK;
    struct simplebuffer *oneline = NULL;

    if ((!value) || (!vo)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    /* Create buffer to hold the value */
    error = simplebuffer_alloc(&oneline);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
        return error;
    }

    /* Put value into the buffer */
    error = simplebuffer_add_str(oneline,
                                 value,
                                 length,
                                 INI_VALUE_BLOCK);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add string", error);
        simplebuffer_free(oneline);
        return error;
    }

    simplebuffer_free(vo->unfolded);

    vo->origin = origin;
    vo->unfolded = oneline;
    vo->boundary = boundary;

    /* Fold in new value */
    error = value_fold(vo->unfolded,
                       vo->keylen,
                       vo->boundary,
                       vo->raw_lines,
                       vo->raw_lengths);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to fold", error);
        /* In this case nothing to free here but
         * the object might be unsiable */
        return error;
    }

    TRACE_FLOW_EXIT();

    return error;

}
Beispiel #13
0
/* Run parser */
static int parser_run(struct parser_obj *po)
{
    int error = EOK;
    struct collection_item *item = NULL;
    uint32_t action = 0;
    action_fn operations[] = { parser_read,
                               parser_inspect,
                               parser_post,
                               parser_error,
                               NULL };

    TRACE_FLOW_ENTRY();

    while(1) {
        /* Get next action */
        item = NULL;
        error = col_dequeue_item(po->queue, &item);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to get action", error);
            return error;
        }

        /* Get action, run operation */
        action = *((uint32_t *)(col_get_item_data(item)));
        col_delete_item(item);

        if (action == PARSE_DONE) {

            TRACE_INFO_NUMBER("We are done", error);

            /* Report merge error in detect mode
             * if no other error was detected. */
            if ((po->ret == 0) &&
                (po->merge_error != 0) &&
                ((po->collision_flags & INI_MV1S_DETECT) ||
                 (po->collision_flags & INI_MV2S_DETECT) ||
                 (po->collision_flags & INI_MS_DETECT)))
                po->ret = po->merge_error;

            error = po->ret;
            break;
        }

        error = operations[action](po);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to perform an action", error);
            return error;
        }

    }

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #14
0
/* Unfold the value represented by the array */
static int value_unfold(struct ref_array *raw_lines,
                        struct ref_array *raw_lengths,
                        struct simplebuffer **unfolded)
{
    int error;
    struct simplebuffer *oneline = NULL;
    uint32_t len = 0;
    char *ptr = NULL;
    uint32_t i = 0;
    char *part = NULL;

    TRACE_FLOW_ENTRY();

    error = simplebuffer_alloc(&oneline);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to allocate dynamic string.", error);
        return error;
    }

    for (;;) {
        /* Get line */
        ptr = ref_array_get(raw_lines, i, NULL);
        if (ptr) {
            /* Get its length */
            ref_array_get(raw_lengths, i, (void *)&len);

            part = *((char **)(ptr));

            TRACE_INFO_STRING("Value:", part);
            TRACE_INFO_NUMBER("Lenght:", len);

            error = simplebuffer_add_raw(oneline,
                                         part,
                                         len,
                                         INI_VALUE_BLOCK);
            if (error) {
                TRACE_ERROR_NUMBER("Failed to add string", error);
                simplebuffer_free(oneline);
                return error;
            }

            i++;
        }
        else break;
    }

    *unfolded = oneline;

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #15
0
/* Prepare metadata */
int prepare_metadata(uint32_t metaflags,
                     struct collection_item **metadata,
                     int *save_error)
{
    int error = EOK;
    struct collection_item *metasec = NULL;

    TRACE_FLOW_STRING("prepare_metadata", "Entry");

    /* Are we supposed to collect or process meta data ? */
    if (!metadata) {
        TRACE_FLOW_STRING("No meta data", "Exit");
        return EOK;
    }

    /* Allocate metadata */
    error = col_create_collection(metadata,
                                  INI_METADATA,
                                  COL_CLASS_INI_META);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create meta data", error);
        return error;
    }

    /* Check and create section for file error if needed */
    if (metaflags & INI_META_SEC_ERROR_FLAG) {
        /* Create ERROR collection */
        if ((error = col_create_collection(&metasec,
                                           INI_META_SEC_ERROR,
                                           COL_CLASS_INI_SECTION)) ||
            (error = col_add_collection_to_collection(
                                           *metadata,
                                           NULL,
                                           NULL,
                                           metasec,
                                           COL_ADD_MODE_REFERENCE))) {
            TRACE_ERROR_NUMBER("Failed to create error section", error);
            col_destroy_collection(metasec);
            col_destroy_collection(*metadata);
            *metadata = NULL;
            return error;
        }
        /* If we are here we would have to save file open error */
        *save_error = 1;
        col_destroy_collection(metasec);
    }

    TRACE_FLOW_STRING("prepare_metadata", "Exit");
    return error;
}
Beispiel #16
0
/* Function to add string to the end of the buffer. */
int simplebuffer_add_str(struct simplebuffer *data,
                         const char *str,
                         uint32_t len,
                         uint32_t block)
{

    int error = EOK;
    uint32_t size;

    TRACE_FLOW_ENTRY();

    size = len + 1;
    error = simplebuffer_grow(data, size,
                             ((block > size) ? block : size));
    if (error) {
        TRACE_ERROR_NUMBER("Failed to grow buffer.", error);
        return error;
    }

    memcpy(data->buffer + data->length, str, len);
    data->length += len;
    data->buffer[data->length] = '\0';

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #17
0
/* Grow buffer to accomodate more space */
int col_grow_buffer(struct col_serial_data *buf_data, int len)
{
    char *tmp;

    TRACE_FLOW_STRING("col_grow_buffer", "Entry point");
    TRACE_INFO_NUMBER("Current length: ", buf_data->length);
    TRACE_INFO_NUMBER("Increment length: ", len);
    TRACE_INFO_NUMBER("Expected length: ", buf_data->length+len);
    TRACE_INFO_NUMBER("Current size: ", buf_data->size);

    /* Grow buffer if needed */
    while (buf_data->length+len >= buf_data->size) {
        tmp = realloc(buf_data->buffer, buf_data->size + BLOCK_SIZE);
        if (tmp == NULL) {
            TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", ENOMEM);
            return ENOMEM;
        }
        buf_data->buffer = tmp;
        buf_data->size += BLOCK_SIZE;
        TRACE_INFO_NUMBER("New size: ", buf_data->size);

    }

    TRACE_INFO_NUMBER("Final size: ", buf_data->size);
    TRACE_FLOW_STRING("col_grow_buffer", "Success Exit.");
    return EOK;
}
Beispiel #18
0
static int ref_array_grow(struct ref_array *ra)
{
    int error = EOK;
    void *newbuf = NULL;

    TRACE_FLOW_ENTRY();

    TRACE_INFO_NUMBER("Current length: ", ra->len);
    TRACE_INFO_NUMBER("Current size: ", ra->size);

    /* Grow buffer if needed */
    newbuf = realloc(ra->storage, (ra->size + ra->grow_by) * ra->elsize);
    if (newbuf == NULL) {
        TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
        return ENOMEM;
    }

    ra->storage = newbuf;
    ra->size += ra->grow_by;

    TRACE_INFO_NUMBER("Final size: ", ra->size);
    TRACE_FLOW_RETURN(error);
    return error;

}
Beispiel #19
0
/* Create a buffer containg JSON serialization */
int col_json_collection(struct collection_item *handle, char **storage)
{
    struct col_serial_data buf_data;
    int error = EOK;

    TRACE_FLOW_STRING("col_json_collection", "Entry");

    if (storage == NULL) {
        TRACE_ERROR_STRING("Error.", "Storage data is not passed in!");
        return EINVAL;
    }

    *storage = NULL;

    buf_data.buffer = NULL;
    buf_data.length = 0;
    buf_data.size = 0;
    buf_data.nest_level = 0;

    /* Traverse collection */
    error = col_traverse_collection(handle,
                                    COL_TRAVERSE_DEFAULT | COL_TRAVERSE_END ,
                                    col_json, (void *)(&buf_data));
    if (error)
        TRACE_ERROR_NUMBER("Error traversing collection ", error);
    else
        *storage = buf_data.buffer;

    TRACE_FLOW_NUMBER("col_json_collection returning", error);
    return error;
}
Beispiel #20
0
/* Grow buffer */
int simplebuffer_grow(struct simplebuffer *data,
                      uint32_t len,
                      uint32_t block)
{
    int error = EOK;
    unsigned char *newbuf = NULL;

    TRACE_FLOW_ENTRY();

    TRACE_INFO_NUMBER("Current length: ", data->length);
    TRACE_INFO_NUMBER("Current size: ", data->size);
    TRACE_INFO_NUMBER("Length to have: ", len);
    TRACE_INFO_NUMBER("Increment length: ", block);

    /* Grow buffer if needed */
    while (data->length + len >= data->size) {
        newbuf = realloc(data->buffer, data->size + block);
        if (newbuf == NULL) {
            TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", ENOMEM);
            return ENOMEM;
        }
        data->buffer = newbuf;
        data->size += block;
        TRACE_INFO_NUMBER("New size: ", data->size);
    }

    TRACE_INFO_NUMBER("Final size: ", data->size);
    TRACE_FLOW_RETURN(error);
    return error;
}
Beispiel #21
0
/* Insert a new element into the array */
int ref_array_insert(struct ref_array *ra,
                     uint32_t idx,
                     void *element)
{
    int error = EOK;
    uint32_t i;

    TRACE_FLOW_ENTRY();

    if ((!ra) || (!element)) {
        TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
        return EINVAL;
    }

    if (idx > ra->len) {
        TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
        return ERANGE;
    }

    /* Do we have enough room for a new element? */
    if (ra->size == ra->len) {
        error = ref_array_grow(ra);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to grow array.", error);
            return error;
        }
    }

    /* Shift elements right */
    for (i = ra->len; i >= (idx + 1); i--) {
        memcpy((unsigned char *)(ra->storage) + i * ra->elsize,
               (unsigned char *)(ra->storage) + (i - 1) * ra->elsize,
               ra->elsize);
    }

    /* Overwrite element */
    memcpy((unsigned char *)(ra->storage) + idx * ra->elsize,
           element,
           ra->elsize);

    ra->len++;

    TRACE_FLOW_EXIT();
    return error;

}
Beispiel #22
0
/* Function to check whether the configuration is different */
int config_changed(struct collection_item *metadata,
                   struct collection_item *saved_metadata,
                   int *changed)
{
    int error = EOK;
    struct collection_item *md[2];
    unsigned long value[3][2];
    const char *key[] = { INI_META_KEY_MODIFIED,
                          INI_META_KEY_DEV,
                          INI_META_KEY_INODE };
    int i, j;


    TRACE_FLOW_STRING("config_changed", "Entry");

    if ((!metadata) ||
        (!saved_metadata) ||
        (!changed) ||
        (!col_is_of_class(metadata, COL_CLASS_INI_META)) ||
        (!col_is_of_class(saved_metadata, COL_CLASS_INI_META))) {
        TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
        return EINVAL;
    }

    md[0] = metadata;
    md[1] = saved_metadata;

    /* Get three values from each collection and compare them */
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 2; j++) {
            value[i][j] = get_checked_value(md[j], key[i] , &error);
            if (error) {
                TRACE_ERROR_NUMBER("Failed to get section.", error);
                return error;
            }
        }
        if (value[i][0] != value[i][1]) {
            *changed = 1;
            break;
        }
    }

    TRACE_FLOW_STRING("config_changed", "Exit");
    return error;

}
Beispiel #23
0
/* Swap two elements in the array */
int ref_array_swap(struct ref_array *ra,
                   uint32_t idx1,
                   uint32_t idx2)
{
    int error = EOK;
    void *temp = NULL;

    TRACE_FLOW_ENTRY();

    if (!ra) {
        TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
        return EINVAL;
    }

    if ((idx1 >= ra->len) ||
        (idx2 >= ra->len)) {
        TRACE_ERROR_NUMBER("Index is out of range", ERANGE);
        return ERANGE;
    }

    if (idx1 == idx2) {
        TRACE_FLOW_STRING("ref_array_swap", "Noop return");
        return EOK;
    }

    temp = malloc(ra->elsize);
    if (!temp) {
        TRACE_FLOW_STRING("Failed to allocate memory for temp storage.", "");
        return ENOMEM;
    }

    memcpy(temp,
           (unsigned char *)(ra->storage) +  idx2 * ra->elsize,
           ra->elsize);
    memcpy((unsigned char *)(ra->storage) +  idx2 * ra->elsize,
           (unsigned char *)(ra->storage) +  idx1 * ra->elsize,
           ra->elsize);
    memcpy((unsigned char *)(ra->storage) +  idx1 * ra->elsize,
           temp,
           ra->elsize);

    free(temp);

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #24
0
/* Process comment */
static int handle_comment(struct parser_obj *po, uint32_t *action)
{
    int error = EOK;

    TRACE_FLOW_ENTRY();

    /* We got a comment */
    if (po->key) {
        /* Previous value if any is complete */
        error = complete_value_processing(po);
        if (error) {
            TRACE_ERROR_NUMBER("Failed to finish saving value", error);
            return error;
        }
    }

    if (!(po->ic)) {
        /* Create a new comment */
        error = ini_comment_create(&(po->ic));
        if (error) {
            TRACE_ERROR_NUMBER("Failed to create comment", error);
            return error;
        }
    }

    /* Add line to comment */
    error = ini_comment_build_wl(po->ic,
                                 po->last_read,
                                 po->last_read_len);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to add line to comment", error);
        return error;
    }
    /*
     * We are done with the comment line.
     * Free it since comment keeps a copy.
     */
    free(po->last_read);
    po->last_read = NULL;
    po->last_read_len = 0;
    *action = PARSE_READ;

    TRACE_FLOW_EXIT();
    return EOK;
}
Beispiel #25
0
static unsigned long get_checked_value(struct collection_item *metadata,
                                       const char *key,
                                       int *err)
{

    int error = EOK;
    struct collection_item *item = NULL;
    unsigned long value;

    TRACE_FLOW_STRING("get_checked_value", "Entry");
    TRACE_INFO_STRING("Key", key);

    error = get_config_item(INI_META_SEC_ACCESS,
                            key,
                            metadata,
                            &item);
    if (error) {
        TRACE_ERROR_NUMBER("Internal collection error.", error);
        *err = error;
        return 0;
    }

    /* Entry is supposed to be there so it is an error
     * is the item is not found.
     */
    if (item == NULL) {
        TRACE_ERROR_NUMBER("Expected item is not found.", ENOENT);
        *err = ENOENT;
        return 0;
    }

    value = get_ulong_config_value(item, 1, -1, &error);
    if ((error) || (value == -1)) {
        TRACE_ERROR_NUMBER("Conversion failed", EINVAL);
        *err = EINVAL;
        return 0;
    }

    *err = 0;

    TRACE_FLOW_NUMBER("get_checked_value Returning", value);
    return value;

}
Beispiel #26
0
/* Copy configuration */
int ini_config_copy(struct ini_cfgobj *ini_config,
                    struct ini_cfgobj **ini_new)
{
    int error = EOK;
    struct ini_cfgobj *new_co;

    TRACE_FLOW_ENTRY();

    if ((!ini_config) ||
        (!ini_new)) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    /* Create a new configuration object */
    errno = 0;
    new_co = malloc(sizeof(struct ini_cfgobj));
    if (!new_co) {
        error = errno;
        TRACE_ERROR_NUMBER("Failed to allocate memory", ENOMEM);
        return ENOMEM;
    }

    new_co->cfg = NULL;
    new_co->boundary = ini_config->boundary;

    error = col_copy_collection_with_cb(&(new_co->cfg),
                                        ini_config->cfg,
                                        INI_CONFIG_NAME,
                                        COL_COPY_NORMAL,
                                        ini_copy_cb,
                                        NULL);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to copy collection", error);
        ini_config_destroy(new_co);
        return error;
    }

    *ini_new = new_co;

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #27
0
/* Create referenced array */
int ref_array_create(struct ref_array **ra,
                     size_t elemsz,
                     uint32_t grow_by,
                     ref_array_fn cb,
                     void *data)
{
    struct ref_array *new_ra = NULL;

    TRACE_FLOW_ENTRY();

    if (!ra) {
        TRACE_ERROR_NUMBER("Uninitialized argument.", EINVAL);
        return EINVAL;
    }

    if ((!elemsz) || (!grow_by)) {
        TRACE_ERROR_NUMBER("Invalid argument.", EINVAL);
        return EINVAL;
    }

    new_ra = (struct ref_array *)malloc(sizeof(struct ref_array));

    if (!new_ra) {
        TRACE_ERROR_NUMBER("Failed to allocate memory.", ENOMEM);
        return ENOMEM;
    }

    new_ra->storage = NULL;
    new_ra->elsize = elemsz;
    new_ra->size = 0;
    new_ra->grow_by = grow_by;
    new_ra->len = 0;
    new_ra->refcount = 1;
    new_ra->cb = cb;
    new_ra->cb_data = data;

    *ra = new_ra;

    TRACE_FLOW_EXIT();
    return EOK;
}
Beispiel #28
0
/* Create a pair of arrays */
int value_create_arrays(struct ref_array **raw_lines,
                        struct ref_array **raw_lengths)
{
    int error = EOK;
    struct ref_array *new_lines = NULL;
    struct ref_array *new_lengths = NULL;

    TRACE_FLOW_ENTRY();

    error = ref_array_create(&new_lines,
                             sizeof(char *),
                             INI_ARRAY_GROW,
                             value_lines_cleanup_cb,
                             NULL);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create lines array", error);
        return error;

    }

    error = ref_array_create(&new_lengths,
                             sizeof(uint32_t),
                             INI_ARRAY_GROW,
                             NULL,
                             NULL);
    if (error) {
        TRACE_ERROR_NUMBER("Failed to create lengths array", error);
        ref_array_destroy(new_lines);
        return error;

    }

    *raw_lines = new_lines;
    *raw_lengths = new_lengths;

    TRACE_FLOW_EXIT();
    return EOK;
}
Beispiel #29
0
/* Create a config object */
int ini_config_create(struct ini_cfgobj **ini_config)
{
    int error = EOK;
    struct ini_cfgobj *new_co = NULL;

    TRACE_FLOW_ENTRY();

    if (!ini_config) {
        TRACE_ERROR_NUMBER("Invalid argument", EINVAL);
        return EINVAL;
    }

    errno = 0;
    new_co = malloc(sizeof(struct ini_cfgobj));
    if (!new_co) {
        error = errno;
        TRACE_ERROR_NUMBER("Failed to allocate memory", ENOMEM);
        return ENOMEM;
    }

    new_co->cfg = NULL;
    new_co->boundary = INI_WRAP_BOUNDARY;

    /* Create a collection to hold configuration data */
    error = col_create_collection(&(new_co->cfg),
                                  INI_CONFIG_NAME,
                                  COL_CLASS_INI_CONFIG);
    if (error != EOK) {
        TRACE_ERROR_NUMBER("Failed to create collection.", error);
        ini_config_destroy(new_co);
        return error;
    }

    *ini_config = new_co;

    TRACE_FLOW_EXIT();
    return error;
}
Beispiel #30
0
/* Get value's line */
int value_get_line(struct value_obj *vo, uint32_t *line)
{
    TRACE_FLOW_ENTRY();

    if (!vo) {
        TRACE_ERROR_NUMBER("Invalid object", EINVAL);
        return EINVAL;
    }

    *line = vo->line;

    TRACE_FLOW_EXIT();
    return EOK;
}