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-2005 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 * Get character length of UTF-8 string
120 * U-00000000 - U-0000007F: 0xxxxxxx
121 * U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
122 * U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
123 * U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
124 * U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
125 * U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
127 int cstrlen(const char *str)
129 uint8_t *p = (uint8_t *)str;
132 if ((*p & 0xC0) != 0xC0) {
137 if ((*p & 0xD0) == 0xC0) {
142 if ((*p & 0xF0) == 0xD0) {
147 if ((*p & 0xF8) == 0xF0) {
152 if ((*p & 0xFC) == 0xF8) {
157 if ((*p & 0xFE) == 0xFC) {
162 p++; /* Shouln't get here but must advance */
170 void *bmalloc(size_t size)
176 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
182 void *b_malloc(const char *file, int line, size_t size)
187 buf = sm_malloc(file, line, size);
192 e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
198 void *brealloc (void *buf, size_t size)
200 buf = realloc(buf, size);
202 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
208 void *bcalloc (size_t size1, size_t size2)
212 buf = calloc(size1, size2);
214 Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
224 int bsnprintf(char *str, int32_t size, const char *fmt, ...)
229 va_start(arg_ptr, fmt);
230 len = bvsnprintf(str, size, fmt, arg_ptr);
236 * Implement vsnprintf()
238 int bvsnprintf(char *str, int32_t size, const char *format, va_list ap)
240 #ifdef HAVE_VSNPRINTF
242 len = vsnprintf(str, size, format, ap);
250 buflen = size > BIG_BUF ? size : BIG_BUF;
251 buf = get_memory(buflen);
252 len = vsprintf(buf, format, ap);
254 Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
256 memcpy(str, buf, len);
257 str[len] = 0; /* len excludes the null */
263 #ifndef HAVE_LOCALTIME_R
265 struct tm *localtime_r(const time_t *timep, struct tm *tm)
267 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
271 ltm = localtime(timep);
273 memcpy(tm, ltm, sizeof(struct tm));
276 return ltm ? tm : NULL;
278 #endif /* HAVE_LOCALTIME_R */
280 #ifndef HAVE_READDIR_R
284 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
286 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
292 ndir = readdir(dirp);
295 memcpy(entry, ndir, sizeof(struct dirent));
296 strcpy(entry->d_name, ndir->d_name);
306 #endif /* HAVE_READDIR_R */
309 int bstrerror(int errnum, char *buf, size_t bufsiz)
311 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
317 msg = strerror(errnum);
319 msg = _("Bad errno");
322 bstrncpy(buf, msg, bufsiz);
328 * These are mutex routines that do error checking
329 * for deadlock and such. Normally not turned on.
332 void _p(char *file, int line, pthread_mutex_t *m)
335 if ((errstat = pthread_mutex_trylock(m))) {
336 e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock.\n"));
337 /* We didn't get the lock, so do it definitely now */
338 if ((errstat=pthread_mutex_lock(m))) {
340 e_msg(file, line, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
341 be.strerror(errstat));
343 e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock resolved.\n"));
349 void _v(char *file, int line, pthread_mutex_t *m)
353 if ((errstat=pthread_mutex_trylock(m)) == 0) {
355 e_msg(file, line, M_ERROR, 0, _("Mutex unlock not locked. ERR=%s\n"),
356 be.strerror(errstat));
358 if ((errstat=pthread_mutex_unlock(m))) {
360 e_msg(file, line, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
361 be.strerror(errstat));
367 void _p(pthread_mutex_t *m)
370 if ((errstat=pthread_mutex_lock(m))) {
372 e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
373 be.strerror(errstat));
377 void _v(pthread_mutex_t *m)
380 if ((errstat=pthread_mutex_unlock(m))) {
382 e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
383 be.strerror(errstat));
387 #endif /* DEBUG_MUTEX */
390 /* These routines are not normally turned on */
392 void b_memset(const char *file, int line, void *mem, int val, size_t num)
394 /* Testing for 2000 byte zero at beginning of Volume block */
395 if (num > 1900 && num < 3000) {
396 Pmsg3(000, "Memset for %d bytes at %s:%d\n", (int)num, file, line);
398 memset(mem, val, num);
402 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
403 static int del_pid_file_ok = FALSE;
407 * Create a standard "Unix" pid file.
409 void create_pid_file(char *dir, const char *progname, int port)
411 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
415 POOLMEM *fname = get_pool_memory(PM_FNAME);
418 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
419 if (stat(fname, &statp) == 0) {
420 /* File exists, see what we have */
422 if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
423 read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
424 sscanf(pidbuf, "%d", &oldpid) != 1) {
425 Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno));
427 /* See if other Bacula is still alive */
428 if (kill(oldpid, 0) != -1 || errno != ESRCH) {
429 Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
430 progname, oldpid, fname);
432 /* He is not alive, so take over file ownership */
433 unlink(fname); /* remove stale pid file */
435 /* Create new pid file */
436 if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
437 len = sprintf(pidbuf, "%d\n", (int)getpid());
438 write(pidfd, pidbuf, len);
440 del_pid_file_ok = TRUE; /* we created it so we can delete it */
442 Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, strerror(errno));
444 free_pool_memory(fname);
450 * Delete the pid file if we created it
452 int delete_pid_file(char *dir, const char *progname, int port)
454 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
455 POOLMEM *fname = get_pool_memory(PM_FNAME);
457 if (!del_pid_file_ok) {
458 free_pool_memory(fname);
461 del_pid_file_ok = FALSE;
462 Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
464 free_pool_memory(fname);
472 uint64_t last_jobs_addr;
473 uint64_t reserved[20];
476 static struct s_state_hdr state_hdr = {
483 * Open and read the state file for the daemon
485 void read_state_file(char *dir, const char *progname, int port)
489 POOLMEM *fname = get_pool_memory(PM_FNAME);
490 struct s_state_hdr hdr;
491 int hdr_size = sizeof(hdr);
493 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
494 /* If file exists, see what we have */
495 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
496 if ((sfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0) {
497 Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
498 sfd, sizeof(hdr), strerror(errno));
501 if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
502 Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
503 sfd, (int)stat, hdr_size, strerror(errno));
506 if (hdr.version != state_hdr.version) {
507 Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
508 state_hdr.version, hdr.version);
511 if (strcmp(hdr.id, state_hdr.id) != 0) {
512 Dmsg0(000, "State file header id invalid.\n");
515 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
516 read_last_jobs_list(sfd, hdr.last_jobs_addr);
521 free_pool_memory(fname);
525 * Write the state file
527 void write_state_file(char *dir, const char *progname, int port)
530 POOLMEM *fname = get_pool_memory(PM_FNAME);
532 Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
533 /* Create new state file */
534 if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
535 Dmsg2(000, _("Could not create state file. %s ERR=%s\n"), fname, strerror(errno));
536 Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, strerror(errno));
539 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
540 Dmsg1(000, "Write hdr error: ERR=%s\n", strerror(errno));
543 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
544 state_hdr.last_jobs_addr = sizeof(state_hdr);
545 state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
546 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
547 if (lseek(sfd, 0, SEEK_SET) < 0) {
548 Dmsg1(000, "lseek error: ERR=%s\n", strerror(errno));
551 if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
552 Pmsg1(000, "Write final hdr error: ERR=%s\n", strerror(errno));
554 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
559 free_pool_memory(fname);
564 * Drop to privilege new userid and new gid if non-NULL
566 void drop(char *uid, char *gid)
573 if ((group = getgrnam(gid)) == NULL) {
574 Emsg1(M_ERROR_TERM, 0, _("Could not find specified group: %s\n"), gid);
576 if (setgid(group->gr_gid)) {
577 Emsg1(M_ERROR_TERM, 0, _("Could not set specified group: %s\n"), gid);
579 gr_list[0] = group->gr_gid;
580 if (setgroups(1, gr_list)) {
581 Emsg1(M_ERROR_TERM, 0, _("Could not set specified group: %s\n"), gid);
588 struct passwd *passw;
589 if ((passw = getpwnam(uid)) == NULL) {
590 Emsg1(M_ERROR_TERM, 0, _("Could not find specified userid: %s\n"), uid);
592 if (setuid(passw->pw_uid)) {
593 Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), uid);
601 /* BSDI does not have this. This is a *poor* simulation */
604 strtoll(const char *ptr, char **endptr, int base)
606 return (long long int)strtod(ptr, endptr);
611 * Bacula's implementation of fgets(). The difference is that it handles
612 * being interrupted by a signal (e.g. a SIGCHLD).
615 char *bfgets(char *s, int size, FILE *fd)
620 for (int i=0; i < size-1; i++) {
624 } while (ch == -1 && (errno == EINTR || errno == EAGAIN));
634 if (ch == '\r') { /* Support for Mac/Windows file format */
636 if (ch == '\n') { /* Windows (\r\n) */
640 else { /* Mac (\r only) */
641 ungetc(ch, fd); /* Push next character back to fd */
653 * Make a "unique" filename. It is important that if
654 * called again with the same "what" that the result
655 * will be identical. This allows us to use the file
656 * without saving its name, and re-generate the name
657 * so that it can be deleted.
659 void make_unique_filename(POOLMEM **name, int Id, char *what)
661 Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);