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