]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/libtransport/generic_utils.c
moving header files into the directories where they are used. makefiles
[Evergreen.git] / OpenSRF / src / libtransport / generic_utils.c
1 #include "opensrf/generic_utils.h"
2 #include <stdio.h>
3 #include "pthread.h"
4 #include <sys/timeb.h>
5
6 void get_timestamp( char buf_36chars[]) {
7
8         struct timeb tb;
9         ftime(&tb);
10         char* localtime = strdup( ctime( &(tb.time) ) );
11         char mil[4];
12         memset(mil,0,4);
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);
17         free(localtime);
18 }
19
20 /*
21 double get_timestamp_millis() {
22         struct timeb t;
23         ftime(&t);
24         double time     = ( (int)t.time + ( ((double)t.millitm) / 1000 ) );
25         return time;
26 }
27         
28
29 inline void* safe_malloc( int size ) {
30         void* ptr = (void*) malloc( size );
31         if( ptr == NULL ) 
32                 fatal_handler("safe_malloc(): Out of Memory" );
33         memset( ptr, 0, size );
34         return ptr;
35 }
36 */
37
38
39 static FILE* log_file = NULL;
40 static int log_level = -1;
41 static int logging = 0;
42 pthread_mutex_t mutex;
43
44 void log_free() { if( log_file != NULL ) fclose(log_file ); }
45
46 void fatal_handler( char* msg, ... ) {
47                 
48         char buf[36];
49         memset( buf, 0, 36 );
50         get_timestamp( buf );
51         pid_t  pid = getpid();
52         va_list args;
53
54         if( logging ) {
55
56                 if( log_level < LOG_ERROR )
57                         return;
58
59                 pthread_mutex_lock( &(mutex) );
60                 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "ERR " );
61         
62                 va_start(args, msg);
63                 vfprintf(log_file, msg, args);
64                 va_end(args);
65         
66                 fprintf(log_file, "\n");
67                 fflush( log_file );
68                 pthread_mutex_unlock( &(mutex) );
69
70         }
71         
72         /* also log to stderr  for ERRORS*/
73         fprintf( stderr, "[%s %d] [%s] ", buf, pid, "ERR " );
74         va_start(args, msg);
75         vfprintf(stderr, msg, args);
76         va_end(args);
77         fprintf( stderr, "\n" );
78
79         exit(99);
80 }
81
82 void warning_handler( char* msg, ... ) {
83
84         char buf[36];
85         memset( buf, 0, 36 );
86         get_timestamp( buf );
87         pid_t  pid = getpid();
88         va_list args;
89         
90         if(logging) {
91
92                 if( log_level < LOG_WARNING )
93                         return;
94
95                 pthread_mutex_lock( &(mutex) );
96                 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "WARN" );
97         
98                 va_start(args, msg);
99                 vfprintf(log_file, msg, args);
100                 va_end(args);
101         
102                 fprintf(log_file, "\n");
103                 fflush( log_file );
104                 pthread_mutex_unlock( &(mutex) );
105
106         } else {
107
108                 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "WARN" );
109                 va_start(args, msg);
110                 vfprintf(stderr, msg, args);
111                 va_end(args);
112                 fprintf( stderr, "\n" );
113         }
114
115 }
116
117 void info_handler( char* msg, ... ) {
118
119         char buf[36];
120         memset( buf, 0, 36 );
121         get_timestamp( buf );
122         pid_t  pid = getpid();
123         va_list args;
124
125         if(logging) {
126
127                 if( log_level < LOG_INFO )
128                         return;
129                 pthread_mutex_lock( &(mutex) );
130                 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "INFO" );
131
132                 va_start(args, msg);
133                 vfprintf(log_file, msg, args);
134                 va_end(args);
135         
136                 fprintf(log_file, "\n");
137                 fflush( log_file );
138                 pthread_mutex_unlock( &(mutex) );
139
140         } else {
141
142                 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "INFO" );
143                 va_start(args, msg);
144                 vfprintf(stderr, msg, args);
145                 va_end(args);
146                 fprintf( stderr, "\n" );
147                 fflush(stderr);
148
149         }
150 }
151
152
153 void debug_handler( char* msg, ... ) {
154
155         char buf[36];
156         memset( buf, 0, 36 );
157         get_timestamp( buf );
158         pid_t  pid = getpid();
159         va_list args;
160         
161         if(logging) {
162
163                 if( log_level < LOG_DEBUG )
164                         return;
165
166                 pthread_mutex_lock( &(mutex) );
167                 fprintf( log_file, "[%s %d] [%s] ", buf, pid, "DEBG" );
168         
169                 va_start(args, msg);
170                 vfprintf(log_file, msg, args);
171                 va_end(args);
172         
173                 fprintf(log_file, "\n");
174                 fflush( log_file );
175                 pthread_mutex_unlock( &(mutex) );
176
177         } else {
178
179                 fprintf( stderr, "[%s %d] [%s] ", buf, pid, "DEBG" );
180                 va_start(args, msg);
181                 vfprintf(stderr, msg, args);
182                 va_end(args);
183                 fprintf( stderr, "\n" );
184         }
185
186 }
187
188
189 int log_init( int llevel, char* lfile ) {
190
191
192         if( llevel < 1 ) {
193                 logging = 0;
194                 return 0;
195         }
196
197         log_level = llevel;
198         log_file = fopen( lfile, "a" );
199         if( log_file == NULL ) {
200                 fprintf( stderr, "Unable to open log file %s for appending\n", lfile );
201                 return 0;
202         }
203         logging = 1;
204         return 1;
205
206 }
207
208
209 /*
210 growing_buffer* buffer_init(int num_initial_bytes) {
211
212         if( num_initial_bytes > BUFFER_MAX_SIZE ) {
213                 return NULL;
214         }
215
216
217         size_t len = sizeof(growing_buffer);
218
219         growing_buffer* gb = (growing_buffer*) safe_malloc(len);
220
221         gb->n_used = 0;
222         gb->size = num_initial_bytes;
223         gb->buf = (char *) safe_malloc(gb->size + 1);
224
225         return gb;
226 }
227
228 int buffer_add(growing_buffer* gb, char* data) {
229
230
231         if( ! gb || ! data  ) { return 0; }
232         int data_len = strlen( data );
233
234         if( data_len == 0 ) { return 0; }
235         int total_len = data_len + gb->n_used;
236
237         while( total_len >= gb->size ) {
238                 gb->size *= 2;
239         }
240
241         if( gb->size > BUFFER_MAX_SIZE ) {
242                 warning_handler( "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
243                 buffer_free( gb );
244                 return 0;
245         }
246
247         char* new_data = (char*) safe_malloc( gb->size );
248
249         strcpy( new_data, gb->buf );
250         free( gb->buf );
251         gb->buf = new_data;
252
253         strcat( gb->buf, data );
254         gb->n_used = total_len;
255         return total_len;
256 }
257
258
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 );
263         gb->n_used = 0;
264         return 1;
265 }
266
267 int buffer_free( growing_buffer* gb ) {
268         if( gb == NULL ) 
269                 return 0;
270         free( gb->buf );
271         free( gb );
272         return 1;
273 }
274
275 char* buffer_data( growing_buffer *gb) {
276         return strdup( gb->buf );
277 }
278 */
279
280
281
282
283
284 // ---------------------------------------------------------------------------------
285 // Config module
286 // ---------------------------------------------------------------------------------
287
288
289 // ---------------------------------------------------------------------------------
290 // Allocate and build the conf_reader.  This only has to happen once in a given
291 // system.  Repeated calls are ignored.
292 // ---------------------------------------------------------------------------------
293 /*
294 void config_reader_init( char* config_file ) {
295         if( conf_reader == NULL ) {
296
297                 if( config_file == NULL || strlen(config_file) == 0 ) {
298                         fatal_handler( "config_reader_init(): No config file specified" );
299                         return;
300                 }
301
302                 size_t len = sizeof( config_reader );
303                 conf_reader = (config_reader*) safe_malloc( len );
304
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");
309                         return;
310                 }
311         }
312 }
313 */
314
315 void config_reader_init( char* name, char* config_file ) {
316
317         if( name == NULL || config_file == NULL || strlen(config_file) == 0 ) {
318                 fatal_handler( "config_reader_init(): No config file specified" );
319                 return;
320         }
321
322         config_reader* reader = 
323                 (config_reader*) safe_malloc(sizeof(config_reader));
324
325         reader->config_doc = xmlParseFile( config_file ); 
326         reader->xpathCx = xmlXPathNewContext( reader->config_doc );
327         reader->name = strdup(name);
328         reader->next = NULL;
329
330         if( reader->xpathCx == NULL ) {
331                 fprintf( stderr, "config_reader_init(): Unable to create xpath context\n");
332                 return;
333         }
334
335         if( conf_reader == NULL ) {
336                 conf_reader = reader;
337         } else {
338                 config_reader* tmp = conf_reader;
339                 conf_reader = reader;
340                 reader->next = tmp;
341         }
342 }
343
344
345 char* config_value( const char* config_name, const char* xp_query, ... ) {
346
347         if( conf_reader == NULL || xp_query == NULL ) {
348                 fatal_handler( "config_value(): NULL conf_reader or NULL param(s)" );
349                 return NULL;
350         }
351
352         config_reader* reader = conf_reader;
353         while( reader != NULL ) {
354                 if( !strcmp(reader->name, config_name)) 
355                         break;
356                 reader = reader->next;
357         }
358
359         if( reader == NULL ) {
360                 fprintf(stderr, "No Config file with name %s\n", config_name );
361                 return NULL;
362         }
363
364         int slen = strlen(xp_query) + 512;/* this is unsafe ... */
365         char xpath_query[ slen ]; 
366         memset( xpath_query, 0, slen );
367         va_list va_args;
368         va_start(va_args, xp_query);
369         vsprintf(xpath_query, xp_query, va_args);
370         va_end(va_args);
371
372
373         char* val;
374         int len = strlen(xpath_query) + 100;
375         char alert_buffer[len];
376         memset( alert_buffer, 0, len );
377
378         // build the xpath object
379         xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression( BAD_CAST xpath_query, reader->xpathCx );
380
381         if( xpathObj == NULL ) {
382                 sprintf( alert_buffer, "Could not build xpath object: %s", xpath_query );
383                 fatal_handler( alert_buffer );
384                 return NULL;
385         }
386
387
388         if( xpathObj->type == XPATH_NODESET ) {
389
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);
398                         return NULL;
399                 }
400
401                 if( node_list->nodeNr == 0 ) {
402                         sprintf( alert_buffer, "Config XPATH query  returned 0 results: %s", xpath_query );
403                         warning_handler(alert_buffer);
404                         return NULL;
405                 }
406
407
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);
412                         return NULL;
413                 }
414
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);
419                         return NULL;
420                 }
421
422                 val = text_node->content;
423                 if( val == NULL ) {
424                         sprintf( alert_buffer, "Config variable has no value: %s", xpath_query );
425                         warning_handler(alert_buffer);
426                         return NULL;
427                 }
428
429
430         } else { 
431                 sprintf( alert_buffer, "Xpath evaluation failed: %s", xpath_query );
432                 warning_handler(alert_buffer);
433                 return NULL;
434         }
435
436         char* value = strdup(val);
437         if( value == NULL ) { warning_handler( "config_value(): Empty config value or Out of Memory!" ); }
438
439         // Free XPATH structures
440         if( xpathObj != NULL ) xmlXPathFreeObject( xpathObj );
441
442         return value;
443 }
444
445
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;
452                 free( conf_reader );
453                 conf_reader = tmp;
454         }
455 }