/* Push a bool property. */
int col_push_bool_property(struct collection_item *stack,
                           const char *property,
                           unsigned char logical)
{
    int error = EOK;

    TRACE_FLOW_STRING("col_push_bool_property", "Entry point.");

    /* Check that stack is not empty */
    if (stack == NULL) {
        TRACE_ERROR_STRING("Stack can't be NULL", "");
        return EINVAL;
    }

    /* Make sure it is a stack */
    if (!col_is_of_class(stack, COL_CLASS_STACK)) {
        TRACE_ERROR_STRING("Wrong class", "");
        return EINVAL;
    }

    error = col_add_bool_property(stack, NULL, property, logical);

    TRACE_FLOW_STRING("push_double_property", "Exit.");
    return error;
}
/* Pop_item */
int col_pop_item(struct collection_item *stack,
                 struct collection_item **item)
{
    int error = EOK;

    TRACE_FLOW_STRING("col_pop_item", "Entry point.");

    /* Check that stack is not empty */
    if (stack == NULL) {
        TRACE_ERROR_STRING("Stack can't be NULL", "");
        return EINVAL;
    }

    /* Make sure it is a stack */
    if (!col_is_of_class(stack, COL_CLASS_STACK)) {
        TRACE_ERROR_STRING("Wrong class", "");
        return EINVAL;
    }

    error = col_extract_item_from_current(stack,
                                          COL_DSP_END,
                                          NULL,
                                          0,
                                          0,
                                          item);

    TRACE_FLOW_STRING("col_pop_item", "Exit.");
    return error;
}
/* Push a binary property to stack.  */
int col_push_binary_property(struct collection_item *stack,
                             const char *property,
                             void *binary_data,
                             int length)
{
    int error = EOK;

    TRACE_FLOW_STRING("col_push_binary_property", "Entry point.");

    /* Check that stack is not empty */
    if (stack == NULL) {
        TRACE_ERROR_STRING("Stack can't be NULL", "");
        return EINVAL;
    }

    /* Make sure it is a stack */
    if (!col_is_of_class(stack, COL_CLASS_STACK)) {
        TRACE_ERROR_STRING("Wrong class", "");
        return EINVAL;
    }

    error = col_add_binary_property(stack, NULL, property, binary_data, length);

    TRACE_FLOW_STRING("col_push_binary_property", "Exit.");
    return error;
}
Beispiel #4
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;
}
/* Pins down the iterator to loop around this point */
void col_pin_iterator(struct collection_iterator *iterator)
{
    TRACE_FLOW_STRING("col_iterator_add_pin", "Entry");

    if ((!iterator) || (!iterator->stack)) {
        TRACE_FLOW_STRING("Invalid itertor", "Ingoring");
        return;
    }

    while ((iterator->stack_depth) &&
           (iterator->stack[iterator->stack_depth - 1] == NULL)) {
        iterator->stack_depth--;
    }

    if (iterator->stack_depth == 0) {
        iterator->pin = iterator->top;
        iterator->pin_level = 0;
    }
    else {
        iterator->pin = iterator->stack[iterator->stack_depth - 1];
        iterator->pin_level = iterator->stack_depth - 1;
    }
    iterator->can_break = 0;

    TRACE_FLOW_STRING("col_iterator_add_pin", "Exit");
}
/* Function that destroys a stack object */
void col_destroy_stack(struct collection_item *stack)
{
    TRACE_FLOW_STRING("col_destroy_stack", "Entry point.");

    col_destroy_collection(stack);

    TRACE_FLOW_STRING("col_destroy_stack", "Exit");
}
/* Unbind the iterator from the collection */
void col_unbind_iterator(struct collection_iterator *iterator)
{
    TRACE_FLOW_STRING("col_unbind_iterator", "Entry.");
    if (iterator != NULL) {
        col_destroy_collection(iterator->top);
        col_delete_item(iterator->end_item);
        free(iterator->stack);
        free(iterator);
    }
    TRACE_FLOW_STRING("col_unbind_iterator", "Exit");
}
/* Function that creates a stack object */
int col_create_stack(struct collection_item **stack)
{
    int error = EOK;

    TRACE_FLOW_STRING("col_create_stack", "Entry point.");

    error = col_create_collection(stack, COL_NAME_STACK, COL_CLASS_STACK);

    TRACE_FLOW_STRING("col_create_stack", "Exit.");
    return error;
}
Beispiel #9
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 #10
0
/* What was the level of the last item we got? */
int col_get_item_depth(struct collection_iterator *iterator, int *depth)
{
    TRACE_FLOW_STRING("col_get_item_depth", "Entry");

    if ((iterator == NULL) || (depth == NULL)) {
        TRACE_ERROR_NUMBER("Invalid parameter.", EINVAL);
        return EINVAL;
    }

    *depth = iterator->item_level;

    TRACE_INFO_NUMBER("Item level at the end:", iterator->item_level);
    TRACE_FLOW_STRING("col_get_item_depth","Exit");
    return EOK;
}
Beispiel #11
0
/* Function to free the list of properties. */
void col_free_property_list(char **str_list)
{
    int current = 0;

    TRACE_FLOW_STRING("col_free_property_list","Entry");

    if (str_list != NULL) {
        while(str_list[current]) {
            free(str_list[current]);
            current++;
        }
        free(str_list);
    }

    TRACE_FLOW_STRING("col_free_property_list","Exit");
}
Beispiel #12
0
/* Print the collection using default serialization */
int col_print_collection(struct collection_item *handle)
{
    struct col_serial_data buf_data;
    int error = EOK;

    TRACE_FLOW_STRING("col_print_collection", "Entry");

    printf("COLLECTION:\n");

    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_serialize, (void *)(&buf_data));
    if (error)
        printf("Error traversing collection %d\n", error);
    else
        printf("%s\n", buf_data.buffer);

    free(buf_data.buffer);

    TRACE_FLOW_NUMBER("col_print_collection returning", error);
    return error;
}
Beispiel #13
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 #14
0
/* Find and print one item using default serialization */
int col_print_item(struct collection_item *handle, const char *name)
{
    struct col_serial_data buf_data;
    int error = EOK;

    TRACE_FLOW_STRING("col_print_item", "Entry");

    printf("PRINT ITEM:\n");

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

    error =  col_get_item_and_do(handle, name, COL_TYPE_ANY,
                                 COL_TRAVERSE_DEFAULT,
                                 col_serialize, &buf_data);
    if(error) printf("Error searching collection %d\n", error);
    else {
        if (buf_data.buffer != NULL) {
            if (buf_data.length > 0) buf_data.length--;
            buf_data.buffer[buf_data.length] = '\0',
                                               printf("%s\n", buf_data.buffer);
            free(buf_data.buffer);
        }
        else {
            printf("Name %s is not found in the collection %s.\n",
                   name, handle->property);
        }
    }

    TRACE_FLOW_NUMBER("col_print_item returning", error);
    return error;
}
Beispiel #15
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 #16
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 #17
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 #18
0
/* Rewinds iterator to the beginning */
void col_rewind_iterator(struct collection_iterator *iterator)
{
    TRACE_FLOW_STRING("col_rewind_iterator", "Entry");

    if ((!iterator) || (!iterator->stack)) {
        TRACE_FLOW_STRING("Invalid itertor", "Ingoring");
        return;
    }

    iterator->pin = iterator->top;
    iterator->stack[0] = iterator->top;
    iterator->stack_depth = 1;
    iterator->item_level = 0;
    iterator->pin_level = 0;
    iterator->can_break = 0;

    TRACE_FLOW_STRING("col_rewind_iterator", "Exit");
}
Beispiel #19
0
/* Function to check uid or gid */
static int check_id(struct collection_item *metadata,
                    unsigned long id,
                    const char *key)
{
    int error = EOK;
    struct collection_item *item = NULL;
    unsigned long fid;

    TRACE_FLOW_STRING("check_id", "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);
        return error;
    }

    /* 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);
        return ENOENT;
    }

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

    if (id != fid) {
        TRACE_ERROR_NUMBER("File ID:", fid);
        TRACE_ERROR_NUMBER("ID passed in.", id);
        TRACE_ERROR_NUMBER("Access denied.", EACCES);
        return EACCES;
    }

    TRACE_FLOW_STRING("check_id", "Exit");
    return EOK;
}
Beispiel #20
0
/* Specail function to add different formatting symbols to the output */
int col_put_marker(struct col_serial_data *buf_data, const void *data, int len)
{
    int error = EOK;

    TRACE_FLOW_STRING("col_put_marker", "Entry point");
    TRACE_INFO_NUMBER("Marker length: ", len);

    error = col_grow_buffer(buf_data, len);
    if (error) {
        TRACE_ERROR_NUMBER("col_grow_buffer failed with: ", error);
        return error;
    }
    memcpy(buf_data->buffer + buf_data->length, data, len);
    buf_data->length += len;
    buf_data->buffer[buf_data->length] = '\0';

    TRACE_FLOW_STRING("col_put_marker","Success exit");
    return error;
}
Beispiel #21
0
/* Grow iteration stack */
static int col_grow_stack(struct collection_iterator *iterator, unsigned desired)
{
    int grow_by = 0;
    struct collection_item **temp;

    TRACE_FLOW_STRING("col_grow_stack", "Entry.");

    if (desired > iterator->stack_size) {
        grow_by = (((desired - iterator->stack_size) / STACK_DEPTH_BLOCK) + 1) * STACK_DEPTH_BLOCK;
        temp = (struct collection_item **)realloc(iterator->stack, grow_by * sizeof(struct collection_item *));
        if (temp == NULL) {
            TRACE_ERROR_NUMBER("Failed to allocate memory", ENOMEM);
            return ENOMEM;
        }
        iterator->stack = temp;
        iterator->stack_size += grow_by;
    }
    TRACE_FLOW_STRING("col_grow_stack", "Exit.");
    return EOK;
}
Beispiel #22
0
/* Stop processing this subcollection and move to the next item in the
 * collection 'level' levels up.*/
int col_iterate_up(struct collection_iterator *iterator, unsigned level)
{
    TRACE_FLOW_STRING("iterate_up", "Entry");

    if (iterator == NULL) {
        TRACE_ERROR_NUMBER("Invalid parameter.", EINVAL);
        return EINVAL;
    }

    TRACE_INFO_NUMBER("Going up:", level);
    TRACE_INFO_NUMBER("Current stack depth:", iterator->stack_depth);

    /* If level is big just move to the top,
     * that will end the iteration process.
     */
    if (level >= iterator->stack_depth) iterator->stack_depth = 0;
    else iterator->stack_depth -= level;

    TRACE_INFO_NUMBER("Stack depth at the end:", iterator->stack_depth);
    TRACE_FLOW_STRING("col_iterate_up", "Exit");
    return EOK;
}
Beispiel #23
0
/* Print collection for debugging purposes */
int col_debug_collection(struct collection_item *handle, int flag)
{
    int error = EOK;
    int nest_level = 0;

    TRACE_FLOW_STRING("col_debug_collection", "Entry.");

    printf("DEBUG COLLECTION %s\n", handle->property);

    flag |= COL_TRAVERSE_END;

    printf("Traverse flags %d\n", flag);

    /* Traverse collection */
    error = col_traverse_collection(handle, flag,
                                    col_debug_handle,
                                    (void *)(&nest_level));
    if (error) printf("Error debuging collection %d\n", error);

    TRACE_FLOW_STRING("col_debug_collection", "Exit.");
    return error;
}
Beispiel #24
0
/* Calculate the potential size of the item */
int col_get_data_len(int type, int length)
{
    int len = 0;

    TRACE_FLOW_STRING("col_get_data_len", "Entry point");

    switch (type) {
    case COL_TYPE_INTEGER:
    case COL_TYPE_UNSIGNED:
        len = 11;
        break;
    case COL_TYPE_LONG:
    case COL_TYPE_ULONG:
        len = 20;
        break;

    case COL_TYPE_STRING:
    case COL_TYPE_BINARY:
        len = length * 2 + 2;
        break;

    case COL_TYPE_DOUBLE:
        len = 64;
        break;

    case COL_TYPE_BOOL:
        len = 6;
        break;

    default:
        len = 0;
        break;
    }

    TRACE_FLOW_STRING("col_get_data_len","Exit point");

    return len;
}
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
/* Function to print errors from the list */
void ini_print_errors(FILE *file, char **error_list)
{
    unsigned count = 0;

    TRACE_FLOW_ENTRY();

    if (!error_list) {
        TRACE_FLOW_STRING("List is empty.", "");
        return;
    }

    while (error_list[count]) {
        fprintf(file, "%s\n", error_list[count]);
        count++;
    }

    TRACE_FLOW_EXIT();
    return;
}
Beispiel #27
0
/* Function to read next line from the file */
static int parser_read(struct parser_obj *po)
{
    int error = EOK;
    char *buffer = NULL;
    ssize_t res = 0;
    size_t len = 0;
    int32_t i = 0;
    uint32_t action;

    TRACE_FLOW_ENTRY();

    /* Adjust line number */
    (po->linenum)++;

    /* Get line from the file */
    res = getline(&buffer, &len, po->file);
    if (res == -1) {
        if (feof(po->file)) {
            TRACE_FLOW_STRING("Read nothing", "");
            if (po->inside_comment) {
                action = PARSE_ERROR;
                po->last_error = ERR_BADCOMMENT;
            }
            else action = PARSE_POST;
        }
        else {
            TRACE_ERROR_STRING("Error reading", "");
            action = PARSE_ERROR;
            po->last_error = ERR_READ;
        }
        if(buffer) free(buffer);
    }
    else {
        /* Read Ok */
        len = res;
        TRACE_INFO_STRING("Read line ok:", buffer);
        TRACE_INFO_NUMBER("Length:", len);
        TRACE_INFO_NUMBER("Strlen:", strlen(buffer));

        if (buffer[0] == '\0') {
            /* Empty line - read again (should not ever happen) */
            action = PARSE_READ;
            free(buffer);
        }
        else {
            /* Check length */
            if (len >= BUFFER_SIZE) {
                TRACE_ERROR_STRING("Too long", "");
                action = PARSE_ERROR;
                po->last_error = ERR_LONGDATA;
                free(buffer);
            }
            else {
                /* Trim end line */
                i = len - 1;
                while ((i >= 0) &&
                       ((buffer[i] == '\r') ||
                        (buffer[i] == '\n'))) {
                    TRACE_INFO_NUMBER("Offset:", i);
                    TRACE_INFO_NUMBER("Code:", buffer[i]);
                    buffer[i] = '\0';
                    i--;
                }

                po->last_read = buffer;
                po->last_read_len = i + 1;
                action = PARSE_INSPECT;
                TRACE_INFO_STRING("Line:", po->last_read);
                TRACE_INFO_NUMBER("Linelen:", po->last_read_len);
            }
        }
    }

    /* 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 EOK;
}
Beispiel #28
0
/* Use JSON formal for serialization */
int col_json(const char *property_in,
             int property_len_in,
             int type,
             void *data_in,
             int length_in,
             void *custom_data,
             int *dummy)
{
    int len;
    struct col_serial_data *buf_data;
    const char *property;
    const void *data;
    int  property_len;
    int length;
    int error = EOK;
    int i;

    TRACE_FLOW_STRING("col_json","Entry point");

    *dummy = 0;

    /* Check is there is buffer. If not allocate */
    buf_data = (struct col_serial_data *)custom_data;
    if (buf_data == NULL) {
        TRACE_ERROR_STRING("Error.", "Storage data is not passed in!");
        return EINVAL;
    }
    if (buf_data->buffer == NULL) {
        TRACE_INFO_STRING("First time use.", "Allocating buffer.");
        buf_data->buffer = malloc(BLOCK_SIZE);
        if (buf_data->buffer == NULL) {
            TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", ENOMEM);
            return ENOMEM;
        }
        buf_data->buffer[0] = '\0';
        buf_data->length = 0;
        buf_data->size = BLOCK_SIZE;
    }

    TRACE_INFO_NUMBER("Buffer len: ", buf_data->length);
    TRACE_INFO_NUMBER("Buffer size: ", buf_data->size);
    TRACE_INFO_STRING("Buffer: ", buf_data->buffer);

    /* Check the beginning of the collection */
    if (type == COL_TYPE_COLLECTION) {
        TRACE_INFO_STRING("Serializing collection: ", property_in);
        TRACE_INFO_STRING("First header. ", "");
        error = col_put_marker(buf_data, "{", 1);
        if (error != EOK) return error;
        property = TEXT_EVENT;
        property_len = TEXT_EVENTLEN;
        data = property_in;
        length = property_len_in + 1;
        type = COL_TYPE_STRING;
        buf_data->nest_level++;
    }
    /* Check for subcollections */
    else if (type == COL_TYPE_COLLECTIONREF) {
        /* Skip */
        TRACE_FLOW_STRING("col_serialize", "skip reference return");
        return EOK;
    }
    /* Check for the end of the collection */
    else if (type == COL_TYPE_END) {
        if ((buf_data->length > 0) &&
                (buf_data->buffer[buf_data->length-1] == ',')) {
            buf_data->length--;
            buf_data->buffer[buf_data->length] = '\0';
        }
        if (buf_data->nest_level > 0) {
            buf_data->nest_level--;
            error = col_put_marker(buf_data, "}", 1);
            if (error != EOK) return error;
        }
        TRACE_FLOW_STRING("col_serialize", "end collection item processed returning");
        return EOK;
    }
    else {
        property = property_in;
        property_len = property_len_in;
        data = data_in;
        length = length_in;
    }

    TRACE_INFO_STRING("Property: ", property);
    TRACE_INFO_NUMBER("Property length: ", property_len);

    /* Start with property and ":" */
    if ((error = col_put_marker(buf_data, "\"", 1)) ||
            (error = col_put_marker(buf_data, property, property_len)) ||
            (error = col_put_marker(buf_data, "\":", 2))) {
        TRACE_ERROR_NUMBER("put_marker returned error: ", error);
        return error;
    }
    /* Get projected length of the item */
    len = col_get_data_len(type,length);
    TRACE_INFO_NUMBER("Expected data length: ",len);
    TRACE_INFO_STRING("Buffer so far: ", buf_data->buffer);

    /* Make sure we have enough space */
    if ((error = col_grow_buffer(buf_data, len))) {
        TRACE_ERROR_NUMBER("grow_buffer returned error: ", error);
        return error;
    }

    /* Add the value */
    switch (type) {
    case COL_TYPE_STRING:
        /* Escape double quotes */
        len = col_copy_esc(&buf_data->buffer[buf_data->length],
                           (const char *)(data), '"');
        break;

    case COL_TYPE_BINARY:
        buf_data->buffer[buf_data->length] = '\'';
        for (i = 0; i < length; i++)
            sprintf(&buf_data->buffer[buf_data->length + i *2] + 1,
                    "%02X", (unsigned int)(((const unsigned char *)(data))[i]));
        len = length * 2 + 1;
        buf_data->buffer[buf_data->length + len] = '\'';
        len++;
        break;

    case COL_TYPE_INTEGER:
        len = sprintf(&buf_data->buffer[buf_data->length],
                      "%d", *((const int32_t *)(data)));
        break;

    case COL_TYPE_UNSIGNED:
        len = sprintf(&buf_data->buffer[buf_data->length],
                      "%u", *((const uint32_t *)(data)));
        break;

    case COL_TYPE_LONG:
        len = sprintf(&buf_data->buffer[buf_data->length],
                      "%lld",
                      (long long int)(*((const int64_t *)(data))));
        break;

    case COL_TYPE_ULONG:
        len = sprintf(&buf_data->buffer[buf_data->length],
                      "%llu",
                      (long long unsigned)(*((const uint64_t *)(data))));
        break;

    case COL_TYPE_DOUBLE:
        len = sprintf(&buf_data->buffer[buf_data->length],
                      "%.4f", *((const double *)(data)));
        break;

    case COL_TYPE_BOOL:
        len = sprintf(&buf_data->buffer[buf_data->length],
                      "%s", (*((const unsigned char *)(data))) ? "true" : "false");
        break;

    default:
        buf_data->buffer[buf_data->length] = '\0';
        len = 0;
        break;
    }

    /* Adjust length */
    buf_data->length += len;
    buf_data->buffer[buf_data->length] = '\0';

    /* Always put a comma at the end */
    error = col_put_marker(buf_data, ",", 1);
    if (error != EOK) {
        TRACE_ERROR_NUMBER("put_marker returned error: ", error);
        return error;
    }

    TRACE_INFO_STRING("Data: ", buf_data->buffer);
    TRACE_FLOW_STRING("col_json", "Exit point");
    return EOK;

}
Beispiel #29
0
/* Debug handle */
int col_debug_handle(const char *property,
                     int property_len,
                     int type,
                     void *data,
                     int length,
                     void *custom_data,
                     int *dummy)
{
    int i;
    int nest_level;
    int ignore = 0;

    TRACE_FLOW_STRING("col_debug_handle", "Entry.");


    nest_level = *(int *)(custom_data);
    if (nest_level == -1) {
        ignore = 1;
        nest_level = 1;
    }

    TRACE_INFO_NUMBER("We are getting this pointer:", custom_data);
    TRACE_INFO_NUMBER("Nest level:", nest_level);

    switch (type) {
    case COL_TYPE_STRING:
        printf(">%*s%s[%d] str: %s (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               (char *)(data),
               nest_level);
        break;
    case COL_TYPE_BINARY:
        printf(">%*s%s[%d] bin: ",
               (nest_level -1) * 4, "",
               property,
               length);
        for (i = 0; i < length; i++)
            printf("%02X", ((unsigned char *)(data))[i]);
        printf(" (%d)\n", nest_level);
        break;
    case COL_TYPE_INTEGER:
        printf(">%*s%s[%d] int: %d (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               *((int32_t *)(data)),
               nest_level);
        break;
    case COL_TYPE_UNSIGNED:
        printf(">%*s%s[%d] uint: %u (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               *((uint32_t *)(data)),
               nest_level);
        break;
    case COL_TYPE_LONG:
        printf(">%*s%s[%d] long: %lld (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               (long long int)(*((int64_t *)(data))),
               nest_level);
        break;
    case COL_TYPE_ULONG:
        printf(">%*s%s[%d] ulong: %llu (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               (long long unsigned)(*((uint64_t *)(data))),
               nest_level);
        break;
    case COL_TYPE_DOUBLE:
        printf(">%*s%s[%d] double: %.4f (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               *((double *)(data)),
               nest_level);
        break;
    case COL_TYPE_BOOL:
        printf(">%*s%s[%d] bool: %s (%d)\n",
               (nest_level -1) * 4, "",
               property,
               length,
               (*((unsigned char *)(data)) == '\0') ? "false" : "true",
               nest_level);
        break;
    case COL_TYPE_COLLECTION:
        if (!ignore) nest_level++;
        printf(">%*s%s[%d] header: count %d, ref_count %d class %d data: ",
               (nest_level -1) * 4, "",
               property,
               length,
               ((struct collection_header *)(data))->count,
               ((struct collection_header *)(data))->reference_count,
               ((struct collection_header *)(data))->cclass);
        for (i = 0; i < length; i++)
            printf("%02X", ((unsigned char *)(data))[i]);
        printf(" (%d)\n", nest_level);
        break;
    case COL_TYPE_COLLECTIONREF:
        printf(">%*s%s[%d] external link: ",
               (nest_level -1) * 4, "",
               property,
               length);
        for (i = 0; i < length; i++)
            printf("%02X", ((unsigned char *)(data))[i]);
        printf(" (%d)\n", nest_level);
        break;
    case COL_TYPE_END:
        printf(">%*sEND[N/A] (%d)\n",
               (nest_level -1) * 4, "",
               nest_level);
        if (!ignore) nest_level--;
        break;
    default:
        printf("Not implemented yet.\n");
        break;
    }
    *(int *)(custom_data) = nest_level;
    TRACE_INFO_NUMBER("Nest level at the end:", nest_level);
    TRACE_FLOW_STRING("col_debug_handle", "Success exit.");
    return EOK;
}
Beispiel #30
0
/* Bind iterator to a collection */
int col_bind_iterator(struct collection_iterator **iterator,
                      struct collection_item *ci,
                      int mode_flags)
{
    int error;
    struct collection_header *header;
    struct collection_iterator *iter = NULL;

    TRACE_FLOW_STRING("col_bind_iterator", "Entry.");

    /* Do some argument checking first */
    if ((iterator == NULL) || (ci == NULL)) {
        TRACE_ERROR_NUMBER("Invalid parameter.", EINVAL);
        return EINVAL;
    }

    iter = (struct collection_iterator *)malloc(sizeof(struct collection_iterator));
    if (iter == NULL) {
        TRACE_ERROR_NUMBER("Error allocating memory for the iterator.", ENOMEM);
        return ENOMEM;
    }

    /* Allocate memory for the stack */
    iter->stack = NULL;
    iter->stack_size = 0;
    iter->stack_depth = 0;
    iter->item_level = 0;
    iter->flags = mode_flags;
    iter->pin_level = 0;
    iter->can_break = 0;

    TRACE_INFO_NUMBER("Iterator flags", iter->flags);

    /* Allocate memory for stack */
    error = col_grow_stack(iter, 1);
    if(error) {
        free(iter);
        TRACE_ERROR_NUMBER("Error growing stack.", error);
        return error;
    }

    /* Create a special end item */
    error = col_allocate_item(&(iter->end_item), "", NULL, 0, COL_TYPE_END);
    if(error) {
        free(iter);
        TRACE_ERROR_NUMBER("Error allocating end item.", error);
        return error;
    }

    /* Make sure that we tie iterator to the collection */
    header = (struct collection_header *)ci->data;
    header->reference_count++;
    iter->top = ci;
    iter->pin = ci;
    *(iter->stack) = ci;
    iter->stack_depth++;

    *iterator = iter;

    TRACE_FLOW_STRING("col_bind_iterator", "Exit");
    return EOK;
}