]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bsys.c
- Remove warning message about multiple saves of hardlinked files
[bacula/bacula] / bacula / src / lib / bsys.c
1 /*
2  * Miscellaneous Bacula memory and thread safe routines
3  *   Generally, these are interfaces to system or standard
4  *   library routines.
5  *
6  *  Bacula utility functions are in util.c
7  *
8  *   Version $Id$
9  */
10 /*
11    Copyright (C) 2000-2005 Kern Sibbald
12
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.
17
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.
22
23  */
24
25
26 #include "bacula.h"
27 #ifdef HAVE_PWD_H
28 #include <pwd.h>
29 #endif
30 #ifdef HAVE_GRP_H
31 #include <grp.h>
32 #endif
33
34 static pthread_mutex_t timer_mutex = PTHREAD_MUTEX_INITIALIZER;
35 static pthread_cond_t timer = PTHREAD_COND_INITIALIZER;
36
37 /*
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
41  *   requested time.
42  */
43 int bmicrosleep(time_t sec, long usec)
44 {
45    struct timespec timeout;
46    struct timeval tv;
47    struct timezone tz;
48    int stat;
49
50    timeout.tv_sec = sec;
51    timeout.tv_nsec = usec * 1000;
52
53 #ifdef HAVE_NANOSLEEP
54    stat = nanosleep(&timeout, NULL);
55    if (!(stat < 0 && errno == ENOSYS)) {
56       return stat;
57    }
58    /* If we reach here it is because nanosleep is not supported by the OS */
59 #endif
60
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;
67       timeout.tv_sec++;
68    }
69
70    Dmsg2(200, "pthread_cond_timedwait sec=%d usec=%d\n", sec, usec);
71    /* Note, this unlocks mutex during the sleep */
72    P(timer_mutex);
73    stat = pthread_cond_timedwait(&timer, &timer_mutex, &timeout);
74    if (stat != 0) {
75       berrno be;
76       Dmsg2(200, "pthread_cond_timedwait stat=%d ERR=%s\n", stat,
77          be.strerror(stat));
78    }
79    V(timer_mutex);
80    return stat;
81 }
82
83 /*
84  * Guarantee that the string is properly terminated */
85 char *bstrncpy(char *dest, const char *src, int maxlen)
86 {
87    strncpy(dest, src, maxlen-1);
88    dest[maxlen-1] = 0;
89    return dest;
90 }
91
92 /*
93  * Guarantee that the string is properly terminated */
94 char *bstrncpy(char *dest, POOL_MEM &src, int maxlen)
95 {
96    strncpy(dest, src.c_str(), maxlen-1);
97    dest[maxlen-1] = 0;
98    return dest;
99 }
100
101
102 char *bstrncat(char *dest, const char *src, int maxlen)
103 {
104    strncat(dest, src, maxlen-1);
105    dest[maxlen-1] = 0;
106    return dest;
107 }
108
109 char *bstrncat(char *dest, POOL_MEM &src, int maxlen)
110 {
111    strncat(dest, src.c_str(), maxlen-1);
112    dest[maxlen-1] = 0;
113    return dest;
114 }
115
116 /*
117  * Get character length of UTF-8 string
118  *
119  * Valid UTF-8 codes
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
126  */
127 int cstrlen(const char *str)
128 {
129    uint8_t *p = (uint8_t *)str;
130    int len = 0;
131    while (*p) {
132       if ((*p & 0xC0) != 0xC0) {
133          p++;
134          len++;
135          continue;
136       }
137       if ((*p & 0xD0) == 0xC0) {
138          p += 2;
139          len++;
140          continue;
141       }
142       if ((*p & 0xF0) == 0xD0) {
143          p += 3;
144          len++;
145          continue;
146       }
147       if ((*p & 0xF8) == 0xF0) {
148          p += 4;
149          len++;
150          continue;
151       }
152       if ((*p & 0xFC) == 0xF8) {
153          p += 5;
154          len++;
155          continue;
156       }
157       if ((*p & 0xFE) == 0xFC) {
158          p += 6;
159          len++;
160          continue;
161       }
162       p++;                      /* Shouln't get here but must advance */
163    }
164    return len;
165 }
166
167
168
169 #ifndef DEBUG
170 void *bmalloc(size_t size)
171 {
172   void *buf;
173
174   buf = malloc(size);
175   if (buf == NULL) {
176      Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
177   }
178   return buf;
179 }
180 #endif
181
182 void *b_malloc(const char *file, int line, size_t size)
183 {
184   void *buf;
185
186 #ifdef SMARTALLOC
187   buf = sm_malloc(file, line, size);
188 #else
189   buf = malloc(size);
190 #endif
191   if (buf == NULL) {
192      e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
193   }
194   return buf;
195 }
196
197
198 void *brealloc (void *buf, size_t size)
199 {
200    buf = realloc(buf, size);
201    if (buf == NULL) {
202       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
203    }
204    return buf;
205 }
206
207
208 void *bcalloc (size_t size1, size_t size2)
209 {
210   void *buf;
211
212    buf = calloc(size1, size2);
213    if (buf == NULL) {
214       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), strerror(errno));
215    }
216    return buf;
217 }
218
219 /* Code now in src/lib/bsnprintf.c */
220 #ifndef USE_BSNPRINTF
221
222 #define BIG_BUF 5000
223 /*
224  * Implement snprintf
225  */
226 int bsnprintf(char *str, int32_t size, const char *fmt,  ...)
227 {
228    va_list   arg_ptr;
229    int len;
230
231    va_start(arg_ptr, fmt);
232    len = bvsnprintf(str, size, fmt, arg_ptr);
233    va_end(arg_ptr);
234    return len;
235 }
236
237 /*
238  * Implement vsnprintf()
239  */
240 int bvsnprintf(char *str, int32_t size, const char  *format, va_list ap)
241 {
242 #ifdef HAVE_VSNPRINTF
243    int len;
244    len = vsnprintf(str, size, format, ap);
245    str[size-1] = 0;
246    return len;
247
248 #else
249
250    int len, buflen;
251    char *buf;
252    buflen = size > BIG_BUF ? size : BIG_BUF;
253    buf = get_memory(buflen);
254    len = vsprintf(buf, format, ap);
255    if (len >= buflen) {
256       Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
257    }
258    memcpy(str, buf, len);
259    str[len] = 0;                /* len excludes the null */
260    free_memory(buf);
261    return len;
262 #endif
263 }
264 #endif /* USE_BSNPRINTF */
265
266 #ifndef HAVE_LOCALTIME_R
267
268 struct tm *localtime_r(const time_t *timep, struct tm *tm)
269 {
270     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
271     struct tm *ltm,
272
273     P(mutex);
274     ltm = localtime(timep);
275     if (ltm) {
276        memcpy(tm, ltm, sizeof(struct tm));
277     }
278     V(mutex);
279     return ltm ? tm : NULL;
280 }
281 #endif /* HAVE_LOCALTIME_R */
282
283 #ifndef HAVE_READDIR_R
284 #ifndef HAVE_WIN32
285 #include <dirent.h>
286
287 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
288 {
289     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
290     struct dirent *ndir;
291     int stat;
292
293     P(mutex);
294     errno = 0;
295     ndir = readdir(dirp);
296     stat = errno;
297     if (ndir) {
298        memcpy(entry, ndir, sizeof(struct dirent));
299        strcpy(entry->d_name, ndir->d_name);
300        *result = entry;
301     } else {
302        *result = NULL;
303     }
304     V(mutex);
305     return stat;
306
307 }
308 #endif
309 #endif /* HAVE_READDIR_R */
310
311
312 int bstrerror(int errnum, char *buf, size_t bufsiz)
313 {
314     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
315     int stat = 0;
316     const char *msg;
317
318     P(mutex);
319
320     msg = strerror(errnum);
321     if (!msg) {
322        msg = _("Bad errno");
323        stat = -1;
324     }
325     bstrncpy(buf, msg, bufsiz);
326     V(mutex);
327     return stat;
328 }
329
330 /*
331  * These are mutex routines that do error checking
332  *  for deadlock and such.  Normally not turned on.
333  */
334 #ifdef DEBUG_MUTEX
335 void _p(char *file, int line, pthread_mutex_t *m)
336 {
337    int errstat;
338    if ((errstat = pthread_mutex_trylock(m))) {
339       e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock.\n"));
340       /* We didn't get the lock, so do it definitely now */
341       if ((errstat=pthread_mutex_lock(m))) {
342          berrno be;
343          e_msg(file, line, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
344                be.strerror(errstat));
345       } else {
346          e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock resolved.\n"));
347       }
348
349    }
350 }
351
352 void _v(char *file, int line, pthread_mutex_t *m)
353 {
354    int errstat;
355
356    if ((errstat=pthread_mutex_trylock(m)) == 0) {
357       berrno be;
358       e_msg(file, line, M_ERROR, 0, _("Mutex unlock not locked. ERR=%s\n"),
359            be.strerror(errstat));
360     }
361     if ((errstat=pthread_mutex_unlock(m))) {
362        berrno be;
363        e_msg(file, line, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
364               be.strerror(errstat));
365     }
366 }
367
368 #else
369
370 void _p(pthread_mutex_t *m)
371 {
372    int errstat;
373    if ((errstat=pthread_mutex_lock(m))) {
374       berrno be;
375       e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
376             be.strerror(errstat));
377    }
378 }
379
380 void _v(pthread_mutex_t *m)
381 {
382    int errstat;
383    if ((errstat=pthread_mutex_unlock(m))) {
384       berrno be;
385       e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
386             be.strerror(errstat));
387    }
388 }
389
390 #endif /* DEBUG_MUTEX */
391
392 #ifdef DEBUG_MEMSET
393 /* These routines are not normally turned on */
394 #undef memset
395 void b_memset(const char *file, int line, void *mem, int val, size_t num)
396 {
397    /* Testing for 2000 byte zero at beginning of Volume block */
398    if (num > 1900 && num < 3000) {
399       Pmsg3(000, _("Memset for %d bytes at %s:%d\n"), (int)num, file, line);
400    }
401    memset(mem, val, num);
402 }
403 #endif
404
405 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
406 static int del_pid_file_ok = FALSE;
407 #endif
408
409 /*
410  * Create a standard "Unix" pid file.
411  */
412 void create_pid_file(char *dir, const char *progname, int port)
413 {
414 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
415    int pidfd, len;
416    int oldpid;
417    char  pidbuf[20];
418    POOLMEM *fname = get_pool_memory(PM_FNAME);
419    struct stat statp;
420
421    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
422    if (stat(fname, &statp) == 0) {
423       /* File exists, see what we have */
424       *pidbuf = 0;
425       if ((pidfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0 ||
426            read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
427            sscanf(pidbuf, "%d", &oldpid) != 1) {
428          Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno));
429       }
430       /* See if other Bacula is still alive */
431       if (kill(oldpid, 0) != -1 || errno != ESRCH) {
432          Emsg3(M_ERROR_TERM, 0, _("%s is already running. pid=%d\nCheck file %s\n"),
433                progname, oldpid, fname);
434       }
435       /* He is not alive, so take over file ownership */
436       unlink(fname);                  /* remove stale pid file */
437    }
438    /* Create new pid file */
439    if ((pidfd = open(fname, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) >= 0) {
440       len = sprintf(pidbuf, "%d\n", (int)getpid());
441       write(pidfd, pidbuf, len);
442       close(pidfd);
443       del_pid_file_ok = TRUE;         /* we created it so we can delete it */
444    } else {
445       Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, strerror(errno));
446    }
447    free_pool_memory(fname);
448 #endif
449 }
450
451
452 /*
453  * Delete the pid file if we created it
454  */
455 int delete_pid_file(char *dir, const char *progname, int port)
456 {
457 #if !defined(HAVE_CYGWIN)  && !defined(HAVE_WIN32)
458    POOLMEM *fname = get_pool_memory(PM_FNAME);
459
460    if (!del_pid_file_ok) {
461       free_pool_memory(fname);
462       return 0;
463    }
464    del_pid_file_ok = FALSE;
465    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
466    unlink(fname);
467    free_pool_memory(fname);
468 #endif
469    return 1;
470 }
471
472 struct s_state_hdr {
473    char id[14];
474    int32_t version;
475    uint64_t last_jobs_addr;
476    uint64_t reserved[20];
477 };
478
479 static struct s_state_hdr state_hdr = {
480    "Bacula State\n",
481    3,
482    0
483 };
484
485 /*
486  * Open and read the state file for the daemon
487  */
488 void read_state_file(char *dir, const char *progname, int port)
489 {
490    int sfd;
491    ssize_t stat;
492    bool ok = false;
493    POOLMEM *fname = get_pool_memory(PM_FNAME);
494    struct s_state_hdr hdr;
495    int hdr_size = sizeof(hdr);
496
497    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
498    /* If file exists, see what we have */
499 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
500    if ((sfd = open(fname, O_RDONLY|O_BINARY, 0)) < 0) {
501       Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
502                     sfd, sizeof(hdr), strerror(errno));
503       goto bail_out;
504    }
505    if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
506       Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
507                     sfd, (int)stat, hdr_size, strerror(errno));
508       goto bail_out;
509    }
510    if (hdr.version != state_hdr.version) {
511       Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
512          state_hdr.version, hdr.version);
513    }
514    hdr.id[13] = 0;
515    if (strcmp(hdr.id, state_hdr.id) != 0) {
516       Dmsg0(000, "State file header id invalid.\n");
517       goto bail_out;
518    }
519 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
520    if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
521       goto bail_out;
522    }
523    ok = true;
524 bail_out:
525    if (sfd >= 0) {
526       close(sfd);
527    }
528    if (!ok) {
529       unlink(fname);
530     }
531    free_pool_memory(fname);
532 }
533
534 /*
535  * Write the state file
536  */
537 void write_state_file(char *dir, const char *progname, int port)
538 {
539    int sfd;
540    bool ok = false;
541    POOLMEM *fname = get_pool_memory(PM_FNAME);
542
543    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
544    /* Create new state file */
545    if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
546       berrno be;
547       Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.strerror());
548       Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.strerror());
549       goto bail_out;
550    }
551    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
552       berrno be;
553       Dmsg1(000, "Write hdr error: ERR=%s\n", be.strerror());
554       goto bail_out;
555    }
556 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
557    state_hdr.last_jobs_addr = sizeof(state_hdr);
558    state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
559 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
560    if (lseek(sfd, 0, SEEK_SET) < 0) {
561       berrno be;
562       Dmsg1(000, "lseek error: ERR=%s\n", be.strerror());
563       goto bail_out;
564    }
565    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
566       berrno be;
567       Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.strerror());
568       goto bail_out;
569    }
570    ok = true;
571 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
572 bail_out:
573    if (sfd >= 0) {
574       close(sfd);
575    }
576    if (!ok) {
577       unlink(fname);
578    }
579    free_pool_memory(fname);
580 }
581
582
583 /*
584  * Drop to privilege new userid and new gid if non-NULL
585  */
586 void drop(char *uid, char *gid)
587 {
588 #ifdef HAVE_GRP_H
589    if (gid) {
590       struct group *group;
591       gid_t gr_list[1];
592
593       if ((group = getgrnam(gid)) == NULL) {
594          Emsg1(M_ERROR_TERM, 0, _("Could not find specified group: %s\n"), gid);
595       }
596       if (setgid(group->gr_gid)) {
597          Emsg1(M_ERROR_TERM, 0, _("Could not set specified group: %s\n"), gid);
598       }
599       gr_list[0] = group->gr_gid;
600       if (setgroups(1, gr_list)) {
601          Emsg1(M_ERROR_TERM, 0, _("Could not set specified group: %s\n"), gid);
602       }
603    }
604 #endif
605
606 #ifdef HAVE_PWD_H
607    if (uid) {
608       struct passwd *passw;
609       if ((passw = getpwnam(uid)) == NULL) {
610          Emsg1(M_ERROR_TERM, 0, _("Could not find specified userid: %s\n"), uid);
611       }
612       if (setuid(passw->pw_uid)) {
613          Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), uid);
614       }
615    }
616 #endif
617
618 }
619
620
621 /* BSDI does not have this.  This is a *poor* simulation */
622 #ifndef HAVE_STRTOLL
623 long long int
624 strtoll(const char *ptr, char **endptr, int base)
625 {
626    return (long long int)strtod(ptr, endptr);
627 }
628 #endif
629
630 /*
631  * Bacula's implementation of fgets(). The difference is that it handles
632  *   being interrupted by a signal (e.g. a SIGCHLD).
633  */
634 #undef fgetc
635 char *bfgets(char *s, int size, FILE *fd)
636 {
637    char *p = s;
638    int ch;
639    *p = 0;
640    for (int i=0; i < size-1; i++) {
641       do {
642          errno = 0;
643          ch = fgetc(fd);
644       } while (ch == -1 && (errno == EINTR || errno == EAGAIN));
645       if (ch == -1) {
646          if (i == 0) {
647             return NULL;
648          } else {
649             return s;
650          }
651       }
652       *p++ = ch;
653       *p = 0;
654       if (ch == '\r') { /* Support for Mac/Windows file format */
655          ch = fgetc(fd);
656          if (ch == '\n') { /* Windows (\r\n) */
657             *p++ = ch;
658             *p = 0;
659          }
660          else { /* Mac (\r only) */
661             ungetc(ch, fd); /* Push next character back to fd */
662          }
663          break;
664       }
665       if (ch == '\n') {
666          break;
667       }
668    }
669    return s;
670 }
671
672 /*
673  * Make a "unique" filename.  It is important that if
674  *   called again with the same "what" that the result
675  *   will be identical. This allows us to use the file
676  *   without saving its name, and re-generate the name
677  *   so that it can be deleted.
678  */
679 void make_unique_filename(POOLMEM **name, int Id, char *what)
680 {
681    Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
682 }