2 * Miscellaneous Bacula memory and thread safe routines
3 * Generally, these are interfaces to system or standard
6 * Bacula utility functions are in util.c
11 Copyright (C) 2000-2006 Kern Sibbald
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License
15 version 2 as amended with additional clauses defined in the
16 file LICENSE in the main source directory.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 the file LICENSE for additional details.
34 static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
35 static pthread_cond_t timer = PTHREAD_COND_INITIALIZER;
38 * This routine will sleep (sec, microsec). Note, however, that if a
39 * signal occurs, it will return early. It is up to the caller
40 * to recall this routine if he/she REALLY wants to sleep the
43 int bmicrosleep(time_t sec, long usec)
45 struct timespec timeout;
51 timeout.tv_nsec = usec * 1000;
54 stat = nanosleep(&timeout, NULL);
55 if (!(stat < 0 && errno == ENOSYS)) {
58 /* If we reach here it is because nanosleep is not supported by the OS */
61 /* Do it the old way */
62 gettimeofday(&tv, &tz);
63 timeout.tv_nsec += tv.tv_usec * 1000;
64 timeout.tv_sec += tv.tv_sec;
65 while (timeout.tv_nsec >= 1000000000) {
66 timeout.tv_nsec -= 1000000000;
70 Dmsg2(200, "pthread_cond_timedwait sec=%d usec=%d\n", sec, usec);
71 /* Note, this unlocks mutex during the sleep */
73 stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout);
76 Dmsg2(200, "pthread_cond_timedwait stat=%d ERR=%s\n", stat,
84 * Guarantee that the string is properly terminated */
85 char *bstrncpy(char *dest, const char *src, int maxlen)
87 strncpy(dest, src, maxlen-1);
93 * Guarantee that the string is properly terminated */
94 char *bstrncpy(char *dest, POOL_MEM &src, int maxlen)
96 strncpy(dest, src.c_str(), maxlen-1);
102 char *bstrncat(char *dest, const char *src, int maxlen)
104 strncat(dest, src, maxlen-1);
109 char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
111 strncat(dest, src.c_str(), maxlen-1);
117 * Allows one or both pointers to be NULL
119 bool bstrcmp(const char *s1, const char *s2)
121 if (s1 == s2) return true;
122 if (s1 == NULL || s2 == NULL) return false;
123 return strcmp(s1, s2) == 0;
127 * Get character length of UTF-8 string
130 * U-00000000 - U-0000007F: 0xxxxxxx
131 * U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
132 * U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
133 * U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
134 * U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
135 * U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
137 int cstrlen(const char *str)
139 uint8_t *p = (uint8_t *)str;
142 if ((*p & 0xC0) != 0xC0) {
147 if ((*p & 0xD0) == 0xC0) {
152 if ((*p & 0xF0) == 0xD0) {
157 if ((*p & 0xF8) == 0xF0) {
162 if ((*p & 0xFC) == 0xF8) {
167 if ((*p & 0xFE) == 0xFC) {
172 p++; /* Shouln't get here but must advance */
180 void *bmalloc(size_t size)
187 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
193 void *b_malloc(const char *file, int line, size_t size)
198 buf = sm_malloc(file, line, size);
204 e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
210 void *brealloc (void *buf, size_t size)
212 buf = realloc(buf, size);
215 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
221 void *bcalloc (size_t size1, size_t size2)
225 buf = calloc(size1, size2);
228 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
233 /* Code now in src/lib/bsnprintf.c */
234 #ifndef USE_BSNPRINTF
240 int bsnprintf(char *str, int32_t size, const char *fmt, ...)
245 va_start(arg_ptr, fmt);
246 len = bvsnprintf(str, size, fmt, arg_ptr);
252 * Implement vsnprintf()
254 int bvsnprintf(char *str, int32_t size, const char *format, va_list ap)
256 #ifdef HAVE_VSNPRINTF
258 len = vsnprintf(str, size, format, ap);
266 buflen = size > BIG_BUF ? size : BIG_BUF;
267 buf = get_memory(buflen);
268 len = vsprintf(buf, format, ap);
270 Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
272 memcpy(str, buf, len);
273 str[len] = 0; /* len excludes the null */
278 #endif /* USE_BSNPRINTF */
280 #ifndef HAVE_LOCALTIME_R
282 struct tm *localtime_r(const time_t *timep, struct tm *tm)
284 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
288 ltm = localtime(timep);
290 memcpy(tm, ltm, sizeof(struct tm));
293 return ltm ? tm : NULL;
295 #endif /* HAVE_LOCALTIME_R */
297 #ifndef HAVE_READDIR_R
301 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
303 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
309 ndir = readdir(dirp);
312 memcpy(entry, ndir, sizeof(struct dirent));
313 strcpy(entry->d_name, ndir->d_name);
323 #endif /* HAVE_READDIR_R */
326 int bstrerror(int errnum, char *buf, size_t bufsiz)
328 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
334 msg = strerror(errnum);
336 msg = _("Bad errno");
339 bstrncpy(buf, msg, bufsiz);
345 * These are mutex routines that do error checking
346 * for deadlock and such. Normally not turned on.
349 void _p(char *file, int line, pthread_mutex_t *m)
352 if ((errstat = pthread_mutex_trylock(m))) {
353 e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock.\n"));
354 /* We didn't get the lock, so do it definitely now */
355 if ((errstat=pthread_mutex_lock(m))) {
357 e_msg(file, line, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
358 be.strerror(errstat));
360 e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock resolved.\n"));
366 void _v(char *file, int line, pthread_mutex_t *m)
370 /* Note, this trylock *should* fail if the mutex is locked */
371 if ((errstat=pthread_mutex_trylock(m)) == 0) {
373 e_msg(file, line, M_ERROR, 0, _("Mutex unlock not locked. ERR=%s\n"),
374 be.strerror(errstat));
376 if ((errstat=pthread_mutex_unlock(m))) {
378 e_msg(file, line, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
379 be.strerror(errstat));
385 void _p(pthread_mutex_t *m)
388 if ((errstat=pthread_mutex_lock(m))) {
390 e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
391 be.strerror(errstat));
395 void _v(pthread_mutex_t *m)
398 if ((errstat=pthread_mutex_unlock(m))) {
400 e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
401 be.strerror(errstat));
405 #endif /* DEBUG_MUTEX */
408 /* These routines are not normally turned on */
410 void b_memset(const char *file, int line, void *mem, int val, size_t num)
412 /* Testing for 2000 byte zero at beginning of Volume block */
413 if (num > 1900 && num < 3000) {
414 Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line);
416 memset(mem, val, num);
420 #if !defined(HAVE_WIN32)
421 static int del_pid_file_ok = FALSE;
425 * Create a standard "Unix" pid file.
427 void create_pid_file(char *dir, const char *progname, int port)
429 #if !defined(HAVE_WIN32)
433 POOLMEM *fname = get_pool_memory(PM_FNAME);
436 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
437 if (stat(fname, &statp) == 0) {
438 /* File exists, see what we have */
440 if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
441 read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
442 sscanf(pidbuf, "%d", &oldpid) != 1) {
443 Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno));
445 /* See if other Bacula is still alive */
446 if (kill(oldpid, 0) != -1 || errno != ESRCH) {
447 Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
448 progname, oldpid, fname);
450 /* He is not alive, so take over file ownership */
451 unlink(fname); /* remove stale pid file */
453 /* Create new pid file */
454 if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
455 len = sprintf(pidbuf, "%d\n", (int)getpid());
456 write(pidfd, pidbuf, len);
458 del_pid_file_ok = TRUE; /* we created it so we can delete it */
460 Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, strerror(errno));
462 free_pool_memory(fname);
468 * Delete the pid file if we created it
470 int delete_pid_file(char *dir, const char *progname, int port)
472 #if !defined(HAVE_WIN32)
473 POOLMEM *fname = get_pool_memory(PM_FNAME);
475 if (!del_pid_file_ok) {
476 free_pool_memory(fname);
479 del_pid_file_ok = FALSE;
480 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
482 free_pool_memory(fname);
490 uint64_t last_jobs_addr;
491 uint64_t reserved[20];
494 static struct s_state_hdr state_hdr = {
510 #define lseek _lseeki64
512 #define O_BINARY _O_BINARY
516 * Open and read the state file for the daemon
518 void read_state_file(char *dir, const char *progname, int port)
523 POOLMEM *fname = get_pool_memory(PM_FNAME);
524 struct s_state_hdr hdr;
525 int hdr_size = sizeof(hdr);
527 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
528 /* If file exists, see what we have */
529 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
530 if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) {
531 Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
532 sfd, sizeof(hdr), strerror(errno));
535 if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
536 Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
537 sfd, (int)stat, hdr_size, strerror(errno));
540 if (hdr.version != state_hdr.version) {
541 Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
542 state_hdr.version, hdr.version);
546 if (strcmp(hdr.id, state_hdr.id) != 0) {
547 Dmsg0(000, "State file header id invalid.\n");
550 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
551 if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
562 free_pool_memory(fname);
566 * Write the state file
568 void write_state_file(char *dir, const char *progname, int port)
572 POOLMEM *fname = get_pool_memory(PM_FNAME);
574 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
575 /* Create new state file */
577 if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
579 Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.strerror());
580 Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.strerror());
583 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
585 Dmsg1(000, "Write hdr error: ERR=%s\n", be.strerror());
588 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
589 state_hdr.last_jobs_addr = sizeof(state_hdr);
590 state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
591 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
592 if (lseek(sfd, 0, SEEK_SET) < 0) {
594 Dmsg1(000, "lseek error: ERR=%s\n", be.strerror());
597 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
599 Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.strerror());
603 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
611 free_pool_memory(fname);
616 * Drop to privilege new userid and new gid if non-NULL
618 void drop(char *uname, char *gname)
620 #if defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
621 struct passwd *passw = NULL;
622 struct group *group = NULL;
627 Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE");
628 if (!uname && !gname) {
629 return; /* Nothing to do */
633 if ((passw = getpwnam(uname)) == NULL) {
635 Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname,
639 if ((passw = getpwuid(getuid())) == NULL) {
641 Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"),
644 uname = passw->pw_name;
647 /* Any OS uname pointer may get overwritten, so save name, uid, and gid */
648 bstrncpy(username, uname, sizeof(username));
652 if ((group = getgrnam(gname)) == NULL) {
654 Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname,
659 if (initgroups(username, gid)) {
662 Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"),
663 gname, username, be.strerror());
665 Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"),
666 username, be.strerror());
672 Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname,
678 Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username);
684 /* BSDI does not have this. This is a *poor* simulation */
687 strtoll(const char *ptr, char **endptr, int base)
689 return (long long int)strtod(ptr, endptr);
694 * Bacula's implementation of fgets(). The difference is that it handles
695 * being interrupted by a signal (e.g. a SIGCHLD).
698 char *bfgets(char *s, int size, FILE *fd)
703 for (int i=0; i < size-1; i++) {
707 } while (ch == -1 && (errno == EINTR || errno == EAGAIN));
717 if (ch == '\r') { /* Support for Mac/Windows file format */
719 if (ch == '\n') { /* Windows (\r\n) */
723 else { /* Mac (\r only) */
724 (void)ungetc(ch, fd); /* Push next character back to fd */
736 * Make a "unique" filename. It is important that if
737 * called again with the same "what" that the result
738 * will be identical. This allows us to use the file
739 * without saving its name, and re-generate the name
740 * so that it can be deleted.
742 void make_unique_filename(POOLMEM **name, int Id, char *what)
744 Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);