]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bsys.c
Tweak mutex order for SD
[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    while (*p) {
164       if ((*p & 0xC0) != 0xC0) {
165          p++;
166          len++;
167          continue;
168       }
169       if ((*p & 0xD0) == 0xC0) {
170          p += 2;
171          len++;
172          continue;
173       }
174       if ((*p & 0xF0) == 0xD0) {
175          p += 3;
176          len++;
177          continue;
178       }
179       if ((*p & 0xF8) == 0xF0) {
180          p += 4;
181          len++;
182          continue;
183       }
184       if ((*p & 0xFC) == 0xF8) {
185          p += 5;
186          len++;
187          continue;
188       }
189       if ((*p & 0xFE) == 0xFC) {
190          p += 6;
191          len++;
192          continue;
193       }
194       p++;                      /* Shouln't get here but must advance */
195    }
196    return len;
197 }
198
199
200
201 #ifndef bmalloc
202 void *bmalloc(size_t size)
203 {
204   void *buf;
205
206 #ifdef SMARTALLOC
207   buf = sm_malloc(file, line, size);
208 #else
209   buf = malloc(size);
210 #endif
211   if (buf == NULL) {
212      berrno be;
213      Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
214   }
215   return buf;
216 }
217 #endif
218
219 void *b_malloc(const char *file, int line, size_t size)
220 {
221   void *buf;
222
223 #ifdef SMARTALLOC
224   buf = sm_malloc(file, line, size);
225 #else
226   buf = malloc(size);
227 #endif
228   if (buf == NULL) {
229      berrno be;
230      e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
231   }
232   return buf;
233 }
234
235
236 void bfree(void *buf)
237 {
238 #ifdef SMARTALLOC
239   sm_free(__FILE__, __LINE__, buf);
240 #else
241   free(buf);
242 #endif
243 }
244
245 void *brealloc (void *buf, size_t size)
246 {
247 #ifdef SMARTALOC
248    buf = sm_realloc(__FILE__, __LINE__, buf, size);
249 #else
250    buf = realloc(buf, size);
251 #endif
252    if (buf == NULL) {
253       berrno be;
254       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
255    }
256    return buf;
257 }
258
259
260 void *bcalloc(size_t size1, size_t size2)
261 {
262   void *buf;
263
264    buf = calloc(size1, size2);
265    if (buf == NULL) {
266       berrno be;
267       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
268    }
269    return buf;
270 }
271
272 /* Code now in src/lib/bsnprintf.c */
273 #ifndef USE_BSNPRINTF
274
275 #define BIG_BUF 5000
276 /*
277  * Implement snprintf
278  */
279 int bsnprintf(char *str, int32_t size, const char *fmt,  ...)
280 {
281    va_list   arg_ptr;
282    int len;
283
284    va_start(arg_ptr, fmt);
285    len = bvsnprintf(str, size, fmt, arg_ptr);
286    va_end(arg_ptr);
287    return len;
288 }
289
290 /*
291  * Implement vsnprintf()
292  */
293 int bvsnprintf(char *str, int32_t size, const char  *format, va_list ap)
294 {
295 #ifdef HAVE_VSNPRINTF
296    int len;
297    len = vsnprintf(str, size, format, ap);
298    str[size-1] = 0;
299    return len;
300
301 #else
302
303    int len, buflen;
304    char *buf;
305    buflen = size > BIG_BUF ? size : BIG_BUF;
306    buf = get_memory(buflen);
307    len = vsprintf(buf, format, ap);
308    if (len >= buflen) {
309       Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
310    }
311    memcpy(str, buf, len);
312    str[len] = 0;                /* len excludes the null */
313    free_memory(buf);
314    return len;
315 #endif
316 }
317 #endif /* USE_BSNPRINTF */
318
319 #ifndef HAVE_LOCALTIME_R
320
321 struct tm *localtime_r(const time_t *timep, struct tm *tm)
322 {
323     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
324     struct tm *ltm,
325
326     P(mutex);
327     ltm = localtime(timep);
328     if (ltm) {
329        memcpy(tm, ltm, sizeof(struct tm));
330     }
331     V(mutex);
332     return ltm ? tm : NULL;
333 }
334 #endif /* HAVE_LOCALTIME_R */
335
336 #ifndef HAVE_READDIR_R
337 #ifndef HAVE_WIN32
338 #include <dirent.h>
339
340 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
341 {
342     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
343     struct dirent *ndir;
344     int stat;
345
346     P(mutex);
347     errno = 0;
348     ndir = readdir(dirp);
349     stat = errno;
350     if (ndir) {
351        memcpy(entry, ndir, sizeof(struct dirent));
352        strcpy(entry->d_name, ndir->d_name);
353        *result = entry;
354     } else {
355        *result = NULL;
356     }
357     V(mutex);
358     return stat;
359
360 }
361 #endif
362 #endif /* HAVE_READDIR_R */
363
364
365 int b_strerror(int errnum, char *buf, size_t bufsiz)
366 {
367     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
368     int stat = 0;
369     const char *msg;
370
371     P(mutex);
372
373     msg = strerror(errnum);
374     if (!msg) {
375        msg = _("Bad errno");
376        stat = -1;
377     }
378     bstrncpy(buf, msg, bufsiz);
379     V(mutex);
380     return stat;
381 }
382
383 #ifdef DEBUG_MEMSET
384 /* These routines are not normally turned on */
385 #undef memset
386 void b_memset(const char *file, int line, void *mem, int val, size_t num)
387 {
388    /* Testing for 2000 byte zero at beginning of Volume block */
389    if (num > 1900 && num < 3000) {
390       Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line);
391    }
392    memset(mem, val, num);
393 }
394 #endif
395
396 #if !defined(HAVE_WIN32)
397 static int del_pid_file_ok = FALSE;
398 #endif
399
400 /*
401  * Create a standard "Unix" pid file.
402  */
403 void create_pid_file(char *dir, const char *progname, int port)
404 {
405 #if !defined(HAVE_WIN32)
406    int pidfd, len;
407    int oldpid;
408    char  pidbuf[20];
409    POOLMEM *fname = get_pool_memory(PM_FNAME);
410    struct stat statp;
411
412    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
413    if (stat(fname, &statp) == 0) {
414       /* File exists, see what we have */
415       *pidbuf = 0;
416       if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
417            read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
418            sscanf(pidbuf, "%d", &oldpid) != 1) {
419          berrno be;
420          Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, 
421                be.bstrerror());
422       }
423       /* Some OSes (IRIX) don't bother to clean out the old pid files after a crash, and
424        * since they use a deterministic algorithm for assigning PIDs, we can have
425        * pid conflicts with the old PID file after a reboot.
426        * The intent the following code is to check if the oldpid read from the pid
427        * file is the same as the currently executing process's pid,
428        * and if oldpid == getpid(), skip the attempt to
429        * kill(oldpid,0), since the attempt is guaranteed to succeed,
430        * but the success won't actually mean that there is an
431        * another Bacula process already running.
432        * For more details see bug #797.
433        */
434        if ((oldpid != (int)getpid()) && (kill(oldpid, 0) != -1 || errno != ESRCH)) {
435          Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
436                progname, oldpid, fname);
437       }
438       /* He is not alive, so take over file ownership */
439       unlink(fname);                  /* remove stale pid file */
440    }
441    /* Create new pid file */
442    if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
443       len = sprintf(pidbuf, "%d\n", (int)getpid());
444       write(pidfd, pidbuf, len);
445       close(pidfd);
446       del_pid_file_ok = TRUE;         /* we created it so we can delete it */
447    } else {
448       berrno be;
449       Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, 
450             be.bstrerror());
451    }
452    free_pool_memory(fname);
453 #endif
454 }
455
456
457 /*
458  * Delete the pid file if we created it
459  */
460 int delete_pid_file(char *dir, const char *progname, int port)
461 {
462 #if !defined(HAVE_WIN32)
463    POOLMEM *fname = get_pool_memory(PM_FNAME);
464
465    if (!del_pid_file_ok) {
466       free_pool_memory(fname);
467       return 0;
468    }
469    del_pid_file_ok = FALSE;
470    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
471    unlink(fname);
472    free_pool_memory(fname);
473 #endif
474    return 1;
475 }
476
477 struct s_state_hdr {
478    char id[14];
479    int32_t version;
480    uint64_t last_jobs_addr;
481    uint64_t reserved[20];
482 };
483
484 static struct s_state_hdr state_hdr = {
485    "Bacula State\n",
486    4,
487    0
488 };
489
490 /*
491  * Open and read the state file for the daemon
492  */
493 void read_state_file(char *dir, const char *progname, int port)
494 {
495    int sfd;
496    ssize_t stat;
497    bool ok = false;
498    POOLMEM *fname = get_pool_memory(PM_FNAME);
499    struct s_state_hdr hdr;
500    int hdr_size = sizeof(hdr);
501
502    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
503    /* If file exists, see what we have */
504 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
505    if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) {
506       berrno be;
507       Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
508                     sfd, sizeof(hdr), be.bstrerror());
509       goto bail_out;
510    }
511    if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
512       berrno be;
513       Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
514                     sfd, (int)stat, hdr_size, be.bstrerror());
515       goto bail_out;
516    }
517    if (hdr.version != state_hdr.version) {
518       Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
519          state_hdr.version, hdr.version);
520       goto bail_out;
521    }
522    hdr.id[13] = 0;
523    if (strcmp(hdr.id, state_hdr.id) != 0) {
524       Dmsg0(000, "State file header id invalid.\n");
525       goto bail_out;
526    }
527 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
528    if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
529       goto bail_out;
530    }
531    ok = true;
532 bail_out:
533    if (sfd >= 0) {
534       close(sfd);
535    }
536    if (!ok) {
537       unlink(fname);
538     }
539    free_pool_memory(fname);
540 }
541
542 /*
543  * Write the state file
544  */
545 void write_state_file(char *dir, const char *progname, int port)
546 {
547    int sfd;
548    bool ok = false;
549    POOLMEM *fname = get_pool_memory(PM_FNAME);
550
551    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
552    /* Create new state file */
553    unlink(fname);
554    if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
555       berrno be;
556       Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.bstrerror());
557       Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.bstrerror());
558       goto bail_out;
559    }
560    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
561       berrno be;
562       Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
563       goto bail_out;
564    }
565 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
566    state_hdr.last_jobs_addr = sizeof(state_hdr);
567    state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
568 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
569    if (lseek(sfd, 0, SEEK_SET) < 0) {
570       berrno be;
571       Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror());
572       goto bail_out;
573    }
574    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
575       berrno be;
576       Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror());
577       goto bail_out;
578    }
579    ok = true;
580 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
581 bail_out:
582    if (sfd >= 0) {
583       close(sfd);
584    }
585    if (!ok) {
586       unlink(fname);
587    }
588    free_pool_memory(fname);
589 }
590
591
592 /* BSDI does not have this.  This is a *poor* simulation */
593 #ifndef HAVE_STRTOLL
594 long long int
595 strtoll(const char *ptr, char **endptr, int base)
596 {
597    return (long long int)strtod(ptr, endptr);
598 }
599 #endif
600
601 /*
602  * Bacula's implementation of fgets(). The difference is that it handles
603  *   being interrupted by a signal (e.g. a SIGCHLD).
604  */
605 #undef fgetc
606 char *bfgets(char *s, int size, FILE *fd)
607 {
608    char *p = s;
609    int ch;
610    *p = 0;
611    for (int i=0; i < size-1; i++) {
612       do {
613          errno = 0;
614          ch = fgetc(fd);
615       } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
616       if (ch == EOF) {
617          if (i == 0) {
618             return NULL;
619          } else {
620             return s;
621          }
622       }
623       *p++ = ch;
624       *p = 0;
625       if (ch == '\r') { /* Support for Mac/Windows file format */
626          ch = fgetc(fd);
627          if (ch != '\n') { /* Mac (\r only) */
628             (void)ungetc(ch, fd); /* Push next character back to fd */
629          }
630          p[-1] = '\n';
631          break;
632       }
633       if (ch == '\n') {
634          break;
635       }
636    }
637    return s;
638 }
639
640 /*
641  * Make a "unique" filename.  It is important that if
642  *   called again with the same "what" that the result
643  *   will be identical. This allows us to use the file
644  *   without saving its name, and re-generate the name
645  *   so that it can be deleted.
646  */
647 void make_unique_filename(POOLMEM **name, int Id, char *what)
648 {
649    Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
650 }
651
652 char *escape_filename(const char *file_path)
653 {
654    if (file_path == NULL || strpbrk(file_path, "\"\\") == NULL) {
655       return NULL;
656    }
657
658    char *escaped_path = (char *)bmalloc(2 * (strlen(file_path) + 1));
659    char *cur_char = escaped_path;
660
661    while (*file_path) {
662       if (*file_path == '\\' || *file_path == '"') {
663          *cur_char++ = '\\';
664       }
665
666       *cur_char++ = *file_path++;
667    }
668
669    *cur_char = '\0';
670
671    return escaped_path;
672 }