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);
20 double get_timestamp_millis() {
23 double time = ( (int)t.time + ( ((double)t.millitm) / 1000 ) );
28 inline void* safe_malloc( int size ) {
29 void* ptr = (void*) malloc( size );
31 fatal_handler("safe_malloc(): Out of Memory" );
32 memset( ptr, 0, size );
36 // ---------------------------------------------------------------------------------
37 // Here we define how we want to handle various error levels.
38 // ---------------------------------------------------------------------------------
41 static FILE* log_file = NULL;
42 static int log_level = -1;
43 static int logging = 0;
44 pthread_mutex_t mutex;
46 void log_free() { if( log_file != NULL ) fclose(log_file ); }
48 void fatal_handler( char* msg, ... ) {
58 if( log_level < LOG_ERROR )
61 pthread_mutex_lock( &(mutex) );
62 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "ERR " );
65 vfprintf(log_file, msg, args);
68 fprintf(log_file, "\n");
70 pthread_mutex_unlock( &(mutex) );
74 /* also log to stderr for ERRORS*/
75 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "ERR " );
77 vfprintf(stderr, msg, args);
79 fprintf( stderr, "\n" );
84 void warning_handler( char* msg, ... ) {
94 if( log_level < LOG_WARNING )
97 pthread_mutex_lock( &(mutex) );
98 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "WARN" );
101 vfprintf(log_file, msg, args);
104 fprintf(log_file, "\n");
106 pthread_mutex_unlock( &(mutex) );
110 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "WARN" );
112 vfprintf(stderr, msg, args);
114 fprintf( stderr, "\n" );
119 void info_handler( char* msg, ... ) {
122 memset( buf, 0, 36 );
123 get_timestamp( buf );
124 pid_t pid = getpid();
129 if( log_level < LOG_INFO )
131 pthread_mutex_lock( &(mutex) );
132 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "INFO" );
135 vfprintf(log_file, msg, args);
138 fprintf(log_file, "\n");
140 pthread_mutex_unlock( &(mutex) );
144 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "INFO" );
146 vfprintf(stderr, msg, args);
148 fprintf( stderr, "\n" );
155 void debug_handler( char* msg, ... ) {
158 memset( buf, 0, 36 );
159 get_timestamp( buf );
160 pid_t pid = getpid();
165 if( log_level < LOG_DEBUG )
168 pthread_mutex_lock( &(mutex) );
169 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "DEBG" );
172 vfprintf(log_file, msg, args);
175 fprintf(log_file, "\n");
177 pthread_mutex_unlock( &(mutex) );
181 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "DEBG" );
183 vfprintf(stderr, msg, args);
185 fprintf( stderr, "\n" );
191 int log_init( int llevel, char* lfile ) {
200 log_file = fopen( lfile, "a" );
201 if( log_file == NULL ) {
202 fprintf( stderr, "Unable to open log file %s for appending\n", lfile );
211 // ---------------------------------------------------------------------------------
212 // Flesh out a ubiqitous growing string buffer
213 // ---------------------------------------------------------------------------------
215 growing_buffer* buffer_init(int num_initial_bytes) {
217 if( num_initial_bytes > BUFFER_MAX_SIZE ) {
222 size_t len = sizeof(growing_buffer);
224 growing_buffer* gb = (growing_buffer*) safe_malloc(len);
226 gb->n_used = 0;/* nothing stored so far */
227 gb->size = num_initial_bytes;
228 gb->buf = (char *) safe_malloc(gb->size + 1);
233 int buffer_add(growing_buffer* gb, char* data) {
236 if( ! gb || ! data ) { return 0; }
237 int data_len = strlen( data );
239 if( data_len == 0 ) { return 0; }
240 int total_len = data_len + gb->n_used;
242 while( total_len >= gb->size ) {
246 if( gb->size > BUFFER_MAX_SIZE ) {
247 warning_handler( "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
252 char* new_data = (char*) safe_malloc( gb->size );
254 strcpy( new_data, gb->buf );
258 strcat( gb->buf, data );
259 gb->n_used = total_len;
264 int buffer_reset( growing_buffer *gb){
265 if( gb == NULL ) { return 0; }
266 if( gb->buf == NULL ) { return 0; }
267 memset( gb->buf, 0, gb->size );
272 int buffer_free( growing_buffer* gb ) {
280 char* buffer_data( growing_buffer *gb) {
281 return strdup( gb->buf );
288 // ---------------------------------------------------------------------------------
290 // ---------------------------------------------------------------------------------
293 // ---------------------------------------------------------------------------------
294 // Allocate and build the conf_reader. This only has to happen once in a given
295 // system. Repeated calls are ignored.
296 // ---------------------------------------------------------------------------------
298 void config_reader_init( char* config_file ) {
299 if( conf_reader == NULL ) {
301 if( config_file == NULL || strlen(config_file) == 0 ) {
302 fatal_handler( "config_reader_init(): No config file specified" );
306 size_t len = sizeof( config_reader );
307 conf_reader = (config_reader*) safe_malloc( len );
309 conf_reader->config_doc = xmlParseFile( config_file );
310 conf_reader->xpathCx = xmlXPathNewContext( conf_reader->config_doc );
311 if( conf_reader->xpathCx == NULL ) {
312 fatal_handler( "config_reader_init(): Unable to create xpath context");
319 void config_reader_init( char* name, char* config_file ) {
321 if( name == NULL || config_file == NULL || strlen(config_file) == 0 ) {
322 fatal_handler( "config_reader_init(): No config file specified" );
326 config_reader* reader =
327 (config_reader*) safe_malloc(sizeof(config_reader));
329 reader->config_doc = xmlParseFile( config_file );
330 reader->xpathCx = xmlXPathNewContext( reader->config_doc );
331 reader->name = strdup(name);
334 if( reader->xpathCx == NULL ) {
335 fprintf( stderr, "config_reader_init(): Unable to create xpath context\n");
339 if( conf_reader == NULL ) {
340 conf_reader = reader;
342 config_reader* tmp = conf_reader;
343 conf_reader = reader;
349 char* config_value( const char* config_name, const char* xp_query, ... ) {
351 if( conf_reader == NULL || xp_query == NULL ) {
352 fatal_handler( "config_value(): NULL conf_reader or NULL param(s)" );
356 config_reader* reader = conf_reader;
357 while( reader != NULL ) {
358 if( !strcmp(reader->name, config_name))
360 reader = reader->next;
363 if( reader == NULL ) {
364 fprintf(stderr, "No Config file with name %s\n", config_name );
368 int slen = strlen(xp_query) + 512;/* this is unsafe ... */
369 char xpath_query[ slen ];
370 memset( xpath_query, 0, slen );
372 va_start(va_args, xp_query);
373 vsprintf(xpath_query, xp_query, va_args);
378 int len = strlen(xpath_query) + 100;
379 char alert_buffer[len];
380 memset( alert_buffer, 0, len );
382 // build the xpath object
383 xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, reader->xpathCx );
385 if( xpathObj == NULL ) {
386 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
387 fatal_handler( alert_buffer );
392 if( xpathObj->type == XPATH_NODESET ) {
394 // ----------------------------------------------------------------------------
395 // Grab nodeset from xpath query, then first node, then first text node and
396 // finaly the text node's value
397 // ----------------------------------------------------------------------------
398 xmlNodeSet* node_list = xpathObj->nodesetval;
399 if( node_list == NULL ) {
400 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
401 warning_handler(alert_buffer);
405 if( node_list->nodeNr == 0 ) {
406 sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query );
407 warning_handler(alert_buffer);
412 xmlNodePtr element_node = *(node_list)->nodeTab;
413 if( element_node == NULL ) {
414 sprintf( alert_buffer, "Config XPATH query returned 0 results: %s", xpath_query );
415 warning_handler(alert_buffer);
419 xmlNodePtr text_node = element_node->children;
420 if( text_node == NULL ) {
421 sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
422 warning_handler(alert_buffer);
426 val = text_node->content;
428 sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
429 warning_handler(alert_buffer);
435 sprintf( alert_buffer, "Xpath evaluation failed: %s", xpath_query );
436 warning_handler(alert_buffer);
440 char* value = strdup(val);
441 if( value == NULL ) { warning_handler( "config_value(): Empty config value or Out of Memory!" ); }
443 // Free XPATH structures
444 if( xpathObj != NULL ) xmlXPathFreeObject( xpathObj );
450 void config_reader_free() {
451 while( conf_reader != NULL ) {
452 xmlXPathFreeContext( conf_reader->xpathCx );
453 xmlFreeDoc( conf_reader->config_doc );
454 free(conf_reader->name );
455 config_reader* tmp = conf_reader->next;