]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bsys.c
Fix seg fault in SQlite driver
[bacula/bacula] / bacula / src / lib / bsys.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Miscellaneous Bacula memory and thread safe routines
30  *   Generally, these are interfaces to system or standard
31  *   library routines.
32  *
33  *  Bacula utility functions are in util.c
34  *
35  *   Version $Id$
36  */
37
38 #include "bacula.h"
39
40
41 static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
42 static pthread_cond_t timer = PTHREAD_COND_INITIALIZER;
43
44 /*
45  * This routine will sleep (sec, microsec).  Note, however, that if a
46  *   signal occurs, it will return early.  It is up to the caller
47  *   to recall this routine if he/she REALLY wants to sleep the
48  *   requested time.
49  */
50 int bmicrosleep(int32_t sec, int32_t usec)
51 {
52    struct timespec timeout;
53    struct timeval tv;
54    struct timezone tz;
55    int stat;
56
57    timeout.tv_sec = sec;
58    timeout.tv_nsec = usec * 1000;
59
60 #ifdef HAVE_NANOSLEEP
61    stat = nanosleep(&timeout, NULL);
62    if (!(stat < 0 && errno == ENOSYS)) {
63       return stat;
64    }
65    /* If we reach here it is because nanosleep is not supported by the OS */
66 #endif
67
68    /* Do it the old way */
69    gettimeofday(&tv, &tz);
70    timeout.tv_nsec += tv.tv_usec * 1000;
71    timeout.tv_sec += tv.tv_sec;
72    while (timeout.tv_nsec >= 1000000000) {
73       timeout.tv_nsec -= 1000000000;
74       timeout.tv_sec++;
75    }
76
77    Dmsg2(200, "pthread_cond_timedwait sec=%lld usec=%d\n", sec, usec);
78    /* Note, this unlocks mutex during the sleep */
79    P(timer_mutex);
80    stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout);
81    if (stat != 0) {
82       berrno be;
83       Dmsg2(200, "pthread_cond_timedwait stat=%d ERR=%s\n", stat,
84          be.bstrerror(stat));
85    }
86    V(timer_mutex);
87    return stat;
88 }
89
90 /*
91  * Guarantee that the string is properly terminated */
92 char *bstrncpy(char *dest, const char *src, int maxlen)
93 {
94    strncpy(dest, src, maxlen-1);
95    dest[maxlen-1] = 0;
96    return dest;
97 }
98
99 /*
100  * Guarantee that the string is properly terminated */
101 char *bstrncpy(char *dest, POOL_MEM &src, int maxlen)
102 {
103    strncpy(dest, src.c_str(), maxlen-1);
104    dest[maxlen-1] = 0;
105    return dest;
106 }
107
108 /*
109  * Note: Here the maxlen is the maximum length permitted
110  *  stored in dest, while on Unix systems, it is the maximum characters
111  *  that may be copied from src.
112  */
113 char *bstrncat(char *dest, const char *src, int maxlen)
114 {
115    int len = strlen(dest);
116    if (len < maxlen-1) {
117       strncpy(dest+len, src, maxlen-len-1);
118    }
119    dest[maxlen-1] = 0;
120    return dest;
121 }
122
123 /*
124  * Note: Here the maxlen is the maximum length permitted
125  *  stored in dest, while on Unix systems, it is the maximum characters
126  *  that may be copied from src.
127  */
128 char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
129 {
130    int len = strlen(dest);
131    if (len < maxlen-1) {
132       strncpy(dest+len, src.c_str(), maxlen-len-1);
133    }
134    dest[maxlen-1] = 0;
135    return dest;
136 }
137
138 /*
139  * Allows one or both pointers to be NULL
140  */
141 bool bstrcmp(const char *s1, const char *s2)
142 {
143    if (s1 == s2) return true;
144    if (s1 == NULL || s2 == NULL) return false;
145    return strcmp(s1, s2) == 0;
146 }
147
148 /*
149  * Get character length of UTF-8 string
150  *
151  * Valid UTF-8 codes
152  * U-00000000 - U-0000007F: 0xxxxxxx 
153  * U-00000080 - U-000007FF: 110xxxxx 10xxxxxx 
154  * U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 
155  * U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
156  * U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
157  * U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
158  */
159 int cstrlen(const char *str)
160 {
161    uint8_t *p = (uint8_t *)str;
162    int len = 0;
163    if (str == NULL) {
164       return 0;
165    }
166    while (*p) {
167       if ((*p & 0xC0) != 0xC0) {
168          p++;
169          len++;
170          continue;
171       }
172       if ((*p & 0xD0) == 0xC0) {
173          p += 2;
174          len++;
175          continue;
176       }
177       if ((*p & 0xF0) == 0xD0) {
178          p += 3;
179          len++;
180          continue;
181       }
182       if ((*p & 0xF8) == 0xF0) {
183          p += 4;
184          len++;
185          continue;
186       }
187       if ((*p & 0xFC) == 0xF8) {
188          p += 5;
189          len++;
190          continue;
191       }
192       if ((*p & 0xFE) == 0xFC) {
193          p += 6;
194          len++;
195          continue;
196       }
197       p++;                      /* Shouln't get here but must advance */
198    }
199    return len;
200 }
201
202
203
204 #ifndef bmalloc
205 void *bmalloc(size_t size)
206 {
207   void *buf;
208
209 #ifdef SMARTALLOC
210   buf = sm_malloc(file, line, size);
211 #else
212   buf = malloc(size);
213 #endif
214   if (buf == NULL) {
215      berrno be;
216      Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
217   }
218   return buf;
219 }
220 #endif
221
222 void *b_malloc(const char *file, int line, size_t size)
223 {
224   void *buf;
225
226 #ifdef SMARTALLOC
227   buf = sm_malloc(file, line, size);
228 #else
229   buf = malloc(size);
230 #endif
231   if (buf == NULL) {
232      berrno be;
233      e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
234   }
235   return buf;
236 }
237
238
239 void bfree(void *buf)
240 {
241 #ifdef SMARTALLOC
242   sm_free(__FILE__, __LINE__, buf);
243 #else
244   free(buf);
245 #endif
246 }
247
248 void *brealloc (void *buf, size_t size)
249 {
250 #ifdef SMARTALOC
251    buf = sm_realloc(__FILE__, __LINE__, buf, size);
252 #else
253    buf = realloc(buf, size);
254 #endif
255    if (buf == NULL) {
256       berrno be;
257       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
258    }
259    return buf;
260 }
261
262
263 void *bcalloc(size_t size1, size_t size2)
264 {
265   void *buf;
266
267    buf = calloc(size1, size2);
268    if (buf == NULL) {
269       berrno be;
270       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
271    }
272    return buf;
273 }
274
275 /* Code now in src/lib/bsnprintf.c */
276 #ifndef USE_BSNPRINTF
277
278 #define BIG_BUF 5000
279 /*
280  * Implement snprintf
281  */
282 int bsnprintf(char *str, int32_t size, const char *fmt,  ...)
283 {
284    va_list   arg_ptr;
285    int len;
286
287    va_start(arg_ptr, fmt);
288    len = bvsnprintf(str, size, fmt, arg_ptr);
289    va_end(arg_ptr);
290    return len;
291 }
292
293 /*
294  * Implement vsnprintf()
295  */
296 int bvsnprintf(char *str, int32_t size, const char  *format, va_list ap)
297 {
298 #ifdef HAVE_VSNPRINTF
299    int len;
300    len = vsnprintf(str, size, format, ap);
301    str[size-1] = 0;
302    return len;
303
304 #else
305
306    int len, buflen;
307    char *buf;
308    buflen = size > BIG_BUF ? size : BIG_BUF;
309    buf = get_memory(buflen);
310    len = vsprintf(buf, format, ap);
311    if (len >= buflen) {
312       Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
313    }
314    memcpy(str, buf, len);
315    str[len] = 0;                /* len excludes the null */
316    free_memory(buf);
317    return len;
318 #endif
319 }
320 #endif /* USE_BSNPRINTF */
321
322 #ifndef HAVE_LOCALTIME_R
323
324 struct tm *localtime_r(const time_t *timep, struct tm *tm)
325 {
326     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
327     struct tm *ltm,
328
329     P(mutex);
330     ltm = localtime(timep);
331     if (ltm) {
332        memcpy(tm, ltm, sizeof(struct tm));
333     }
334     V(mutex);
335     return ltm ? tm : NULL;
336 }
337 #endif /* HAVE_LOCALTIME_R */
338
339 #ifndef HAVE_READDIR_R
340 #ifndef HAVE_WIN32
341 #include <dirent.h>
342
343 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
344 {
345     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
346     struct dirent *ndir;
347     int stat;
348
349     P(mutex);
350     errno = 0;
351     ndir = readdir(dirp);
352     stat = errno;
353     if (ndir) {
354        memcpy(entry, ndir, sizeof(struct dirent));
355        strcpy(entry->d_name, ndir->d_name);
356        *result = entry;
357     } else {
358        *result = NULL;
359     }
360     V(mutex);
361     return stat;
362
363 }
364 #endif
365 #endif /* HAVE_READDIR_R */
366
367
368 int b_strerror(int errnum, char *buf, size_t bufsiz)
369 {
370     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
371     int stat = 0;
372     const char *msg;
373
374     P(mutex);
375
376     msg = strerror(errnum);
377     if (!msg) {
378        msg = _("Bad errno");
379        stat = -1;
380     }
381     bstrncpy(buf, msg, bufsiz);
382     V(mutex);
383     return stat;
384 }
385
386 #ifdef DEBUG_MEMSET
387 /* These routines are not normally turned on */
388 #undef memset
389 void b_memset(const char *file, int line, void *mem, int val, size_t num)
390 {
391    /* Testing for 2000 byte zero at beginning of Volume block */
392    if (num > 1900 && num < 3000) {
393       Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line);
394    }
395    memset(mem, val, num);
396 }
397 #endif
398
399 #if !defined(HAVE_WIN32)
400 static int del_pid_file_ok = FALSE;
401 #endif
402
403 /*
404  * Create a standard "Unix" pid file.
405  */
406 void create_pid_file(char *dir, const char *progname, int port)
407 {
408 #if !defined(HAVE_WIN32)
409    int pidfd, len;
410    int oldpid;
411    char  pidbuf[20];
412    POOLMEM *fname = get_pool_memory(PM_FNAME);
413    struct stat statp;
414
415    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
416    if (stat(fname, &statp) == 0) {
417       /* File exists, see what we have */
418       *pidbuf = 0;
419       if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
420            read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
421            sscanf(pidbuf, "%d", &oldpid) != 1) {
422          berrno be;
423          Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, 
424                be.bstrerror());
425       }
426       /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and
427        * since they use a deterministic algorithm for assigning PIDs, we can have
428        * pid conflicts with the old PID file after a reboot.
429        * The intent the following code is to check if the oldpid read from the pid
430        * file is the same as the currently executing process's pid,
431        * and if oldpid == getpid(), skip the attempt to
432        * kill(oldpid,0), since the attempt is guaranteed to succeed,
433        * but the success won't actually mean that there is an
434        * another Bacula process already running.
435        * For more details see bug #797.
436        */
437        if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) {
438          Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
439                progname, oldpid, fname);
440       }
441       /* He is not alive, so take over file ownership */
442       unlink(fname);                  /* remove stale pid file */
443    }
444    /* Create new pid file */
445    if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
446       len = sprintf(pidbuf, "%d\n", (int)getpid());
447       write(pidfd, pidbuf, len);
448       close(pidfd);
449       del_pid_file_ok = TRUE;         /* we created it so we can delete it */
450    } else {
451       berrno be;
452       Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, 
453             be.bstrerror());
454    }
455    free_pool_memory(fname);
456 #endif
457 }
458
459
460 /*
461  * Delete the pid file if we created it
462  */
463 int delete_pid_file(char *dir, const char *progname, int port)
464 {
465 #if !defined(HAVE_WIN32)
466    POOLMEM *fname = get_pool_memory(PM_FNAME);
467
468    if (!del_pid_file_ok) {
469       free_pool_memory(fname);
470       return 0;
471    }
472    del_pid_file_ok = FALSE;
473    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
474    unlink(fname);
475    free_pool_memory(fname);
476 #endif
477    return 1;
478 }
479
480 struct s_state_hdr {
481    char id[14];
482    int32_t version;
483    uint64_t last_jobs_addr;
484    uint64_t reserved[20];
485 };
486
487 static struct s_state_hdr state_hdr = {
488    "Bacula State\n",
489    4,
490    0
491 };
492
493 /*
494  * Open and read the state file for the daemon
495  */
496 void read_state_file(char *dir, const char *progname, int port)
497 {
498    int sfd;
499    ssize_t stat;
500    bool ok = false;
501    POOLMEM *fname = get_pool_memory(PM_FNAME);
502    struct s_state_hdr hdr;
503    int hdr_size = sizeof(hdr);
504
505    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
506    /* If file exists, see what we have */
507 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
508    if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) {
509       berrno be;
510       Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
511                     sfd, sizeof(hdr), be.bstrerror());
512       goto bail_out;
513    }
514    if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
515       berrno be;
516       Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
517                     sfd, (int)stat, hdr_size, be.bstrerror());
518       goto bail_out;
519    }
520    if (hdr.version != state_hdr.version) {
521       Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
522          state_hdr.version, hdr.version);
523       goto bail_out;
524    }
525    hdr.id[13] = 0;
526    if (strcmp(hdr.id, state_hdr.id) != 0) {
527       Dmsg0(000, "State file header id invalid.\n");
528       goto bail_out;
529    }
530 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
531    if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
532       goto bail_out;
533    }
534    ok = true;
535 bail_out:
536    if (sfd >= 0) {
537       close(sfd);
538    }
539    if (!ok) {
540       unlink(fname);
541     }
542    free_pool_memory(fname);
543 }
544
545 /*
546  * Write the state file
547  */
548 void write_state_file(char *dir, const char *progname, int port)
549 {
550    int sfd;
551    bool ok = false;
552    POOLMEM *fname = get_pool_memory(PM_FNAME);
553
554    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
555    /* Create new state file */
556    unlink(fname);
557    if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
558       berrno be;
559       Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.bstrerror());
560       Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.bstrerror());
561       goto bail_out;
562    }
563    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
564       berrno be;
565       Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
566       goto bail_out;
567    }
568 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
569    state_hdr.last_jobs_addr = sizeof(state_hdr);
570    state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
571 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
572    if (lseek(sfd, 0, SEEK_SET) < 0) {
573       berrno be;
574       Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror());
575       goto bail_out;
576    }
577    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
578       berrno be;
579       Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror());
580       goto bail_out;
581    }
582    ok = true;
583 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
584 bail_out:
585    if (sfd >= 0) {
586       close(sfd);
587    }
588    if (!ok) {
589       unlink(fname);
590    }
591    free_pool_memory(fname);
592 }
593
594
595 /* BSDI does not have this.  This is a *poor* simulation */
596 #ifndef HAVE_STRTOLL
597 long long int
598 strtoll(const char *ptr, char **endptr, int base)
599 {
600    return (long long int)strtod(ptr, endptr);
601 }
602 #endif
603
604 /*
605  * Bacula's implementation of fgets(). The difference is that it handles
606  *   being interrupted by a signal (e.g. a SIGCHLD).
607  */
608 #undef fgetc
609 char *bfgets(char *s, int size, FILE *fd)
610 {
611    char *p = s;
612    int ch;
613    *p = 0;
614    for (int i=0; i < size-1; i++) {
615       do {
616          errno = 0;
617          ch = fgetc(fd);
618       } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
619       if (ch == EOF) {
620          if (i == 0) {
621             return NULL;
622          } else {
623             return s;
624          }
625       }
626       *p++ = ch;
627       *p = 0;
628       if (ch == '\r') { /* Support for Mac/Windows file format */
629          ch = fgetc(fd);
630          if (ch != '\n') { /* Mac (\r only) */
631             (void)ungetc(ch, fd); /* Push next character back to fd */
632          }
633          p[-1] = '\n';
634          break;
635       }
636       if (ch == '\n') {
637          break;
638       }
639    }
640    return s;
641 }
642
643 /*
644  * Make a "unique" filename.  It is important that if
645  *   called again with the same "what" that the result
646  *   will be identical. This allows us to use the file
647  *   without saving its name, and re-generate the name
648  *   so that it can be deleted.
649  */
650 void make_unique_filename(POOLMEM **name, int Id, char *what)
651 {
652    Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
653 }
654
655 char *escape_filename(const char *file_path)
656 {
657    if (file_path == NULL || strpbrk(file_path, "\"\\") == NULL) {
658       return NULL;
659    }
660
661    char *escaped_path = (char *)bmalloc(2 * (strlen(file_path) + 1));
662    char *cur_char = escaped_path;
663
664    while (*file_path) {
665       if (*file_path == '\\' || *file_path == '"') {
666          *cur_char++ = '\\';
667       }
668
669       *cur_char++ = *file_path++;
670    }
671
672    *cur_char = '\0';
673
674    return escaped_path;
675 }