]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/utils/utils.c
9c0a3c2ad91e906c3aaaffdfec8d917321cad7cc
[working/Evergreen.git] / OpenSRF / 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 <stdio.h>
18
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 //#include <sys/timeb.h>
25 #include "utils.h"
26
27 inline void* safe_malloc( int size ) {
28         void* ptr = (void*) malloc( size );
29         if( ptr == NULL ) {
30                 perror("safe_malloc(): Out of Memory" );
31                 exit(99);
32         }
33         memset( ptr, 0, size );
34         return ptr;
35 }
36
37 /* utility method for profiling */
38 double get_timestamp_millis() {
39         //struct timeb t;
40         struct timeval tv;
41         gettimeofday(&tv, NULL);
42         //ftime(&t);
43 //      double time     = (int)t.time   + ( ((double)t.millitm) / 1000 )  + ( ((double)tv.tv_usec / 1000000) );
44         double time     = (int)tv.tv_sec        + ( ((double)tv.tv_usec / 1000000) );
45         return time;
46 }
47
48
49 /* setting/clearing file flags */
50 int set_fl( int fd, int flags ) {
51         
52         int val;
53
54         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
55                 fprintf(stderr, "fcntl F_GETFL error");
56                 return -1;
57         }
58
59         val |= flags;
60
61         if( fcntl( fd, F_SETFL, val ) < 0 ) {
62                 fprintf(stderr, "fcntl F_SETFL error");
63                 return -1;
64         }
65         return 0;
66 }
67         
68 int clr_fl( int fd, int flags ) {
69         
70         int val;
71
72         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
73                 fprintf(stderr, "fcntl F_GETFL error" );
74                 return -1;
75         }
76
77         val &= ~flags;
78
79         if( fcntl( fd, F_SETFL, val ) < 0 ) {
80                 fprintf( stderr, "fcntl F_SETFL error" );
81                 return -1;
82         }
83         return 0;
84 }
85
86 long va_list_size(const char* format, va_list args) {
87         int len = 0;
88         len = vsnprintf(NULL, 0, format, args);
89         va_end(args);
90         len += 2;
91         return len;
92 }
93
94
95 // ---------------------------------------------------------------------------------
96 // Flesh out a ubiqitous growing string buffer
97 // ---------------------------------------------------------------------------------
98
99 growing_buffer* buffer_init(int num_initial_bytes) {
100
101         if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
102
103         size_t len = sizeof(growing_buffer);
104
105         growing_buffer* gb = (growing_buffer*) safe_malloc(len);
106
107         gb->n_used = 0;/* nothing stored so far */
108         gb->size = num_initial_bytes;
109         gb->buf = (char *) safe_malloc(gb->size + 1);
110
111         return gb;
112 }
113
114
115 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
116
117         if(!gb || !format) return 0; 
118
119         long len = 0;
120         va_list args;
121         va_list a_copy;
122
123         va_copy(a_copy, args);
124
125         va_start(args, format);
126         len = va_list_size(format, args);
127
128         char buf[len];
129         memset(buf, 0, len);
130
131         va_start(a_copy, format);
132         vsnprintf(buf, len - 1, format, a_copy);
133         va_end(a_copy);
134
135         return buffer_add(gb, buf);
136
137 }
138
139 int buffer_add(growing_buffer* gb, char* data) {
140
141
142         if( ! gb || ! data  ) { return 0; }
143         int data_len = strlen( data );
144
145         if( data_len == 0 ) { return 0; }
146         int total_len = data_len + gb->n_used;
147
148         while( total_len >= gb->size ) {
149                 gb->size *= 2;
150         }
151
152         if( gb->size > BUFFER_MAX_SIZE ) {
153                 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
154                 buffer_free( gb );
155                 return 0;
156         }
157
158         char* new_data = (char*) safe_malloc( gb->size );
159
160         strcpy( new_data, gb->buf );
161         free( gb->buf );
162         gb->buf = new_data;
163
164         strcat( gb->buf, data );
165         gb->n_used = total_len;
166         return total_len;
167 }
168
169
170 int buffer_reset( growing_buffer *gb){
171         if( gb == NULL ) { return 0; }
172         if( gb->buf == NULL ) { return 0; }
173         memset( gb->buf, 0, gb->size );
174         gb->n_used = 0;
175         return 1;
176 }
177
178 int buffer_free( growing_buffer* gb ) {
179         if( gb == NULL ) 
180                 return 0;
181         free( gb->buf );
182         free( gb );
183         return 1;
184 }
185
186 char* buffer_data( growing_buffer *gb) {
187         return strdup( gb->buf );
188 }
189
190
191 int buffer_add_char(growing_buffer* gb, char c) {
192         char buf[2];
193         buf[0] = c;
194         buf[1] = '\0';
195         buffer_add(gb, buf);
196         return 1;
197 }
198
199
200
201 char* uescape( const char* string, int size, int full_escape ) {
202
203         growing_buffer* buf = buffer_init(size + 64);
204         int idx = 0;
205         long unsigned int c = 0;
206
207         while (string[idx]) {
208         
209                 c ^= c;
210                 
211                 if ((string[idx] & 0xF0) == 0xF0) {
212                         c = string[idx]<<18;
213
214                         if( size - idx < 4 ) return NULL;
215                         
216                         idx++;
217                         c |= (string[idx] & 0x3F)<<12;
218                         
219                         idx++;
220                         c |= (string[idx] & 0x3F)<<6;
221                         
222                         idx++;
223                         c |= (string[idx] & 0x3F);
224                         
225                         c ^= 0xFF000000;
226                         
227                         buffer_fadd(buf, "\\u%0.4x", c);
228
229                 } else if ((string[idx] & 0xE0) == 0xE0) {
230                         c = string[idx]<<12;
231                         if( size - idx < 3 ) return NULL;
232                         
233                         idx++;
234                         c |= (string[idx] & 0x3F)<<6;
235                         
236                         idx++;
237                         c |= (string[idx] & 0x3F);
238                         
239                         c ^= 0xFFF80000;
240                         
241                         buffer_fadd(buf, "\\u%0.4x", c);
242
243                 } else if ((string[idx] & 0xC0) == 0xC0) {
244                         // Two byte char
245                         c = string[idx]<<6;
246                         if( size - idx < 2 ) return NULL;
247                         
248                         idx++;
249                         c |= (string[idx] & 0x3F);
250                         
251                         c ^= 0xFFFFF000;
252                         
253                         buffer_fadd(buf, "\\u%0.4x", c);
254
255                 } else {
256                         c = string[idx];
257
258                         /* escape the usual suspects */
259                         if(full_escape) {
260                                 switch(c) {
261                                         case '"':
262                                                 buffer_add_char(buf, '\\');
263                                                 buffer_add_char(buf, '"');
264                                                 break;
265         
266                                         case '\b':
267                                                 buffer_add_char(buf, '\\');
268                                                 buffer_add_char(buf, 'b');
269                                                 break;
270         
271                                         case '\f':
272                                                 buffer_add_char(buf, '\\');
273                                                 buffer_add_char(buf, 'f');
274                                                 break;
275         
276                                         case '\t':
277                                                 buffer_add_char(buf, '\\');
278                                                 buffer_add_char(buf, 't');
279                                                 break;
280         
281                                         case '\n':
282                                                 buffer_add_char(buf, '\\');
283                                                 buffer_add_char(buf, 'n');
284                                                 break;
285         
286                                         case '\r':
287                                                 buffer_add_char(buf, '\\');
288                                                 buffer_add_char(buf, 'r');
289                                                 break;
290
291                                         default:
292                                                 buffer_add_char(buf, c);
293                                 }
294
295                         } else {
296                                 buffer_add_char(buf, c);
297                         }
298                 }
299
300                 idx++;
301         }
302
303         char* d = buffer_data(buf);
304         buffer_free(buf);
305         return d;
306 }
307
308
309 // A function to turn a process into a daemon and set it's process name in ps/top
310 int daemonize() {
311         int f = fork();
312
313         if (f == -1) {
314                 perror("Failed to fork!");
315                 return -1;
316
317         } else if (f == 0) { // We're in the child now...
318                 setsid();
319                 return 0;
320
321         } else { // We're in the parent...
322                 exit(0);
323         }
324 }
325
326 int stringisnum(char* s) {
327         char* w = (char*) malloc(strlen(s) * sizeof(char*));
328         bzero(w, strlen(s));
329         strtol(s, &w, 10);
330         if(strlen(w) > 0)  
331                 return 0;
332         return 1;
333 }
334         
335
336
337 char* file_to_string(char* filename) {
338
339         if(!filename) return NULL;
340
341         int len = 1024;
342         char buf[len];
343         bzero(buf, len);
344         growing_buffer* gb = buffer_init(len);
345
346         FILE* file = fopen(filename, "r");
347         if(!file) {
348                 perror("Unable to open file in json_parse_file()");
349                 return NULL;
350         }
351
352         while(fgets(buf, len - 1, file)) {
353                 buffer_add(gb, buf);
354                 bzero(buf, len);
355         }
356
357         char* data = buffer_data(gb);
358         buffer_free(gb);
359         return data;
360 }
361