~ubuntu-branches/ubuntu/raring/nagios3/raring

« back to all changes in this revision

Viewing changes to common/shared.c

  • Committer: Package Import Robot
  • Author(s): Alexander Wirt
  • Date: 2012-06-16 09:05:19 UTC
  • mfrom: (8.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120616090519-1okxgkbe21vumokr
Tags: 3.4.1-1
* [28e077b] Imported Upstream version 3.3.1
* [d5314e0] don't call updatepo in clean target
* [45b3eb9] Don't remove config foo
* [54e3dff] Don't fix permissions in cgi postinst
* [d7be9db] Build-depend on libpng-dev (Closes: #662441)
* [4c47006] Add dutch po translation (Closes: #654855)
* [2b6573b] Refresh 10_p1_pl_shebang.dpatch
* [316fd7a] Update 40_fix_spurious_dollar_signs_added_to_command_lines
* [5ff2780] Refresh 55_strip_logarchivepath.dpatch
* [811d269] Refresh 60_fix_p1.pl_patch_mini_epn.dpatch
* [39a1e9c] Remove now unneeded patch 98_fix_XSS_CVE-2011-2179
* [785a4e8] Remove unneded patch 99_fix_XSS_CVE-2011-1523
* [6ce98ef] Remove unneeded patchs from 00list
* [1d18266] Imported Upstream version 3.4.0
* [05584c8] Refresh patches
* [58098cd] Imported Upstream version 3.4.1
* [3e9e07a] Bump standards version
* [fe991e2] wrap-and-sort
* [1ba78f7] Also create /var/run/nagios in cgi package (Closes: #626854)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "../include/config.h"
 
2
#include "../include/common.h"
 
3
 
 
4
/*
 
5
 * This file holds random utility functions shared by cgi's and
 
6
 * core.
 
7
 */
 
8
extern int date_format;
 
9
 
 
10
/* fix the problem with strtok() skipping empty options between tokens */
 
11
char *my_strtok(char *buffer, char *tokens) {
 
12
        char *token_position = NULL;
 
13
        char *sequence_head = NULL;
 
14
        static char *my_strtok_buffer = NULL;
 
15
        static char *original_my_strtok_buffer = NULL;
 
16
 
 
17
        if(buffer != NULL) {
 
18
                my_free(original_my_strtok_buffer);
 
19
                if((my_strtok_buffer = (char *)strdup(buffer)) == NULL)
 
20
                        return NULL;
 
21
                original_my_strtok_buffer = my_strtok_buffer;
 
22
                }
 
23
 
 
24
        sequence_head = my_strtok_buffer;
 
25
 
 
26
        if(sequence_head[0] == '\x0')
 
27
                return NULL;
 
28
 
 
29
        token_position = strchr(my_strtok_buffer, tokens[0]);
 
30
 
 
31
        if(token_position == NULL) {
 
32
                my_strtok_buffer = strchr(my_strtok_buffer, '\x0');
 
33
                return sequence_head;
 
34
                }
 
35
 
 
36
        token_position[0] = '\x0';
 
37
        my_strtok_buffer = token_position + 1;
 
38
 
 
39
        return sequence_head;
 
40
        }
 
41
 
 
42
/* fixes compiler problems under Solaris, since strsep() isn't included */
 
43
/* this code is taken from the glibc source */
 
44
char *my_strsep(char **stringp, const char *delim) {
 
45
        char *begin, *end;
 
46
 
 
47
        begin = *stringp;
 
48
        if(begin == NULL)
 
49
                return NULL;
 
50
 
 
51
        /* A frequent case is when the delimiter string contains only one
 
52
         * character.  Here we don't need to call the expensive `strpbrk'
 
53
         * function and instead work using `strchr'.  */
 
54
        if(delim[0] == '\0' || delim[1] == '\0') {
 
55
                char ch = delim[0];
 
56
 
 
57
                if(ch == '\0' || begin[0] == '\0')
 
58
                        end = NULL;
 
59
                else {
 
60
                        if(*begin == ch)
 
61
                                end = begin;
 
62
                        else
 
63
                                end = strchr(begin + 1, ch);
 
64
                        }
 
65
                }
 
66
        else {
 
67
                /* find the end of the token.  */
 
68
                end = strpbrk(begin, delim);
 
69
                }
 
70
 
 
71
        if(end) {
 
72
                /* terminate the token and set *STRINGP past NUL character.  */
 
73
                *end++ = '\0';
 
74
                *stringp = end;
 
75
                }
 
76
        else
 
77
                /* no more delimiters; this is the last token.  */
 
78
                *stringp = NULL;
 
79
 
 
80
        return begin;
 
81
        }
 
82
 
 
83
/* open a file read-only via mmap() */
 
84
mmapfile *mmap_fopen(char *filename) {
 
85
        mmapfile *new_mmapfile = NULL;
 
86
        int fd = 0;
 
87
        void *mmap_buf = NULL;
 
88
        struct stat statbuf;
 
89
        int mode = O_RDONLY;
 
90
        unsigned long file_size = 0L;
 
91
 
 
92
        if(filename == NULL)
 
93
                return NULL;
 
94
 
 
95
        /* allocate memory */
 
96
        if((new_mmapfile = (mmapfile *) malloc(sizeof(mmapfile))) == NULL)
 
97
                return NULL;
 
98
 
 
99
        /* open the file */
 
100
        if((fd = open(filename, mode)) == -1) {
 
101
                my_free(new_mmapfile);
 
102
                return NULL;
 
103
                }
 
104
 
 
105
        /* get file info */
 
106
        if((fstat(fd, &statbuf)) == -1) {
 
107
                close(fd);
 
108
                my_free(new_mmapfile);
 
109
                return NULL;
 
110
                }
 
111
 
 
112
        /* get file size */
 
113
        file_size = (unsigned long)statbuf.st_size;
 
114
 
 
115
        /* only mmap() if we have a file greater than 0 bytes */
 
116
        if(file_size > 0) {
 
117
 
 
118
                /* mmap() the file - allocate one extra byte for processing zero-byte files */
 
119
                if((mmap_buf =
 
120
                            (void *)mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd,
 
121
                                         0)) == MAP_FAILED) {
 
122
                        close(fd);
 
123
                        my_free(new_mmapfile);
 
124
                        return NULL;
 
125
                        }
 
126
                }
 
127
        else
 
128
                mmap_buf = NULL;
 
129
 
 
130
        /* populate struct info for later use */
 
131
        new_mmapfile->path = (char *)strdup(filename);
 
132
        new_mmapfile->fd = fd;
 
133
        new_mmapfile->file_size = (unsigned long)file_size;
 
134
        new_mmapfile->current_position = 0L;
 
135
        new_mmapfile->current_line = 0L;
 
136
        new_mmapfile->mmap_buf = mmap_buf;
 
137
 
 
138
        return new_mmapfile;
 
139
        }
 
140
 
 
141
/* close a file originally opened via mmap() */
 
142
int mmap_fclose(mmapfile * temp_mmapfile) {
 
143
 
 
144
        if(temp_mmapfile == NULL)
 
145
                return ERROR;
 
146
 
 
147
        /* un-mmap() the file */
 
148
        if(temp_mmapfile->file_size > 0L)
 
149
                munmap(temp_mmapfile->mmap_buf, temp_mmapfile->file_size);
 
150
 
 
151
        /* close the file */
 
152
        close(temp_mmapfile->fd);
 
153
 
 
154
        /* free memory */
 
155
        my_free(temp_mmapfile->path);
 
156
        my_free(temp_mmapfile);
 
157
 
 
158
        return OK;
 
159
        }
 
160
 
 
161
/* gets one line of input from an mmap()'ed file */
 
162
char *mmap_fgets(mmapfile * temp_mmapfile) {
 
163
        char *buf = NULL;
 
164
        unsigned long x = 0L;
 
165
        int len = 0;
 
166
 
 
167
        if(temp_mmapfile == NULL)
 
168
                return NULL;
 
169
 
 
170
        /* size of file is 0 bytes */
 
171
        if(temp_mmapfile->file_size == 0L)
 
172
                return NULL;
 
173
 
 
174
        /* we've reached the end of the file */
 
175
        if(temp_mmapfile->current_position >= temp_mmapfile->file_size)
 
176
                return NULL;
 
177
 
 
178
        /* find the end of the string (or buffer) */
 
179
        for(x = temp_mmapfile->current_position; x < temp_mmapfile->file_size;
 
180
                x++) {
 
181
                if(*((char *)(temp_mmapfile->mmap_buf) + x) == '\n') {
 
182
                        x++;
 
183
                        break;
 
184
                        }
 
185
                }
 
186
 
 
187
        /* calculate length of line we just read */
 
188
        len = (int)(x - temp_mmapfile->current_position);
 
189
 
 
190
        /* allocate memory for the new line */
 
191
        if((buf = (char *)malloc(len + 1)) == NULL)
 
192
                return NULL;
 
193
 
 
194
        /* copy string to newly allocated memory and terminate the string */
 
195
        memcpy(buf,
 
196
               ((char *)(temp_mmapfile->mmap_buf) +
 
197
                temp_mmapfile->current_position), len);
 
198
        buf[len] = '\x0';
 
199
 
 
200
        /* update the current position */
 
201
        temp_mmapfile->current_position = x;
 
202
 
 
203
        /* increment the current line */
 
204
        temp_mmapfile->current_line++;
 
205
 
 
206
        return buf;
 
207
        }
 
208
 
 
209
/* gets one line of input from an mmap()'ed file (may be contained on more than one line in the source file) */
 
210
char *mmap_fgets_multiline(mmapfile * temp_mmapfile) {
 
211
        char *buf = NULL;
 
212
        char *tempbuf = NULL;
 
213
        char *stripped = NULL;
 
214
        int len = 0;
 
215
        int len2 = 0;
 
216
        int end = 0;
 
217
 
 
218
        if(temp_mmapfile == NULL)
 
219
                return NULL;
 
220
 
 
221
        while(1) {
 
222
 
 
223
                my_free(tempbuf);
 
224
 
 
225
                if((tempbuf = mmap_fgets(temp_mmapfile)) == NULL)
 
226
                        break;
 
227
 
 
228
                if(buf == NULL) {
 
229
                        len = strlen(tempbuf);
 
230
                        if((buf = (char *)malloc(len + 1)) == NULL)
 
231
                                break;
 
232
                        memcpy(buf, tempbuf, len);
 
233
                        buf[len] = '\x0';
 
234
                        }
 
235
                else {
 
236
                        /* strip leading white space from continuation lines */
 
237
                        stripped = tempbuf;
 
238
                        while(*stripped == ' ' || *stripped == '\t')
 
239
                                stripped++;
 
240
                        len = strlen(stripped);
 
241
                        len2 = strlen(buf);
 
242
                        if((buf =
 
243
                                    (char *)realloc(buf, len + len2 + 1)) == NULL)
 
244
                                break;
 
245
                        strcat(buf, stripped);
 
246
                        len += len2;
 
247
                        buf[len] = '\x0';
 
248
                        }
 
249
 
 
250
                if(len == 0)
 
251
                        break;
 
252
 
 
253
                /* handle Windows/DOS CR/LF */
 
254
                if(len >= 2 && buf[len - 2] == '\r')
 
255
                        end = len - 3;
 
256
                /* normal Unix LF */
 
257
                else if(len >= 1 && buf[len - 1] == '\n')
 
258
                        end = len - 2;
 
259
                else
 
260
                        end = len - 1;
 
261
 
 
262
                /* two backslashes found. unescape first backslash first and break */
 
263
                if(end >= 1 && buf[end - 1] == '\\' && buf[end] == '\\') {
 
264
                        buf[end] = '\n';
 
265
                        buf[end + 1] = '\x0';
 
266
                        break;
 
267
                        }
 
268
 
 
269
                /* one backslash found. continue reading the next line */
 
270
                else if(end > 0 && buf[end] == '\\')
 
271
                        buf[end] = '\x0';
 
272
 
 
273
                /* no continuation marker was found, so break */
 
274
                else
 
275
                        break;
 
276
                }
 
277
 
 
278
        my_free(tempbuf);
 
279
 
 
280
        return buf;
 
281
        }
 
282
 
 
283
/* strip newline, carriage return, and tab characters from beginning and end of a string */
 
284
void strip(char *buffer) {
 
285
        register int x, z;
 
286
        int len;
 
287
 
 
288
        if(buffer == NULL || buffer[0] == '\x0')
 
289
                return;
 
290
 
 
291
        /* strip end of string */
 
292
        len = (int)strlen(buffer);
 
293
        for(x = len - 1; x >= 0; x--) {
 
294
                switch(buffer[x]) {
 
295
                        case ' ':
 
296
                        case '\n':
 
297
                        case '\r':
 
298
                        case '\t':
 
299
                                buffer[x] = '\x0';
 
300
                                continue;
 
301
                        }
 
302
                break;
 
303
                }
 
304
 
 
305
        /* if we stripped all of it, just return */
 
306
        if(!x)
 
307
                return;
 
308
 
 
309
        /* save last position for later... */
 
310
        z = x;
 
311
 
 
312
        /* strip beginning of string (by shifting) */
 
313
        /* NOTE: this is very expensive to do, so avoid it whenever possible */
 
314
        for(x = 0;; x++) {
 
315
                switch(buffer[x]) {
 
316
                        case ' ':
 
317
                        case '\n':
 
318
                        case '\r':
 
319
                        case '\t':
 
320
                                continue;
 
321
                        }
 
322
                break;
 
323
                }
 
324
 
 
325
        if(x > 0 && z > 0) {
 
326
                /* new length of the string after we stripped the end */
 
327
                len = z + 1;
 
328
 
 
329
                /* shift chars towards beginning of string to remove leading whitespace */
 
330
                for(z = x; z < len; z++)
 
331
                        buffer[z - x] = buffer[z];
 
332
                buffer[len - x] = '\x0';
 
333
                }
 
334
        }
 
335
 
 
336
/**************************************************
 
337
 *************** HASH FUNCTIONS *******************
 
338
 **************************************************/
 
339
/* dual hash function */
 
340
int hashfunc(const char *name1, const char *name2, int hashslots) {
 
341
        unsigned int i, result;
 
342
 
 
343
        result = 0;
 
344
 
 
345
        if(name1)
 
346
                for(i = 0; i < strlen(name1); i++)
 
347
                        result += name1[i];
 
348
 
 
349
        if(name2)
 
350
                for(i = 0; i < strlen(name2); i++)
 
351
                        result += name2[i];
 
352
 
 
353
        result = result % hashslots;
 
354
 
 
355
        return result;
 
356
        }
 
357
 
 
358
/* dual hash data comparison */
 
359
int compare_hashdata(const char *val1a, const char *val1b, const char *val2a,
 
360
                     const char *val2b) {
 
361
        int result = 0;
 
362
 
 
363
        /* NOTE: If hash calculation changes, update the compare_strings() function! */
 
364
 
 
365
        /* check first name */
 
366
        if(val1a == NULL && val2a == NULL)
 
367
                result = 0;
 
368
        else if(val1a == NULL)
 
369
                result = 1;
 
370
        else if(val2a == NULL)
 
371
                result = -1;
 
372
        else
 
373
                result = strcmp(val1a, val2a);
 
374
 
 
375
        /* check second name if necessary */
 
376
        if(result == 0) {
 
377
                if(val1b == NULL && val2b == NULL)
 
378
                        result = 0;
 
379
                else if(val1b == NULL)
 
380
                        result = 1;
 
381
                else if(val2b == NULL)
 
382
                        result = -1;
 
383
                else
 
384
                        result = strcmp(val1b, val2b);
 
385
                }
 
386
 
 
387
        return result;
 
388
        }
 
389
/*
 
390
 * given a date/time in time_t format, produce a corresponding
 
391
 * date/time string, including timezone
 
392
 */
 
393
void get_datetime_string(time_t * raw_time, char *buffer, int buffer_length,
 
394
                         int type) {
 
395
        time_t t;
 
396
        struct tm *tm_ptr, tm_s;
 
397
        int hour;
 
398
        int minute;
 
399
        int second;
 
400
        int month;
 
401
        int day;
 
402
        int year;
 
403
        char *weekdays[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
 
404
        char *months[12] = {
 
405
                "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept",
 
406
                "Oct", "Nov", "Dec"
 
407
                };
 
408
        char *tzone = "";
 
409
 
 
410
        if(raw_time == NULL)
 
411
                time(&t);
 
412
        else
 
413
                t = *raw_time;
 
414
 
 
415
        if(type == HTTP_DATE_TIME)
 
416
                tm_ptr = gmtime_r(&t, &tm_s);
 
417
        else
 
418
                tm_ptr = localtime_r(&t, &tm_s);
 
419
 
 
420
        hour = tm_ptr->tm_hour;
 
421
        minute = tm_ptr->tm_min;
 
422
        second = tm_ptr->tm_sec;
 
423
        month = tm_ptr->tm_mon + 1;
 
424
        day = tm_ptr->tm_mday;
 
425
        year = tm_ptr->tm_year + 1900;
 
426
 
 
427
#ifdef HAVE_TM_ZONE
 
428
        tzone = (char *)(tm_ptr->tm_zone);
 
429
#else
 
430
        tzone = (tm_ptr->tm_isdst) ? tzname[1] : tzname[0];
 
431
#endif
 
432
 
 
433
        /* ctime() style date/time */
 
434
        if(type == LONG_DATE_TIME)
 
435
                snprintf(buffer, buffer_length, "%s %s %d %02d:%02d:%02d %s %d",
 
436
                         weekdays[tm_ptr->tm_wday], months[tm_ptr->tm_mon], day,
 
437
                         hour, minute, second, tzone, year);
 
438
 
 
439
        /* short date/time */
 
440
        else if(type == SHORT_DATE_TIME) {
 
441
                if(date_format == DATE_FORMAT_EURO)
 
442
                        snprintf(buffer, buffer_length,
 
443
                                 "%02d-%02d-%04d %02d:%02d:%02d", day, month,
 
444
                                 year, hour, minute, second);
 
445
                else if(date_format == DATE_FORMAT_ISO8601
 
446
                        || date_format == DATE_FORMAT_STRICT_ISO8601)
 
447
                        snprintf(buffer, buffer_length,
 
448
                                 "%04d-%02d-%02d%c%02d:%02d:%02d", year, month,
 
449
                                 day,
 
450
                                 (date_format ==
 
451
                                  DATE_FORMAT_STRICT_ISO8601) ? 'T' : ' ', hour,
 
452
                                 minute, second);
 
453
                else
 
454
                        snprintf(buffer, buffer_length,
 
455
                                 "%02d-%02d-%04d %02d:%02d:%02d", month, day,
 
456
                                 year, hour, minute, second);
 
457
                }
 
458
 
 
459
        /* short date */
 
460
        else if(type == SHORT_DATE) {
 
461
                if(date_format == DATE_FORMAT_EURO)
 
462
                        snprintf(buffer, buffer_length, "%02d-%02d-%04d", day,
 
463
                                 month, year);
 
464
                else if(date_format == DATE_FORMAT_ISO8601
 
465
                        || date_format == DATE_FORMAT_STRICT_ISO8601)
 
466
                        snprintf(buffer, buffer_length, "%04d-%02d-%02d", year,
 
467
                                 month, day);
 
468
                else
 
469
                        snprintf(buffer, buffer_length, "%02d-%02d-%04d", month,
 
470
                                 day, year);
 
471
                }
 
472
 
 
473
        /* expiration date/time for HTTP headers */
 
474
        else if(type == HTTP_DATE_TIME)
 
475
                snprintf(buffer, buffer_length,
 
476
                         "%s, %02d %s %d %02d:%02d:%02d GMT",
 
477
                         weekdays[tm_ptr->tm_wday], day, months[tm_ptr->tm_mon],
 
478
                         year, hour, minute, second);
 
479
 
 
480
        /* short time */
 
481
        else
 
482
                snprintf(buffer, buffer_length, "%02d:%02d:%02d", hour, minute,
 
483
                         second);
 
484
 
 
485
        buffer[buffer_length - 1] = '\x0';
 
486
        }
 
487
 
 
488
/* get days, hours, minutes, and seconds from a raw time_t format or total seconds */
 
489
void get_time_breakdown(unsigned long raw_time, int *days, int *hours,
 
490
                        int *minutes, int *seconds) {
 
491
        unsigned long temp_time;
 
492
        int temp_days;
 
493
        int temp_hours;
 
494
        int temp_minutes;
 
495
        int temp_seconds;
 
496
 
 
497
        temp_time = raw_time;
 
498
 
 
499
        temp_days = temp_time / 86400;
 
500
        temp_time -= (temp_days * 86400);
 
501
        temp_hours = temp_time / 3600;
 
502
        temp_time -= (temp_hours * 3600);
 
503
        temp_minutes = temp_time / 60;
 
504
        temp_time -= (temp_minutes * 60);
 
505
        temp_seconds = (int)temp_time;
 
506
 
 
507
        *days = temp_days;
 
508
        *hours = temp_hours;
 
509
        *minutes = temp_minutes;
 
510
        *seconds = temp_seconds;
 
511
        }