]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/utils/utils.c
added CONNECT handling
[OpenSRF.git] / src / utils / utils.c
1 /*
2 Copyright (C) 2005  Georgia Public Library Service 
3 Bill Erickson <highfalutin@gmail.com>
4 Mike Rylander <mrylander@gmail.com>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 */
16
17 #include "utils.h"
18
19 inline void* safe_malloc( int size ) {
20         void* ptr = (void*) malloc( size );
21         if( ptr == NULL ) {
22                 perror("safe_malloc(): Out of Memory" );
23                 exit(99);
24         }
25         memset( ptr, 0, size );
26         return ptr;
27 }
28
29
30 char** __global_argv = NULL;
31 int __global_argv_size = 0;
32
33 int init_proc_title( int argc, char* argv[] ) {
34
35         __global_argv = argv;
36
37         int i = 0;
38         while( i < argc ) {
39                 int len = strlen( __global_argv[i]);
40                 bzero( __global_argv[i++], len );
41                 __global_argv_size += len;
42         }
43
44         __global_argv_size -= 2;
45         return 0;
46 }
47
48 int set_proc_title( char* format, ... ) {
49         VA_LIST_TO_STRING(format);
50         bzero( *(__global_argv), __global_argv_size );
51         return snprintf( *(__global_argv), __global_argv_size, VA_BUF );
52 }
53
54
55 /* utility method for profiling */
56 double get_timestamp_millis() {
57         struct timeval tv;
58         gettimeofday(&tv, NULL);
59         double time     = (int)tv.tv_sec        + ( ((double)tv.tv_usec / 1000000) );
60         return time;
61 }
62
63
64 /* setting/clearing file flags */
65 int set_fl( int fd, int flags ) {
66         
67         int val;
68
69         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
70                 fprintf(stderr, "fcntl F_GETFL error");
71                 return -1;
72         }
73
74         val |= flags;
75
76         if( fcntl( fd, F_SETFL, val ) < 0 ) {
77                 fprintf(stderr, "fcntl F_SETFL error");
78                 return -1;
79         }
80         return 0;
81 }
82         
83 int clr_fl( int fd, int flags ) {
84         
85         int val;
86
87         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
88                 fprintf(stderr, "fcntl F_GETFL error" );
89                 return -1;
90         }
91
92         val &= ~flags;
93
94         if( fcntl( fd, F_SETFL, val ) < 0 ) {
95                 fprintf( stderr, "fcntl F_SETFL error" );
96                 return -1;
97         }
98         return 0;
99 }
100
101 long va_list_size(const char* format, va_list args) {
102         int len = 0;
103         len = vsnprintf(NULL, 0, format, args);
104         va_end(args);
105         len += 2;
106         return len;
107 }
108
109
110 char* va_list_to_string(const char* format, ...) {
111
112         long len = 0;
113         va_list args;
114         va_list a_copy;
115
116         va_copy(a_copy, args);
117
118         va_start(args, format);
119         len = va_list_size(format, args);
120
121         char buf[len];
122         memset(buf, 0, len);
123
124         va_start(a_copy, format);
125         vsnprintf(buf, len - 1, format, a_copy);
126         va_end(a_copy);
127         return strdup(buf);
128 }
129
130 // ---------------------------------------------------------------------------------
131 // Flesh out a ubiqitous growing string buffer
132 // ---------------------------------------------------------------------------------
133
134 growing_buffer* buffer_init(int num_initial_bytes) {
135
136         if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
137
138         size_t len = sizeof(growing_buffer);
139
140         growing_buffer* gb = (growing_buffer*) safe_malloc(len);
141
142         gb->n_used = 0;/* nothing stored so far */
143         gb->size = num_initial_bytes;
144         gb->buf = (char *) safe_malloc(gb->size + 1);
145
146         return gb;
147 }
148
149
150 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
151
152         if(!gb || !format) return 0; 
153
154         long len = 0;
155         va_list args;
156         va_list a_copy;
157
158         va_copy(a_copy, args);
159
160         va_start(args, format);
161         len = va_list_size(format, args);
162
163         char buf[len];
164         memset(buf, 0, len);
165
166         va_start(a_copy, format);
167         vsnprintf(buf, len - 1, format, a_copy);
168         va_end(a_copy);
169
170         return buffer_add(gb, buf);
171
172 }
173
174 int buffer_add(growing_buffer* gb, char* data) {
175
176
177         if( ! gb || ! data  ) { return 0; }
178         int data_len = strlen( data );
179
180         if( data_len == 0 ) { return 0; }
181         int total_len = data_len + gb->n_used;
182
183         while( total_len >= gb->size ) {
184                 gb->size *= 2;
185         }
186
187         if( gb->size > BUFFER_MAX_SIZE ) {
188                 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
189                 buffer_free( gb );
190                 return 0;
191         }
192
193         char* new_data = (char*) safe_malloc( gb->size );
194
195         strcpy( new_data, gb->buf );
196         free( gb->buf );
197         gb->buf = new_data;
198
199         strcat( gb->buf, data );
200         gb->n_used = total_len;
201         return total_len;
202 }
203
204
205 int buffer_reset( growing_buffer *gb){
206         if( gb == NULL ) { return 0; }
207         if( gb->buf == NULL ) { return 0; }
208         memset( gb->buf, 0, gb->size );
209         gb->n_used = 0;
210         return 1;
211 }
212
213 int buffer_free( growing_buffer* gb ) {
214         if( gb == NULL ) 
215                 return 0;
216         free( gb->buf );
217         free( gb );
218         return 1;
219 }
220
221 char* buffer_data( growing_buffer *gb) {
222         return strdup( gb->buf );
223 }
224
225
226 int buffer_add_char(growing_buffer* gb, char c) {
227         char buf[2];
228         buf[0] = c;
229         buf[1] = '\0';
230         buffer_add(gb, buf);
231         return 1;
232 }
233
234
235
236 char* uescape( const char* string, int size, int full_escape ) {
237
238         growing_buffer* buf = buffer_init(size + 64);
239         int idx = 0;
240         long unsigned int c = 0;
241
242         while (string[idx]) {
243         
244                 c ^= c;
245                 
246                 if ((string[idx] & 0xF0) == 0xF0) {
247                         c = string[idx]<<18;
248
249                         if( size - idx < 4 ) return NULL;
250                         
251                         idx++;
252                         c |= (string[idx] & 0x3F)<<12;
253                         
254                         idx++;
255                         c |= (string[idx] & 0x3F)<<6;
256                         
257                         idx++;
258                         c |= (string[idx] & 0x3F);
259                         
260                         c ^= 0xFF000000;
261                         
262                         buffer_fadd(buf, "\\u%0.4x", c);
263
264                 } else if ((string[idx] & 0xE0) == 0xE0) {
265                         c = string[idx]<<12;
266                         if( size - idx < 3 ) return NULL;
267                         
268                         idx++;
269                         c |= (string[idx] & 0x3F)<<6;
270                         
271                         idx++;
272                         c |= (string[idx] & 0x3F);
273                         
274                         c ^= 0xFFF80000;
275                         
276                         buffer_fadd(buf, "\\u%0.4x", c);
277
278                 } else if ((string[idx] & 0xC0) == 0xC0) {
279                         // Two byte char
280                         c = string[idx]<<6;
281                         if( size - idx < 2 ) return NULL;
282                         
283                         idx++;
284                         c |= (string[idx] & 0x3F);
285                         
286                         c ^= 0xFFFFF000;
287                         
288                         buffer_fadd(buf, "\\u%0.4x", c);
289
290                 } else {
291                         c = string[idx];
292
293                         /* escape the usual suspects */
294                         if(full_escape) {
295                                 switch(c) {
296                                         case '"':
297                                                 buffer_add_char(buf, '\\');
298                                                 buffer_add_char(buf, '"');
299                                                 break;
300         
301                                         case '\b':
302                                                 buffer_add_char(buf, '\\');
303                                                 buffer_add_char(buf, 'b');
304                                                 break;
305         
306                                         case '\f':
307                                                 buffer_add_char(buf, '\\');
308                                                 buffer_add_char(buf, 'f');
309                                                 break;
310         
311                                         case '\t':
312                                                 buffer_add_char(buf, '\\');
313                                                 buffer_add_char(buf, 't');
314                                                 break;
315         
316                                         case '\n':
317                                                 buffer_add_char(buf, '\\');
318                                                 buffer_add_char(buf, 'n');
319                                                 break;
320         
321                                         case '\r':
322                                                 buffer_add_char(buf, '\\');
323                                                 buffer_add_char(buf, 'r');
324                                                 break;
325
326                                         default:
327                                                 buffer_add_char(buf, c);
328                                 }
329
330                         } else {
331                                 buffer_add_char(buf, c);
332                         }
333                 }
334
335                 idx++;
336         }
337
338         char* d = buffer_data(buf);
339         buffer_free(buf);
340         return d;
341 }
342
343
344 // A function to turn a process into a daemon and set it's process name in ps/top
345 int daemonize() {
346         int f = fork();
347
348         if (f == -1) {
349                 perror("Failed to fork!");
350                 return -1;
351
352         } else if (f == 0) { // We're in the child now...
353                 setsid();
354                 return 0;
355
356         } else { // We're in the parent...
357                 exit(0);
358         }
359 }
360
361 int stringisnum(char* s) {
362         char* w = (char*) malloc(strlen(s) * sizeof(char*));
363         bzero(w, strlen(s));
364         strtol(s, &w, 10);
365         if(strlen(w) > 0)  
366                 return 0;
367         return 1;
368 }
369         
370
371
372 char* file_to_string(const char* filename) {
373
374         if(!filename) return NULL;
375
376         int len = 1024;
377         char buf[len];
378         bzero(buf, len);
379         growing_buffer* gb = buffer_init(len);
380
381         FILE* file = fopen(filename, "r");
382         if(!file) {
383                 perror("Unable to open file in json_parse_file()");
384                 return NULL;
385         }
386
387         while(fgets(buf, len - 1, file)) {
388                 buffer_add(gb, buf);
389                 bzero(buf, len);
390         }
391
392         fclose(file);
393
394         char* data = buffer_data(gb);
395         buffer_free(gb);
396         return data;
397 }
398