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);
21 double get_timestamp_millis() {
24 double time = ( (int)t.time + ( ((double)t.millitm) / 1000 ) );
29 inline void* safe_malloc( int size ) {
30 void* ptr = (void*) malloc( size );
32 fatal_handler("safe_malloc(): Out of Memory" );
33 memset( ptr, 0, size );
39 static FILE* log_file = NULL;
40 static int log_level = -1;
41 static int logging = 0;
42 pthread_mutex_t mutex;
44 void log_free() { if( log_file != NULL ) fclose(log_file ); }
46 void fatal_handler( char* msg, ... ) {
56 if( log_level < LOG_ERROR )
59 pthread_mutex_lock( &(mutex) );
60 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "ERR " );
63 vfprintf(log_file, msg, args);
66 fprintf(log_file, "\n");
68 pthread_mutex_unlock( &(mutex) );
72 /* also log to stderr for ERRORS*/
73 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "ERR " );
75 vfprintf(stderr, msg, args);
77 fprintf( stderr, "\n" );
82 void warning_handler( char* msg, ... ) {
92 if( log_level < LOG_WARNING )
95 pthread_mutex_lock( &(mutex) );
96 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "WARN" );
99 vfprintf(log_file, msg, args);
102 fprintf(log_file, "\n");
104 pthread_mutex_unlock( &(mutex) );
108 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "WARN" );
110 vfprintf(stderr, msg, args);
112 fprintf( stderr, "\n" );
117 void info_handler( char* msg, ... ) {
120 memset( buf, 0, 36 );
121 get_timestamp( buf );
122 pid_t pid = getpid();
127 if( log_level < LOG_INFO )
129 pthread_mutex_lock( &(mutex) );
130 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "INFO" );
133 vfprintf(log_file, msg, args);
136 fprintf(log_file, "\n");
138 pthread_mutex_unlock( &(mutex) );
142 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "INFO" );
144 vfprintf(stderr, msg, args);
146 fprintf( stderr, "\n" );
153 void debug_handler( char* msg, ... ) {
156 memset( buf, 0, 36 );
157 get_timestamp( buf );
158 pid_t pid = getpid();
163 if( log_level < LOG_DEBUG )
166 pthread_mutex_lock( &(mutex) );
167 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "DEBG" );
170 vfprintf(log_file, msg, args);
173 fprintf(log_file, "\n");
175 pthread_mutex_unlock( &(mutex) );
179 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "DEBG" );
181 vfprintf(stderr, msg, args);
183 fprintf( stderr, "\n" );
189 int log_init( int llevel, char* lfile ) {
198 log_file = fopen( lfile, "a" );
199 if( log_file == NULL ) {
200 fprintf( stderr, "Unable to open log file %s for appending\n", lfile );
210 growing_buffer* buffer_init(int num_initial_bytes) {
212 if( num_initial_bytes > BUFFER_MAX_SIZE ) {
217 size_t len = sizeof(growing_buffer);
219 growing_buffer* gb = (growing_buffer*) safe_malloc(len);
222 gb->size = num_initial_bytes;
223 gb->buf = (char *) safe_malloc(gb->size + 1);
228 int buffer_add(growing_buffer* gb, char* data) {
231 if( ! gb || ! data ) { return 0; }
232 int data_len = strlen( data );
234 if( data_len == 0 ) { return 0; }
235 int total_len = data_len + gb->n_used;
237 while( total_len >= gb->size ) {
241 if( gb->size > BUFFER_MAX_SIZE ) {
242 warning_handler( "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
247 char* new_data = (char*) safe_malloc( gb->size );
249 strcpy( new_data, gb->buf );
253 strcat( gb->buf, data );
254 gb->n_used = total_len;
259 int buffer_reset( growing_buffer *gb){
260 if( gb == NULL ) { return 0; }
261 if( gb->buf == NULL ) { return 0; }
262 memset( gb->buf, 0, gb->size );
267 int buffer_free( growing_buffer* gb ) {
275 char* buffer_data( growing_buffer *gb) {
276 return strdup( gb->buf );
284 // ---------------------------------------------------------------------------------
286 // ---------------------------------------------------------------------------------
289 // ---------------------------------------------------------------------------------
290 // Allocate and build the conf_reader. This only has to happen once in a given
291 // system. Repeated calls are ignored.
292 // ---------------------------------------------------------------------------------
294 void config_reader_init( char* config_file ) {
295 if( conf_reader == NULL ) {
297 if( config_file == NULL || strlen(config_file) == 0 ) {
298 fatal_handler( "config_reader_init(): No config file specified" );
302 size_t len = sizeof( config_reader );
303 conf_reader = (config_reader*) safe_malloc( len );
305 conf_reader->config_doc = xmlParseFile( config_file );
306 conf_reader->xpathCx = xmlXPathNewContext( conf_reader->config_doc );
307 if( conf_reader->xpathCx == NULL ) {
308 fatal_handler( "config_reader_init(): Unable to create xpath context");
315 void config_reader_init( char* name, char* config_file ) {
317 if( name == NULL || config_file == NULL || strlen(config_file) == 0 ) {
318 fatal_handler( "config_reader_init(): No config file specified" );
322 config_reader* reader =
323 (config_reader*) safe_malloc(sizeof(config_reader));
325 reader->config_doc = xmlParseFile( config_file );
326 reader->xpathCx = xmlXPathNewContext( reader->config_doc );
327 reader->name = strdup(name);
330 if( reader->xpathCx == NULL ) {
331 fprintf( stderr, "config_reader_init(): Unable to create xpath context\n");
335 if( conf_reader == NULL ) {
336 conf_reader = reader;
338 config_reader* tmp = conf_reader;
339 conf_reader = reader;
345 char* config_value( const char* config_name, const char* xp_query, ... ) {
347 if( conf_reader == NULL || xp_query == NULL ) {
348 fatal_handler( "config_value(): NULL conf_reader or NULL param(s)" );
352 config_reader* reader = conf_reader;
353 while( reader != NULL ) {
354 if( !strcmp(reader->name, config_name))
356 reader = reader->next;
359 if( reader == NULL ) {
360 fprintf(stderr, "No Config file with name %s\n", config_name );
364 int slen = strlen(xp_query) + 512;/* this is unsafe ... */
365 char xpath_query[ slen ];
366 memset( xpath_query, 0, slen );
368 va_start(va_args, xp_query);
369 vsprintf(xpath_query, xp_query, va_args);
374 int len = strlen(xpath_query) + 100;
375 char alert_buffer[len];
376 memset( alert_buffer, 0, len );
378 // build the xpath object
379 xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, reader->xpathCx );
381 if( xpathObj == NULL ) {
382 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
383 fatal_handler( alert_buffer );
388 if( xpathObj->type == XPATH_NODESET ) {
390 // ----------------------------------------------------------------------------
391 // Grab nodeset from xpath query, then first node, then first text node and
392 // finaly the text node's value
393 // ----------------------------------------------------------------------------
394 xmlNodeSet* node_list = xpathObj->nodesetval;
395 if( node_list == NULL ) {
396 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
397 warning_handler(alert_buffer);
401 if( node_list->nodeNr == 0 ) {
402 sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query );
403 warning_handler(alert_buffer);
408 xmlNodePtr element_node = *(node_list)->nodeTab;
409 if( element_node == NULL ) {
410 sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query );
411 warning_handler(alert_buffer);
415 xmlNodePtr text_node = element_node->children;
416 if( text_node == NULL ) {
417 sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
418 warning_handler(alert_buffer);
422 val = text_node->content;
424 sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
425 warning_handler(alert_buffer);
431 sprintf( alert_buffer, "Xpath evaluation failed: %s", xpath_query );
432 warning_handler(alert_buffer);
436 char* value = strdup(val);
437 if( value == NULL ) { warning_handler( "config_value(): Empty config value or Out of Memory!" ); }
439 // Free XPATH structures
440 if( xpathObj != NULL ) xmlXPathFreeObject( xpathObj );
446 void config_reader_free() {
447 while( conf_reader != NULL ) {
448 xmlXPathFreeContext( conf_reader->xpathCx );
449 xmlFreeDoc( conf_reader->config_doc );
450 free(conf_reader->name );
451 config_reader* tmp = conf_reader->next;