diff options
Diffstat (limited to 'elapi/providers/file/file_fmt_csv.c')
-rw-r--r-- | elapi/providers/file/file_fmt_csv.c | 536 |
1 files changed, 0 insertions, 536 deletions
diff --git a/elapi/providers/file/file_fmt_csv.c b/elapi/providers/file/file_fmt_csv.c deleted file mode 100644 index 1a19871..0000000 --- a/elapi/providers/file/file_fmt_csv.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - ELAPI - - Module contains functions related to outputting events in CSV format. - - Copyright (C) Dmitri Pal <dpal@redhat.com> 2009 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#define _GNU_SOURCE -#include <errno.h> /* for errors */ -#include <stdlib.h> /* for free() */ -#include <string.h> /* for strcmp() */ - -#include "collection.h" -#include "file_fmt_csv.h" -#include "collection_tools.h" -#include "ini_config.h" -#include "trace.h" -#include "config.h" - -/* Reasonable size for one event */ -/* FIXME: may be it would make sense to make it configurable ? */ -#define FILE_CSV_BLOCK 256 - -/* Calculate the potential size of the item */ -static unsigned file_csv_data_len(struct file_csv_cfg *cfg, - int type, - int raw_len) -{ - int serialized_len = 0; - - TRACE_FLOW_STRING("file_csv_data_len", "Entry point"); - - switch (type) { - case COL_TYPE_INTEGER: - case COL_TYPE_UNSIGNED: - case COL_TYPE_LONG: - case COL_TYPE_ULONG: - serialized_len = MAX_LONG_STRING_LEN; - break; - - case COL_TYPE_STRING: - if ((cfg->csvqualifier) && - (cfg->csvescchar)) serialized_len = raw_len * 2; - else serialized_len = raw_len; - break; - - case COL_TYPE_BINARY: - serialized_len = raw_len * 2; - break; - - case COL_TYPE_DOUBLE: - serialized_len = MAX_DOUBLE_STRING_LEN; - break; - - case COL_TYPE_BOOL: - serialized_len = MAX_BOOL_STRING_LEN; - break; - - default: - serialized_len = 0; - break; - } - - if (cfg->csvqualifier) serialized_len += 2; - - TRACE_FLOW_STRING("file_csv_data_len", "Exit point"); - return (uint32_t)serialized_len; -} - -/* Copy data escaping characters */ -int file_copy_esc(char *dest, - const char *source, - unsigned char what_to_esc, - unsigned char what_to_use) -{ - int i = 0; - int j = 0; - - while (source[i]) { - if ((source[i] == what_to_use) || - (source[i] == what_to_esc)) { - - dest[j] = what_to_use; - j++; - - } - dest[j] = source[i]; - i++; - j++; - } - - return j; -} - -/* Serialize item into the csv format */ -int file_serialize_csv(struct elapi_data_out *out_data, - int type, - int length, - void *data, - void *mode_cfg) -{ - int error = EOK; - struct file_csv_cfg *cfg; - uint32_t projected_len; - uint32_t used_len; - int first = 1; - int i; - - TRACE_FLOW_STRING("file_serialize_csv", "Entry"); - - cfg = (struct file_csv_cfg *)mode_cfg; - - /* Get projected length of the item */ - projected_len = file_csv_data_len(cfg, type, length); - - TRACE_INFO_NUMBER("Expected data length: ", projected_len); - - /* Make sure we have enough space */ - if (out_data->buffer != NULL) { - TRACE_INFO_STRING("Not a first time use.", "Adding length overhead"); - if (cfg->csvseparator) projected_len++; - projected_len += cfg->csvnumsp; - first = 0; - } - else { - /* Add null terminating zero */ - projected_len++; - } - - /* Grow buffer if needed */ - error = elapi_grow_data(out_data, - projected_len, - FILE_CSV_BLOCK); - if (error) { - TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", error); - return error; - } - - /* Now everything should fit */ - if (!first) { - /* Add separator if any */ - if (cfg->csvseparator) { - out_data->buffer[out_data->length] = cfg->csvseparator; - out_data->length++; - } - - /* Add spaces if any */ - memset(&out_data->buffer[out_data->length], - cfg->csvspace, - cfg->csvnumsp); - } - - /* Add qualifier */ - if (cfg->csvqualifier) { - out_data->buffer[out_data->length] = cfg->csvqualifier; - out_data->length++; - } - - /* Add the value */ - switch (type) { - case COL_TYPE_STRING: - - if ((cfg->csvqualifier) && (cfg->csvescchar)) { - /* Qualify and escape */ - used_len = file_copy_esc((char *)&out_data->buffer[out_data->length], - (const char *)(data), - cfg->csvqualifier, - cfg->csvescchar); - } - else { - /* No escaping so just copy without trailing 0 */ - /* Item's length includes trailing 0 for data items */ - used_len = length - 1; - memcpy(&out_data->buffer[out_data->length], - (const char *)(data), - used_len); - } - break; - - case COL_TYPE_BINARY: - - for (i = 0; i < length; i++) - sprintf((char *)&out_data->buffer[out_data->length + i * 2], - "%02X", (unsigned int)(((const unsigned char *)(data))[i])); - used_len = length * 2; - break; - - case COL_TYPE_INTEGER: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%d", *((const int *)(data))); - break; - - case COL_TYPE_UNSIGNED: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%u", *((const unsigned int *)(data))); - break; - - case COL_TYPE_LONG: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%ld", *((const long *)(data))); - break; - - case COL_TYPE_ULONG: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%lu", *((const unsigned long *)(data))); - break; - - case COL_TYPE_DOUBLE: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%.4f", *((const double *)(data))); - break; - - case COL_TYPE_BOOL: - used_len = sprintf((char *)&out_data->buffer[out_data->length], - "%s", - (*((const unsigned char *)(data))) ? "true" : "false"); - break; - - default: - out_data->buffer[out_data->length] = '\0'; - used_len = 0; - break; - } - - /* Adjust length */ - out_data->length += used_len; - - /* Add qualifier */ - if (cfg->csvqualifier) { - out_data->buffer[out_data->length] = cfg->csvqualifier; - out_data->length++; - } - - /* The "length" member of the structure does not account - * for the 0 symbol but we made sure that it fits - * when we asked for the memory at the top. - */ - out_data->buffer[out_data->length] = '\0'; - - TRACE_INFO_STRING("Data: ", (char *)out_data->buffer); - - TRACE_FLOW_STRING("file_serialize_csv.", "Exit"); - return error; - -} - -/* Function that reads the specific configuration - * information about the format of the output - */ -int file_get_csv_cfg(void **storage, - const char *name, - struct collection_item *ini_config, - const char *appname) -{ - int error = EOK; - struct collection_item *cfg_item = NULL; - struct file_csv_cfg *cfg= NULL; - const char *qual; - const char *sep; - const char *esc; - const char *space; - - TRACE_FLOW_STRING("file_get_csv_cfg", "Entry"); - - /* Allocate memory for configuration */ - cfg = (struct file_csv_cfg *) calloc(1, sizeof(struct file_csv_cfg)); - if (cfg == NULL) { - TRACE_ERROR_NUMBER("Failed to allocate storage for CSV configuration", ENOMEM); - return ENOMEM; - } - - /*********** Qualifier *************/ - - /* Get qualifier */ - error = get_config_item(name, - FILE_CSV_QUAL, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read qualifier attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have qualifier? */ - if (cfg_item == NULL) { - /* There is no qualifier - use default */ - cfg->csvqualifier = FILE_CSV_DEF_QUAL; - } - else { - /* Get qualifier from configuration */ - error = EOK; - qual = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - if (qual[0] == '\0') cfg->csvqualifier = '\0'; - else if(qual[1] != '\0') { - TRACE_ERROR_STRING("Qualifier has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - else cfg->csvqualifier = qual[0]; - } - - /*********** Separator *************/ - - /* Get separator */ - error = get_config_item(name, - FILE_CSV_SEP, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read separator attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have separator? */ - if (cfg_item == NULL) { - /* There is no separator - use default */ - cfg->csvseparator = FILE_CSV_DEF_SEP; - } - else { - /* Get separator from configuration */ - error = EOK; - sep = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - if (sep[0] == '\0') cfg->csvseparator = '\0'; - else if(sep[1] != '\0') { - TRACE_ERROR_STRING("Separator has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - else cfg->csvseparator = sep[0]; - } - - /*********** Escape symbol *************/ - - /* Get escape symbol */ - error = get_config_item(name, - FILE_CSV_ESCSYM, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read esc symbol attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have esc symbol? */ - if (cfg_item == NULL) { - /* There is no esc symbol - use default */ - cfg->csvescchar = FILE_CSV_DEF_ESC; - } - else { - /* Get esc symbol from configuration */ - error = EOK; - esc = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - if (esc[0] == '\0') cfg->csvescchar = '\0'; - else if(esc[1] != '\0') { - TRACE_ERROR_STRING("Esc symbol has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - else cfg->csvescchar = esc[0]; - } - - /*********** Space *************/ - - /* Get space */ - error = get_config_item(name, - FILE_CSV_SPACE, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read space attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have space? */ - if (cfg_item == NULL) { - /* There is no esc symbol - use default */ - cfg->csvspace = FILE_CSV_DEF_SPC; - } - else { - /* Get file name from configuration */ - error = EOK; - space = get_const_string_config_value(cfg_item, &error); - if (error) { - TRACE_ERROR_STRING("Failed to get value from configuration.", "Fatal Error!"); - free(cfg); - return error; - } - - /* Determine what to use as a space symbol */ - if (space[0] == '\0') cfg->csvspace = ' '; - else if(strcmp(space, FILE_CSV_SP) == 0) cfg->csvspace = ' '; - else if(strcmp(space, FILE_CSV_TAB) == 0) cfg->csvspace = '\t'; - else if(strcmp(space, FILE_CSV_CR) == 0) cfg->csvspace = '\n'; - else { - TRACE_ERROR_STRING("Esc symbol has more than one symbol.", "Fatal Error!"); - free(cfg); - return EINVAL; - } - } - - /*********** Number of spaces *************/ - /* Get number of spaces */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_CSV_NUMSP, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read number of spaces attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have number of spaces? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No attribute.", "Assume no spaces"); - cfg->csvnumsp = 0; - } - else { - cfg->csvnumsp = (uint32_t) get_unsigned_config_value(cfg_item, 1, 0, &error); - if (error) { - TRACE_ERROR_STRING("Invalid number of spaces value", "Fatal Error!"); - free(cfg); - return EINVAL; - } - /* Check for right range */ - if (cfg->csvnumsp > FILE_MAXSPACE) { - TRACE_ERROR_STRING("Too many spaces - not allowed", "Fatal Error!"); - free(cfg); - return ERANGE; - } - } - - /*********** Header *************/ - /* Next is header field */ - - cfg_item = NULL; - error = get_config_item(name, - FILE_CSV_HEADER, - ini_config, - &cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read header attribute returned error", error); - free(cfg); - return error; - } - - /* Do we have header? */ - if (cfg_item == NULL) { - /* There is no attribute - assume default */ - TRACE_INFO_STRING("No attribute.", "Assume no header"); - cfg->csvheader = 0; - } - else { - cfg->csvheader = (uint32_t) get_bool_config_value(cfg_item, '\0', &error); - if (error) { - TRACE_ERROR_STRING("Invalid csv header value", "Fatal Error!"); - free(cfg); - return EINVAL; - } - } - - *((struct file_csv_cfg **)storage) = cfg; - - TRACE_FLOW_STRING("file_get_csv_cfg", "Entry"); - return error; -} - -#ifdef ELAPI_VERBOSE - -void file_print_fmt_csv(void *data) -{ - struct file_csv_cfg *cfg; - - cfg = (struct file_csv_cfg *)(data); - if (cfg == NULL) { - printf("CSV Configuration is undefined!\n"); - return; - } - - printf("CSV Configuration:\n"); - printf(" Qualifier: "); - if (cfg->csvqualifier != '\0') printf("[%c]\n", cfg->csvqualifier); - else printf("[undefined]\n"); - - printf(" Separator: "); - if (cfg->csvseparator != '\0') printf("[%c]\n", cfg->csvseparator); - else printf("[undefined]\n"); - - printf(" Escape: "); - if (cfg->csvescchar != '\0') printf("[%c]\n", cfg->csvescchar); - else printf("[undefined]\n"); - - printf(" Space: [%c] [ASCII: %d]\n", cfg->csvspace, (int)(cfg->csvspace)); - printf(" Number of spaces: [%d]\n", cfg->csvnumsp); - printf(" Header: [%s]\n", ((cfg->csvheader > 0) ? "yes" : "no")); - printf("CSV Configuration END\n"); - -} -#endif |