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