2 Copyright (C) 2005 Georgia Public Library Service
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
15 #include <opensrf/utils.h>
18 inline void* safe_malloc( int size ) {
19 void* ptr = (void*) malloc( size );
21 perror("safe_malloc(): Out of Memory" );
24 memset( ptr, 0, size );
29 The following static variables, and the following two functions,
30 overwrite the argv array passed to main(). The purpose is to
31 change the program name as reported by ps and similar utilities.
33 Warning: this code makes the non-portable assumption that the
34 strings to which argv[] points are contiguous in memory. The
35 C Standard makes no such guarantee.
37 static char** global_argv = NULL;
38 static int global_argv_size = 0;
40 int init_proc_title( int argc, char* argv[] ) {
46 int len = strlen( global_argv[i]);
47 bzero( global_argv[i++], len );
48 global_argv_size += len;
51 global_argv_size -= 2;
55 int set_proc_title( char* format, ... ) {
56 VA_LIST_TO_STRING(format);
57 bzero( *(global_argv), global_argv_size );
58 return snprintf( *(global_argv), global_argv_size, VA_BUF );
62 /* utility method for profiling */
63 double get_timestamp_millis() {
65 gettimeofday(&tv, NULL);
66 double time = (int)tv.tv_sec + ( ((double)tv.tv_usec / 1000000) );
71 /* setting/clearing file flags */
72 int set_fl( int fd, int flags ) {
76 if( (val = fcntl( fd, F_GETFL, 0) ) < 0 )
81 if( fcntl( fd, F_SETFL, val ) < 0 )
87 int clr_fl( int fd, int flags ) {
91 if( (val = fcntl( fd, F_GETFL, 0) ) < 0 )
96 if( fcntl( fd, F_SETFL, val ) < 0 )
102 long va_list_size(const char* format, va_list args) {
104 len = vsnprintf(NULL, 0, format, args);
111 char* va_list_to_string(const char* format, ...) {
117 va_copy(a_copy, args);
119 va_start(args, format);
120 len = va_list_size(format, args);
125 va_start(a_copy, format);
126 vsnprintf(buf, len - 1, format, a_copy);
131 // ---------------------------------------------------------------------------------
132 // Flesh out a ubiqitous growing string buffer
133 // ---------------------------------------------------------------------------------
135 growing_buffer* buffer_init(int num_initial_bytes) {
137 if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
139 size_t len = sizeof(growing_buffer);
142 OSRF_MALLOC(gb, len);
144 gb->n_used = 0;/* nothing stored so far */
145 gb->size = num_initial_bytes;
146 OSRF_MALLOC(gb->buf, gb->size + 1);
152 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
154 if(!gb || !format) return 0;
160 va_copy(a_copy, args);
162 va_start(args, format);
163 len = va_list_size(format, args);
168 va_start(a_copy, format);
169 vsnprintf(buf, len - 1, format, a_copy);
172 return buffer_add(gb, buf);
177 int buffer_add(growing_buffer* gb, char* data) {
178 if(!(gb && data)) return 0;
180 int data_len = strlen( data );
182 if(data_len == 0) return 0;
184 int total_len = data_len + gb->n_used;
186 if( total_len >= gb->size ) {
187 while( total_len >= gb->size ) {
191 if( gb->size > BUFFER_MAX_SIZE ) {
192 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
198 OSRF_MALLOC(new_data, gb->size );
200 strcpy( new_data, gb->buf );
205 strcat( gb->buf, data );
206 gb->n_used = total_len;
211 int buffer_reset( growing_buffer *gb){
212 if( gb == NULL ) { return 0; }
213 if( gb->buf == NULL ) { return 0; }
214 memset( gb->buf, 0, gb->size );
219 /* Return a pointer to the text within a growing_buffer, */
220 /* while destroying the growing_buffer itself. */
222 char* buffer_release( growing_buffer* gb) {
224 s[gb->n_used] = '\0';
229 /* Destroy a growing_buffer and the text it contains */
231 int buffer_free( growing_buffer* gb ) {
239 char* buffer_data( growing_buffer *gb) {
240 return strdup( gb->buf );
245 #define OSRF_BUFFER_ADD_CHAR(gb, c)\
248 if(gb->n_used < gb->size - 1)\
249 gb->buf[gb->n_used++] = c;\
251 buffer_add_char(gb, c);\
256 int buffer_add_char(growing_buffer* gb, char c) {
266 char* uescape( const char* string, int size, int full_escape ) {
268 growing_buffer* buf = buffer_init(size + 64);
271 unsigned long int c = 0x0;
273 while (string[idx]) {
277 if ((unsigned char)string[idx] >= 0x80) { // not ASCII
279 if ((unsigned char)string[idx] >= 0xC0 && (unsigned char)string[idx] <= 0xF4) { // starts a UTF8 string
282 if (((unsigned char)string[idx] & 0xF0) == 0xF0) {
284 c = (unsigned char)string[idx] ^ 0xF0;
286 } else if (((unsigned char)string[idx] & 0xE0) == 0xE0) {
288 c = (unsigned char)string[idx] ^ 0xE0;
290 } else if (((unsigned char)string[idx] & 0xC0) == 0xC0) {
292 c = (unsigned char)string[idx] ^ 0xC0;
297 idx++; // look at the next byte
298 c = (c << 6) | ((unsigned char)string[idx] & 0x3F); // add this byte worth
302 buffer_fadd(buf, "\\u%04x", c);
312 /* escape the usual suspects */
316 OSRF_BUFFER_ADD_CHAR(buf, '\\');
317 OSRF_BUFFER_ADD_CHAR(buf, '"');
321 OSRF_BUFFER_ADD_CHAR(buf, '\\');
322 OSRF_BUFFER_ADD_CHAR(buf, 'b');
326 OSRF_BUFFER_ADD_CHAR(buf, '\\');
327 OSRF_BUFFER_ADD_CHAR(buf, 'f');
331 OSRF_BUFFER_ADD_CHAR(buf, '\\');
332 OSRF_BUFFER_ADD_CHAR(buf, 't');
336 OSRF_BUFFER_ADD_CHAR(buf, '\\');
337 OSRF_BUFFER_ADD_CHAR(buf, 'n');
341 OSRF_BUFFER_ADD_CHAR(buf, '\\');
342 OSRF_BUFFER_ADD_CHAR(buf, 'r');
346 OSRF_BUFFER_ADD_CHAR(buf, '\\');
347 OSRF_BUFFER_ADD_CHAR(buf, '\\');
351 if( c < 32 ) buffer_fadd(buf, "\\u%04x", c);
352 else OSRF_BUFFER_ADD_CHAR(buf, c);
356 OSRF_BUFFER_ADD_CHAR(buf, c);
363 char* d = buffer_data(buf);
369 // A function to turn a process into a daemon and set it's process name in ps/top
374 perror("Failed to fork!");
377 } else if (f == 0) { // We're in the child now...
381 } else { // We're in the parent...
387 /* Return 1 if the string represents an integer, */
388 /* as recognized by strtol(); Otherwise return 0. */
390 int stringisnum(char* s) {
398 char* file_to_string(const char* filename) {
400 if(!filename) return NULL;
405 growing_buffer* gb = buffer_init(len);
407 FILE* file = fopen(filename, "r");
409 int l = strlen(filename) + 64;
411 snprintf(b,l,"Unable to open file [%s] in file_to_string()", filename);
416 while(fgets(buf, len - 1, file)) {
423 char* data = buffer_data(gb);
429 char* md5sum( char* text, ... ) {
432 unsigned char digest[16];
436 VA_LIST_TO_STRING(text);
439 for ( i=0 ; i != strlen(VA_BUF) ; i++ )
440 MD5_feed (&ctx, VA_BUF[i]);
442 MD5_stop (&ctx, digest);
450 for ( i=0 ; i<16 ; i++ ) {
451 sprintf(buf, "%02x", digest[i]);
452 strcat( final, buf );
455 return strdup(final);
459 int osrfUtilsCheckFileDescriptor( int fd ) {
469 if( select(fd + 1, &tmpset, NULL, NULL, &tv) == -1 ) {
470 if( errno == EBADF ) return -1;