1 #include "opensrf/generic_utils.h"
6 void get_timestamp( char buf_36chars[]) {
10 char* localtime = strdup( ctime( &(tb.time) ) );
13 sprintf(mil," (%d)",tb.millitm);
14 strcpy( buf_36chars, localtime );
15 buf_36chars[ strlen(localtime)-1] = '\0'; // remove newline
16 strcat(buf_36chars,mil);
19 double get_timestamp_millis() {
22 double time = ( (int)t.time + ( ((double)t.millitm) / 1000 ) );
27 inline void* safe_malloc( int size ) {
28 void* ptr = (void*) malloc( size );
30 fatal_handler("safe_malloc(): Out of Memory" );
31 memset( ptr, 0, size );
35 // ---------------------------------------------------------------------------------
36 // Here we define how we want to handle various error levels.
37 // ---------------------------------------------------------------------------------
40 static FILE* log_file = NULL;
41 static int log_level = -1;
42 static int logging = 0;
43 pthread_mutex_t mutex;
45 void log_free() { if( log_file != NULL ) fclose(log_file ); }
47 void fatal_handler( char* msg, ... ) {
57 if( log_level < LOG_ERROR )
60 pthread_mutex_lock( &(mutex) );
61 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "ERR " );
64 vfprintf(log_file, msg, args);
67 fprintf(log_file, "\n");
69 pthread_mutex_unlock( &(mutex) );
73 /* also log to stderr for ERRORS*/
74 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "ERR " );
76 vfprintf(stderr, msg, args);
78 fprintf( stderr, "\n" );
83 void warning_handler( char* msg, ... ) {
93 if( log_level < LOG_WARNING )
96 pthread_mutex_lock( &(mutex) );
97 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "WARN" );
100 vfprintf(log_file, msg, args);
103 fprintf(log_file, "\n");
105 pthread_mutex_unlock( &(mutex) );
109 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "WARN" );
111 vfprintf(stderr, msg, args);
113 fprintf( stderr, "\n" );
118 void info_handler( char* msg, ... ) {
121 memset( buf, 0, 36 );
122 get_timestamp( buf );
123 pid_t pid = getpid();
128 if( log_level < LOG_INFO )
130 pthread_mutex_lock( &(mutex) );
131 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "INFO" );
134 vfprintf(log_file, msg, args);
137 fprintf(log_file, "\n");
139 pthread_mutex_unlock( &(mutex) );
143 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "INFO" );
145 vfprintf(stderr, msg, args);
147 fprintf( stderr, "\n" );
154 void debug_handler( char* msg, ... ) {
157 memset( buf, 0, 36 );
158 get_timestamp( buf );
159 pid_t pid = getpid();
164 if( log_level < LOG_DEBUG )
167 pthread_mutex_lock( &(mutex) );
168 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "DEBG" );
171 vfprintf(log_file, msg, args);
174 fprintf(log_file, "\n");
176 pthread_mutex_unlock( &(mutex) );
180 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "DEBG" );
182 vfprintf(stderr, msg, args);
184 fprintf( stderr, "\n" );
190 int log_init( int llevel, char* lfile ) {
199 log_file = fopen( lfile, "a" );
200 if( log_file == NULL ) {
201 fprintf( stderr, "Unable to open log file %s for appending\n", lfile );
210 // ---------------------------------------------------------------------------------
211 // Flesh out a ubiqitous growing string buffer
212 // ---------------------------------------------------------------------------------
214 growing_buffer* buffer_init(int num_initial_bytes) {
216 if( num_initial_bytes > BUFFER_MAX_SIZE ) {
221 size_t len = sizeof(growing_buffer);
223 growing_buffer* gb = (growing_buffer*) safe_malloc(len);
225 gb->n_used = 0;/* nothing stored so far */
226 gb->size = num_initial_bytes;
227 gb->buf = (char *) safe_malloc(gb->size + 1);
232 int buffer_add(growing_buffer* gb, char* data) {
235 if( ! gb || ! data ) { return 0; }
236 int data_len = strlen( data );
238 if( data_len == 0 ) { return 0; }
239 int total_len = data_len + gb->n_used;
241 while( total_len >= gb->size ) {
245 if( gb->size > BUFFER_MAX_SIZE ) {
246 warning_handler( "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
251 char* new_data = (char*) safe_malloc( gb->size );
253 strcpy( new_data, gb->buf );
257 strcat( gb->buf, data );
258 gb->n_used = total_len;
263 int buffer_reset( growing_buffer *gb){
264 if( gb == NULL ) { return 0; }
265 if( gb->buf == NULL ) { return 0; }
266 memset( gb->buf, 0, gb->size );
271 int buffer_free( growing_buffer* gb ) {
279 char* buffer_data( growing_buffer *gb) {
280 return strdup( gb->buf );
287 // ---------------------------------------------------------------------------------
289 // ---------------------------------------------------------------------------------
292 // ---------------------------------------------------------------------------------
293 // Allocate and build the conf_reader. This only has to happen once in a given
294 // system. Repeated calls are ignored.
295 // ---------------------------------------------------------------------------------
297 void config_reader_init( char* config_file ) {
298 if( conf_reader == NULL ) {
300 if( config_file == NULL || strlen(config_file) == 0 ) {
301 fatal_handler( "config_reader_init(): No config file specified" );
305 size_t len = sizeof( config_reader );
306 conf_reader = (config_reader*) safe_malloc( len );
308 conf_reader->config_doc = xmlParseFile( config_file );
309 conf_reader->xpathCx = xmlXPathNewContext( conf_reader->config_doc );
310 if( conf_reader->xpathCx == NULL ) {
311 fatal_handler( "config_reader_init(): Unable to create xpath context");
318 void config_reader_init( char* name, char* config_file ) {
320 if( name == NULL || config_file == NULL || strlen(config_file) == 0 ) {
321 fatal_handler( "config_reader_init(): No config file specified" );
325 config_reader* reader =
326 (config_reader*) safe_malloc(sizeof(config_reader));
328 reader->config_doc = xmlParseFile( config_file );
329 reader->xpathCx = xmlXPathNewContext( reader->config_doc );
330 reader->name = strdup(name);
333 if( reader->xpathCx == NULL ) {
334 fprintf( stderr, "config_reader_init(): Unable to create xpath context\n");
338 if( conf_reader == NULL ) {
339 conf_reader = reader;
341 config_reader* tmp = conf_reader;
342 conf_reader = reader;
348 char* config_value( const char* config_name, const char* xp_query, ... ) {
350 if( conf_reader == NULL || xp_query == NULL ) {
351 fatal_handler( "config_value(): NULL conf_reader or NULL param(s)" );
355 config_reader* reader = conf_reader;
356 while( reader != NULL ) {
357 if( !strcmp(reader->name, config_name))
359 reader = reader->next;
362 if( reader == NULL ) {
363 fprintf(stderr, "No Config file with name %s\n", config_name );
367 int slen = strlen(xp_query) + 512;/* this is unsafe ... */
368 char xpath_query[ slen ];
369 memset( xpath_query, 0, slen );
371 va_start(va_args, xp_query);
372 vsprintf(xpath_query, xp_query, va_args);
377 int len = strlen(xpath_query) + 100;
378 char alert_buffer[len];
379 memset( alert_buffer, 0, len );
381 // build the xpath object
382 xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, reader->xpathCx );
384 if( xpathObj == NULL ) {
385 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
386 fatal_handler( alert_buffer );
391 if( xpathObj->type == XPATH_NODESET ) {
393 // ----------------------------------------------------------------------------
394 // Grab nodeset from xpath query, then first node, then first text node and
395 // finaly the text node's value
396 // ----------------------------------------------------------------------------
397 xmlNodeSet* node_list = xpathObj->nodesetval;
398 if( node_list == NULL ) {
399 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
400 warning_handler(alert_buffer);
404 if( node_list->nodeNr == 0 ) {
405 sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query );
406 warning_handler(alert_buffer);
411 xmlNodePtr element_node = *(node_list)->nodeTab;
412 if( element_node == NULL ) {
413 sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query );
414 warning_handler(alert_buffer);
418 xmlNodePtr text_node = element_node->children;
419 if( text_node == NULL ) {
420 sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
421 warning_handler(alert_buffer);
425 val = text_node->content;
427 sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
428 warning_handler(alert_buffer);
434 sprintf( alert_buffer, "Xpath evaluation failed: %s", xpath_query );
435 warning_handler(alert_buffer);
439 char* value = strdup(val);
440 if( value == NULL ) { warning_handler( "config_value(): Empty config value or Out of Memory!" ); }
442 // Free XPATH structures
443 if( xpathObj != NULL ) xmlXPathFreeObject( xpathObj );
449 void config_reader_free() {
450 while( conf_reader != NULL ) {
451 xmlXPathFreeContext( conf_reader->xpathCx );
452 xmlFreeDoc( conf_reader->config_doc );
453 free(conf_reader->name );
454 config_reader* tmp = conf_reader->next;