2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
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
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.
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
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.
29 * Miscellaneous Bacula memory and thread safe routines
30 * Generally, these are interfaces to system or standard
33 * Bacula utility functions are in util.c
41 static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
42 static pthread_cond_t timer = PTHREAD_COND_INITIALIZER;
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
50 int bmicrosleep(int32_t sec, int32_t usec)
52 struct timespec timeout;
58 timeout.tv_nsec = usec * 1000;
61 stat = nanosleep(&timeout, NULL);
62 if (!(stat < 0 && errno == ENOSYS)) {
65 /* If we reach here it is because nanosleep is not supported by the OS */
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;
77 Dmsg2(200, "pthread_cond_timedwait sec=%lld usec=%d\n", sec, usec);
78 /* Note, this unlocks mutex during the sleep */
80 stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout);
83 Dmsg2(200, "pthread_cond_timedwait stat=%d ERR=%s\n", stat,
91 * Guarantee that the string is properly terminated */
92 char *bstrncpy(char *dest, const char *src, int maxlen)
94 strncpy(dest, src, maxlen-1);
100 * Guarantee that the string is properly terminated */
101 char *bstrncpy(char *dest, POOL_MEM &src, int maxlen)
103 strncpy(dest, src.c_str(), maxlen-1);
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.
113 char *bstrncat(char *dest, const char *src, int maxlen)
115 int len = strlen(dest);
116 if (len < maxlen-1) {
117 strncpy(dest+len, src, maxlen-len-1);
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.
128 char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
130 int len = strlen(dest);
131 if (len < maxlen-1) {
132 strncpy(dest+len, src.c_str(), maxlen-len-1);
139 * Allows one or both pointers to be NULL
141 bool bstrcmp(const char *s1, const char *s2)
143 if (s1 == s2) return true;
144 if (s1 == NULL || s2 == NULL) return false;
145 return strcmp(s1, s2) == 0;
149 * Get character length of UTF-8 string
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
159 int cstrlen(const char *str)
161 uint8_t *p = (uint8_t *)str;
164 if ((*p & 0xC0) != 0xC0) {
169 if ((*p & 0xD0) == 0xC0) {
174 if ((*p & 0xF0) == 0xD0) {
179 if ((*p & 0xF8) == 0xF0) {
184 if ((*p & 0xFC) == 0xF8) {
189 if ((*p & 0xFE) == 0xFC) {
194 p++; /* Shouln't get here but must advance */
202 void *bmalloc(size_t size)
207 buf = sm_malloc(file, line, size);
213 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
219 void *b_malloc(const char *file, int line, size_t size)
224 buf = sm_malloc(file, line, size);
230 e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
236 void bfree(void *buf)
239 sm_free(__FILE__, __LINE__, buf);
245 void *brealloc (void *buf, size_t size)
248 buf = sm_realloc(__FILE__, __LINE__, buf, size);
250 buf = realloc(buf, size);
254 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
260 void *bcalloc(size_t size1, size_t size2)
264 buf = calloc(size1, size2);
267 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.bstrerror());
272 /* Code now in src/lib/bsnprintf.c */
273 #ifndef USE_BSNPRINTF
279 int bsnprintf(char *str, int32_t size, const char *fmt, ...)
284 va_start(arg_ptr, fmt);
285 len = bvsnprintf(str, size, fmt, arg_ptr);
291 * Implement vsnprintf()
293 int bvsnprintf(char *str, int32_t size, const char *format, va_list ap)
295 #ifdef HAVE_VSNPRINTF
297 len = vsnprintf(str, size, format, ap);
305 buflen = size > BIG_BUF ? size : BIG_BUF;
306 buf = get_memory(buflen);
307 len = vsprintf(buf, format, ap);
309 Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
311 memcpy(str, buf, len);
312 str[len] = 0; /* len excludes the null */
317 #endif /* USE_BSNPRINTF */
319 #ifndef HAVE_LOCALTIME_R
321 struct tm *localtime_r(const time_t *timep, struct tm *tm)
323 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
327 ltm = localtime(timep);
329 memcpy(tm, ltm, sizeof(struct tm));
332 return ltm ? tm : NULL;
334 #endif /* HAVE_LOCALTIME_R */
336 #ifndef HAVE_READDIR_R
340 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
342 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
348 ndir = readdir(dirp);
351 memcpy(entry, ndir, sizeof(struct dirent));
352 strcpy(entry->d_name, ndir->d_name);
362 #endif /* HAVE_READDIR_R */
365 int b_strerror(int errnum, char *buf, size_t bufsiz)
367 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
373 msg = strerror(errnum);
375 msg = _("Bad errno");
378 bstrncpy(buf, msg, bufsiz);
384 /* These routines are not normally turned on */
386 void b_memset(const char *file, int line, void *mem, int val, size_t num)
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);
392 memset(mem, val, num);
396 #if !defined(HAVE_WIN32)
397 static int del_pid_file_ok = FALSE;
401 * Create a standard "Unix" pid file.
403 void create_pid_file(char *dir, const char *progname, int port)
405 #if !defined(HAVE_WIN32)
409 POOLMEM *fname = get_pool_memory(PM_FNAME);
412 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
413 if (stat(fname, &statp) == 0) {
414 /* File exists, see what we have */
416 if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
417 read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
418 sscanf(pidbuf, "%d", &oldpid) != 1) {
420 Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname,
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.
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);
438 /* He is not alive, so take over file ownership */
439 unlink(fname); /* remove stale pid file */
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);
446 del_pid_file_ok = TRUE; /* we created it so we can delete it */
449 Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname,
452 free_pool_memory(fname);
458 * Delete the pid file if we created it
460 int delete_pid_file(char *dir, const char *progname, int port)
462 #if !defined(HAVE_WIN32)
463 POOLMEM *fname = get_pool_memory(PM_FNAME);
465 if (!del_pid_file_ok) {
466 free_pool_memory(fname);
469 del_pid_file_ok = FALSE;
470 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
472 free_pool_memory(fname);
480 uint64_t last_jobs_addr;
481 uint64_t reserved[20];
484 static struct s_state_hdr state_hdr = {
491 * Open and read the state file for the daemon
493 void read_state_file(char *dir, const char *progname, int port)
498 POOLMEM *fname = get_pool_memory(PM_FNAME);
499 struct s_state_hdr hdr;
500 int hdr_size = sizeof(hdr);
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) {
507 Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
508 sfd, sizeof(hdr), be.bstrerror());
511 if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
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());
517 if (hdr.version != state_hdr.version) {
518 Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
519 state_hdr.version, hdr.version);
523 if (strcmp(hdr.id, state_hdr.id) != 0) {
524 Dmsg0(000, "State file header id invalid.\n");
527 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
528 if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
539 free_pool_memory(fname);
543 * Write the state file
545 void write_state_file(char *dir, const char *progname, int port)
549 POOLMEM *fname = get_pool_memory(PM_FNAME);
551 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
552 /* Create new state file */
554 if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
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());
560 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
562 Dmsg1(000, "Write hdr error: ERR=%s\n", be.bstrerror());
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) {
571 Dmsg1(000, "lseek error: ERR=%s\n", be.bstrerror());
574 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
576 Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.bstrerror());
580 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
588 free_pool_memory(fname);
592 /* BSDI does not have this. This is a *poor* simulation */
595 strtoll(const char *ptr, char **endptr, int base)
597 return (long long int)strtod(ptr, endptr);
602 * Bacula's implementation of fgets(). The difference is that it handles
603 * being interrupted by a signal (e.g. a SIGCHLD).
606 char *bfgets(char *s, int size, FILE *fd)
611 for (int i=0; i < size-1; i++) {
615 } while (ch == EOF && ferror(fd) && (errno == EINTR || errno == EAGAIN));
625 if (ch == '\r') { /* Support for Mac/Windows file format */
627 if (ch != '\n') { /* Mac (\r only) */
628 (void)ungetc(ch, fd); /* Push next character back to fd */
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.
647 void make_unique_filename(POOLMEM **name, int Id, char *what)
649 Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
652 char *escape_filename(const char *file_path)
654 if (file_path == NULL || strpbrk(file_path, "\"\\") == NULL) {
658 char *escaped_path = (char *)bmalloc(2 * (strlen(file_path) + 1));
659 char *cur_char = escaped_path;
662 if (*file_path == '\\' || *file_path == '"') {
666 *cur_char++ = *file_path++;