/* 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; }
/* 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"); }
/* Print errors and warnings that were detected while parsing * the whole configuration */ void print_config_parsing_errors(FILE *file, struct collection_item *error_list) { struct collection_iterator *iterator; int error; struct collection_item *item = NULL; struct collection_item *file_errors = NULL; TRACE_FLOW_STRING("print_config_parsing_errors", "Entry"); /* If we have something to print print it */ if (error_list == NULL) { TRACE_ERROR_STRING("No error list", ""); return; } /* Make sure we go the right collection */ if (!col_is_of_class(error_list, COL_CLASS_INI_PESET)) { TRACE_ERROR_STRING("Wrong collection class:", WRONG_COLLECTION); fprintf(file, "%s\n", WRONG_COLLECTION); return; } /* Bind iterator */ error = col_bind_iterator(&iterator, error_list, COL_TRAVERSE_DEFAULT); if (error) { TRACE_ERROR_STRING("Error (bind):", FAILED_TO_PROCCESS); fprintf(file,"%s\n", FAILED_TO_PROCCESS); return; } while(1) { /* Loop through a collection */ error = col_iterate_collection(iterator, &item); if (error) { TRACE_ERROR_STRING("Error (iterate):", FAILED_TO_PROCCESS); fprintf(file, "%s\n", FAILED_TO_PROCCESS); col_unbind_iterator(iterator); return; } /* Are we done ? */ if (item == NULL) break; /* Print per file sets of errors */ if (col_get_item_type(item) == COL_TYPE_COLLECTIONREF) { /* Extract a sub collection */ error = col_get_reference_from_item(item, &file_errors); if (error) { TRACE_ERROR_STRING("Error (extract):", FAILED_TO_PROCCESS); fprintf(file, "%s\n", FAILED_TO_PROCCESS); col_unbind_iterator(iterator); return; } print_file_parsing_errors(file, file_errors); col_destroy_collection(file_errors); } } /* Do not forget to unbind iterator - otherwise there will be a leak */ col_unbind_iterator(iterator); TRACE_FLOW_STRING("print_config_parsing_errors", "Exit"); }
int stack_test(void) { struct collection_item *stack = NULL; char binary_dump[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; struct collection_item *item1 = NULL; struct collection_item *item2 = NULL; int error = EOK; TRACE_FLOW_STRING("stack_test", "Entry."); COLOUT(printf("\n\nSTACK TEST!!!.\n\n\n")); if ((error = col_create_stack(&stack)) || (error = col_push_str_property(stack, "item1", "value 1", 0)) || (error = col_push_int_property(stack, "item2", -1)) || (error = col_push_unsigned_property(stack, "item3", 1)) || (error = col_push_long_property(stack, "item4", 100)) || (error = col_push_ulong_property(stack, "item5", 1000)) || (error = col_push_double_property(stack, "item6", 1.1)) || (error = col_push_bool_property(stack, "item7", 1)) || (error = col_push_binary_property(stack, "item8", binary_dump, sizeof(binary_dump)))) { printf("Failed to push property. Error %d\n", error); col_destroy_collection(stack); return error; } COLOUT(col_debug_collection(stack, COL_TRAVERSE_DEFAULT)); COLOUT(printf("Swapping last two items by popping and pushing them back.\n")); if ((error = col_pop_item(stack, &item1)) || (error = col_pop_item(stack, &item2))) { printf("Failed to pop items. Error %d\n", error); col_destroy_collection(stack); return error; } COLOUT(printf("\nPopped two last items.\n")); COLOUT(col_debug_collection(stack, COL_TRAVERSE_DEFAULT)); COLOUT(printf("\nLast item.\n")); COLOUT(col_debug_item(item1)); COLOUT(printf("\nPrevious item.\n")); COLOUT(col_debug_item(item2)); if ((error = col_push_item(stack, item1)) || (error = col_push_item(stack, item2))) { printf("Failed to pop or push items. Error %d\n", error); col_destroy_collection(stack); return error; } COLOUT(printf("\n\nPushed two items again in reverse order.\n\n")); COLOUT(col_debug_collection(stack, COL_TRAVERSE_DEFAULT)); col_destroy_collection(stack); TRACE_FLOW_NUMBER("stack_test. Returning", error); COLOUT(printf("\n\nEND OF STACK TEST!!!.\n\n")); return error; }
/* Collect metadata for the file */ int collect_metadata(uint32_t metaflags, struct collection_item **metadata, FILE *config_file, const char *config_filename) { int error = EOK; struct collection_item *metasec = NULL; int filedes; struct stat file_stats; char buff[CONVERSION_BUFFER]; TRACE_FLOW_STRING("collect_metadata", "Entry"); /* Check and create section for file error if needed */ if (metaflags & INI_META_SEC_ACCESS_FLAG) { /* Create ACCESS collection */ error = col_create_collection(&metasec, INI_META_SEC_ACCESS, COL_CLASS_INI_SECTION); if (error) { TRACE_ERROR_NUMBER("Failed to create access section.", error); col_destroy_collection(metasec); return error; } filedes = fileno(config_file); /* Collect statistics */ errno = 0; if (fstat(filedes, &file_stats) < 0) { error = errno; TRACE_ERROR_NUMBER("Failed to get statistics.", error); col_destroy_collection(metasec); return error; } /* Record statistics */ /* UID */ snprintf(buff, CONVERSION_BUFFER, "%lu", (unsigned long)file_stats.st_uid); error = col_add_str_property(metasec, NULL, INI_META_KEY_UID, buff, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save uid", error); col_destroy_collection(metasec); return error; } /* GID */ snprintf(buff, CONVERSION_BUFFER, "%lu", (unsigned long)file_stats.st_gid); error = col_add_str_property(metasec, NULL, INI_META_KEY_GID, buff, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save gid", error); col_destroy_collection(metasec); return error; } /* PERMISSIONS */ snprintf(buff, CONVERSION_BUFFER, "%lu", (unsigned long)file_stats.st_mode); error = col_add_str_property(metasec, NULL, INI_META_KEY_PERM, buff, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save permissions", error); col_destroy_collection(metasec); return error; } /* Modification time stamp */ snprintf(buff, CONVERSION_BUFFER, "%ld", (long int)file_stats.st_mtime); error = col_add_str_property(metasec, NULL, INI_META_KEY_MODIFIED, buff, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save modification time", error); col_destroy_collection(metasec); return error; } /* Name */ error = col_add_str_property(metasec, NULL, INI_META_KEY_NAME, config_filename, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save file name", error); col_destroy_collection(metasec); return error; } /* The device ID can actualy be bigger than * 32-bits according to the type sizes. * However it is probaly not going to happen * on a real system. * Add a check for this case. */ if (file_stats.st_dev > ULONG_MAX) { TRACE_ERROR_NUMBER("Device is out of range", ERANGE); col_destroy_collection(metasec); return ERANGE; } /* Device ID */ TRACE_INFO_LNUMBER("Device ID", file_stats.st_dev); snprintf(buff, CONVERSION_BUFFER, "%lu", (unsigned long)file_stats.st_dev); error = col_add_str_property(metasec, NULL, INI_META_KEY_DEV, buff, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save inode", error); col_destroy_collection(metasec); return error; } /* i-node */ snprintf(buff, CONVERSION_BUFFER, "%lu", (unsigned long)file_stats.st_ino); error = col_add_str_property(metasec, NULL, INI_META_KEY_INODE, buff, 0); if (error) { TRACE_ERROR_NUMBER("Failed to save inode", error); col_destroy_collection(metasec); return error; } /* Add section to metadata */ error = col_add_collection_to_collection( *metadata, NULL, NULL, metasec, COL_ADD_MODE_REFERENCE); col_destroy_collection(metasec); if (error) { TRACE_ERROR_NUMBER("Failed to save file name", error); return error; } } TRACE_FLOW_STRING("collect_metadata", "Exit"); return error; }
/* Function to free metadata */ void free_ini_config_metadata(struct collection_item *metadata) { TRACE_FLOW_STRING("free_ini_config_metadata", "Entry"); col_destroy_collection(metadata); TRACE_FLOW_STRING("free_ini_config_metadata", "Exit"); }