summaryrefslogtreecommitdiffstats
path: root/sinks/file
diff options
context:
space:
mode:
authorDmitri Pal <dpal@dpal.csb>2009-02-23 10:38:06 -0500
committerDmitri Pal <dpal@dpal.csb>2009-02-23 10:38:06 -0500
commitd986aeb99fa33967374290bf7ce75eab76c6d446 (patch)
treee85af838cd95b43c4f1be5bc2203a1a3474ba589 /sinks/file
Initial commit.
Diffstat (limited to 'sinks/file')
-rw-r--r--sinks/file/elapi_sink_file.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/sinks/file/elapi_sink_file.c b/sinks/file/elapi_sink_file.c
new file mode 100644
index 0000000..8358854
--- /dev/null
+++ b/sinks/file/elapi_sink_file.c
@@ -0,0 +1,268 @@
+/* Copyright */
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "log_file_facility.h"
+#include "log_util.h"
+#include "log_debug.h"
+
+/******************** MAIN MODULE FUNCTIONS ****************************/
+/* Function to fill in the facility configuration */
+int create_file_facility_config(struct file_config **config, char *path, int mode)
+{
+ struct file_config *cfg = (struct file_config *)(NULL);
+
+ DEBUG_STRING("create_file_facility_config","Entry point");
+
+ errno = 0;
+
+ /* Allocate memory for the structure */
+ cfg = (struct file_config *)(malloc(sizeof(struct file_config)));
+
+ if(cfg == (struct file_config *)(NULL)) return errno;
+
+ /* Initialize. */
+ if(path != NULL) {
+ cfg->path = strdup(path);
+ if(cfg->path == NULL) {
+ free(cfg);
+ return errno;
+ }
+ }
+ else cfg->path = NULL;
+
+ cfg->mode = mode;
+ cfg->ff = NULL;
+
+ *config = cfg;
+
+ DEBUG_STRING("create_file_facility_config","Exit point");
+
+ return 0;
+
+}
+
+/* Function cleans the config */
+void clean_file_facility_config(struct file_config **config)
+{
+ DEBUG_STRING("clean_file_facility_config","Entry point");
+
+ if(config == (struct file_config **)(NULL)) return;
+
+ if(*config != (struct file_config *)(NULL)) {
+ if((*config)->path != NULL) free((*config)->path);
+ free(*config);
+ }
+
+ DEBUG_STRING("clean_file_facility_config","Exit point");
+}
+
+/***** Standard functions each facility has to provide *****/
+/* Initialize facility - open files, establish connnectons, etc... */
+int file_facility_init(struct data_descriptor *dblock)
+{
+ struct file_config *cfg;
+ struct file_event_data *event_data;
+
+ DEBUG_STRING("file_facility_init","Entry point");
+
+ /* Prepare the block where the format function will store its data */
+ errno = 0;
+ event_data = malloc(sizeof(struct file_event_data));
+ if(event_data == NULL) return errno;
+ dblock->event_data = event_data;
+
+ /* Deal with file */
+ errno = 0;
+ cfg = (struct file_config *)(dblock->config);
+
+ /* If we have "path" open file and trancate if needed */
+ if(cfg->path != NULL) {
+ if(cfg->mode & EL_FILE_TRUNCATE) {
+ cfg->ff = fopen(cfg->path,"w");
+ if(cfg->ff == (FILE *)(NULL)) return errno;
+ if(cfg->mode & EL_FILE_OPEN_PER_CMD) {
+ fclose(cfg->ff);
+ cfg->ff = NULL;
+ }
+ }
+ }
+ else {
+ cfg->ff=stderr;
+ cfg->mode = EL_FILE_KEEP_OPEN;
+ }
+
+ DEBUG_STRING("file_facility_init","Exit point");
+ return 0;
+}
+
+/* Formatting calback */
+int file_facility_format(struct data_descriptor *dblock,struct event_handle *event)
+{
+ struct file_event_data *event_data;
+ struct event_item *item = NULL;
+ int length = 0;
+ int size = EL_FILE_BLOCK_SIZE;
+ int item_len = 0;
+ int property_len = 0;
+ int nest_level = 0;
+ int cnt = 0;
+ int first = 1;
+
+ DEBUG_STRING("file_facility_format","Entry point");
+
+ event_data = dblock->event_data;
+
+ /* Prepare momory */
+ errno = 0;
+ event_data->buffer = malloc(size);
+ if(event_data->buffer == NULL) return errno;
+
+ /* Loop and add data */
+ start_iterate_event(event);
+ while((item = iterate_event(event)) != (struct event_item *)(NULL)) {
+
+ DEBUG_STRING("file_facility_format","Top of the item processing loop");
+
+ /* Check the size and increase memory if needed */
+ /* Expect more than one byte to express nesting */
+ item_len = util_get_item_len(item) + 2 * abs(item->nest_level - nest_level) + 2 * nest_level + 1;
+
+ DEBUG_NUMBER("expected item length",item_len);
+
+ if(item_len+length >= size) {
+ size+=EL_FILE_BLOCK_SIZE;
+ DEBUG_NUMBER("expanding data to the given size",size);
+ event_data->buffer = realloc(event_data->buffer,size);
+ if(event_data->buffer == NULL) return errno;
+ }
+
+ DEBUG_NUMBER("current nesting",nest_level);
+ DEBUG_NUMBER("item nesting",item->nest_level);
+
+ /* Add nesting closing parenteces */
+ cnt = 0;
+ while((item->nest_level + cnt) < nest_level) {
+ *(event_data->buffer+length)=')';
+ cnt++;
+ length++;
+ }
+
+ /* Add nesting open parenteces */
+ if(item->nest_level > nest_level) {
+ *(event_data->buffer+length)=' ';
+ length++;
+ *(event_data->buffer+length)='(';
+ length++;
+ first = 0;
+ }
+ else {
+ /* Add comma between items */
+ if(first) first = 0;
+ else {
+ *(event_data->buffer+length)=',';
+ length++;
+ }
+ }
+
+ /* Add property data pair */
+ util_add_data(event_data->buffer, &length, item);
+
+#ifdef ELAPI_LOG_DEBUG
+ *(event_data->buffer+length)='\0';
+#endif
+ DEBUG_STRING("Output",event_data->buffer);
+
+
+ nest_level = item->nest_level;
+ }
+
+ /* Add nesting closing parenteces */
+ cnt = 0;
+ while(cnt < nest_level) {
+ *(event_data->buffer+length)=')';
+ cnt++;
+ length++;
+ }
+
+ DEBUG_STRING("file_facility_format","Exit point");
+
+ return 0;
+}
+
+/* Cleanup per event internal data */
+void file_facility_cleanup(struct data_descriptor *dblock)
+{
+ struct file_event_data *event_data;
+
+ DEBUG_STRING("file_facility_cleanup","Entry point");
+
+ if(dblock->event_data != NULL) {
+ event_data = (struct file_event_data *)(dblock->event_data);
+ if(event_data->buffer != NULL) {
+ free(event_data->buffer);
+ event_data->buffer = NULL;
+ }
+ }
+ DEBUG_STRING("file_facility_cleanup","Exit point");
+}
+
+/* Logging calback */
+int file_facility_log(struct data_descriptor *dblock)
+{
+ struct file_event_data *event_data;
+ struct file_config *cfg;
+
+ DEBUG_STRING("file_facility_log","Entry point");
+
+ errno = 0;
+
+ cfg = (struct file_config *)(dblock->config);
+
+ /* Open file if needed */
+ if((cfg->path != NULL) && (cfg->mode & EL_FILE_OPEN_PER_CMD)) {
+ cfg->ff = fopen(cfg->path,"a");
+ if(cfg->ff == (FILE *)(NULL)) return errno;
+ }
+
+ event_data = (struct file_event_data *)(dblock->event_data);
+ fprintf(cfg->ff,"%s\n",event_data->buffer);
+
+ /* Close file if needed */
+ if((cfg->path != NULL) && (cfg->mode & EL_FILE_OPEN_PER_CMD)) {
+ fclose(cfg->ff);
+ cfg->ff = (FILE *)(NULL);
+ }
+
+ DEBUG_STRING("file_facility_log","Exit point");
+ return 0;
+}
+
+/* Close facility */
+void file_facility_close(struct data_descriptor *dblock)
+{
+ struct file_config *cfg;
+ struct file_event_data *event_data;
+
+ DEBUG_STRING("file_facility_close","Entry point");
+
+ /* Close file if needed */
+ cfg = (struct file_config *)(dblock->config);
+ if((cfg->path != NULL) && (cfg->ff != (FILE *)(NULL))) {
+ fclose(cfg->ff);
+ cfg->ff = (FILE *)(NULL);
+ }
+
+ /* Clean internal data storage */
+ if(dblock->event_data != NULL) {
+ event_data = (struct file_event_data *)(dblock->event_data);
+ if(event_data->buffer != NULL) free(event_data->buffer);
+ free(event_data);
+ dblock->event_data = NULL;
+ }
+
+ DEBUG_STRING("file_facility_close","Exit point");
+}
+
+