]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bsys.c
o fix : restore a crypted stream on a fd witch doen't define keys cause
[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-2006 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  * Allows one or both pointers to be NULL
118  */
119 bool bstrcmp(const char *s1, const char *s2)
120 {
121    if (s1 == s2) return true;
122    if (s1 == NULL || s2 == NULL) return false;
123    return strcmp(s1, s2) == 0;
124 }
125
126 /*
127  * Get character length of UTF-8 string
128  *
129  * Valid UTF-8 codes
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
136  */
137 int cstrlen(const char *str)
138 {
139    uint8_t *p = (uint8_t *)str;
140    int len = 0;
141    while (*p) {
142       if ((*p & 0xC0) != 0xC0) {
143          p++;
144          len++;
145          continue;
146       }
147       if ((*p & 0xD0) == 0xC0) {
148          p += 2;
149          len++;
150          continue;
151       }
152       if ((*p & 0xF0) == 0xD0) {
153          p += 3;
154          len++;
155          continue;
156       }
157       if ((*p & 0xF8) == 0xF0) {
158          p += 4;
159          len++;
160          continue;
161       }
162       if ((*p & 0xFC) == 0xF8) {
163          p += 5;
164          len++;
165          continue;
166       }
167       if ((*p & 0xFE) == 0xFC) {
168          p += 6;
169          len++;
170          continue;
171       }
172       p++;                      /* Shouln't get here but must advance */
173    }
174    return len;
175 }
176
177
178
179 #ifndef DEBUG
180 void *bmalloc(size_t size)
181 {
182   void *buf;
183
184   buf = malloc(size);
185   if (buf == NULL) {
186      berrno be;
187      Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
188   }
189   return buf;
190 }
191 #endif
192
193 void *b_malloc(const char *file, int line, size_t size)
194 {
195   void *buf;
196
197 #ifdef SMARTALLOC
198   buf = sm_malloc(file, line, size);
199 #else
200   buf = malloc(size);
201 #endif
202   if (buf == NULL) {
203      berrno be;
204      e_msg(file, line, M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
205   }
206   return buf;
207 }
208
209
210 void *brealloc (void *buf, size_t size)
211 {
212    buf = realloc(buf, size);
213    if (buf == NULL) {
214       berrno be;
215       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
216    }
217    return buf;
218 }
219
220
221 void *bcalloc (size_t size1, size_t size2)
222 {
223   void *buf;
224
225    buf = calloc(size1, size2);
226    if (buf == NULL) {
227       berrno be;
228       Emsg1(M_ABORT, 0, _("Out of memory: ERR=%s\n"), be.strerror());
229    }
230    return buf;
231 }
232
233 /* Code now in src/lib/bsnprintf.c */
234 #ifndef USE_BSNPRINTF
235
236 #define BIG_BUF 5000
237 /*
238  * Implement snprintf
239  */
240 int bsnprintf(char *str, int32_t size, const char *fmt,  ...)
241 {
242    va_list   arg_ptr;
243    int len;
244
245    va_start(arg_ptr, fmt);
246    len = bvsnprintf(str, size, fmt, arg_ptr);
247    va_end(arg_ptr);
248    return len;
249 }
250
251 /*
252  * Implement vsnprintf()
253  */
254 int bvsnprintf(char *str, int32_t size, const char  *format, va_list ap)
255 {
256 #ifdef HAVE_VSNPRINTF
257    int len;
258    len = vsnprintf(str, size, format, ap);
259    str[size-1] = 0;
260    return len;
261
262 #else
263
264    int len, buflen;
265    char *buf;
266    buflen = size > BIG_BUF ? size : BIG_BUF;
267    buf = get_memory(buflen);
268    len = vsprintf(buf, format, ap);
269    if (len >= buflen) {
270       Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
271    }
272    memcpy(str, buf, len);
273    str[len] = 0;                /* len excludes the null */
274    free_memory(buf);
275    return len;
276 #endif
277 }
278 #endif /* USE_BSNPRINTF */
279
280 #ifndef HAVE_LOCALTIME_R
281
282 struct tm *localtime_r(const time_t *timep, struct tm *tm)
283 {
284     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
285     struct tm *ltm,
286
287     P(mutex);
288     ltm = localtime(timep);
289     if (ltm) {
290        memcpy(tm, ltm, sizeof(struct tm));
291     }
292     V(mutex);
293     return ltm ? tm : NULL;
294 }
295 #endif /* HAVE_LOCALTIME_R */
296
297 #ifndef HAVE_READDIR_R
298 #ifndef HAVE_WIN32
299 #include <dirent.h>
300
301 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
302 {
303     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
304     struct dirent *ndir;
305     int stat;
306
307     P(mutex);
308     errno = 0;
309     ndir = readdir(dirp);
310     stat = errno;
311     if (ndir) {
312        memcpy(entry, ndir, sizeof(struct dirent));
313        strcpy(entry->d_name, ndir->d_name);
314        *result = entry;
315     } else {
316        *result = NULL;
317     }
318     V(mutex);
319     return stat;
320
321 }
322 #endif
323 #endif /* HAVE_READDIR_R */
324
325
326 int bstrerror(int errnum, char *buf, size_t bufsiz)
327 {
328     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
329     int stat = 0;
330     const char *msg;
331
332     P(mutex);
333
334     msg = strerror(errnum);
335     if (!msg) {
336        msg = _("Bad errno");
337        stat = -1;
338     }
339     bstrncpy(buf, msg, bufsiz);
340     V(mutex);
341     return stat;
342 }
343
344 /*
345  * These are mutex routines that do error checking
346  *  for deadlock and such.  Normally not turned on.
347  */
348 #ifdef DEBUG_MUTEX
349 void _p(char *file, int line, pthread_mutex_t *m)
350 {
351    int errstat;
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))) {
356          berrno be;
357          e_msg(file, line, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
358                be.strerror(errstat));
359       } else {
360          e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock resolved.\n"));
361       }
362
363    }
364 }
365
366 void _v(char *file, int line, pthread_mutex_t *m)
367 {
368    int errstat;
369
370    /* Note, this trylock *should* fail if the mutex is locked */
371    if ((errstat=pthread_mutex_trylock(m)) == 0) {
372       berrno be;
373       e_msg(file, line, M_ERROR, 0, _("Mutex unlock not locked. ERR=%s\n"),
374            be.strerror(errstat));
375     }
376     if ((errstat=pthread_mutex_unlock(m))) {
377        berrno be;
378        e_msg(file, line, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
379               be.strerror(errstat));
380     }
381 }
382
383 #else
384
385 void _p(pthread_mutex_t *m)
386 {
387    int errstat;
388    if ((errstat=pthread_mutex_lock(m))) {
389       berrno be;
390       e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
391             be.strerror(errstat));
392    }
393 }
394
395 void _v(pthread_mutex_t *m)
396 {
397    int errstat;
398    if ((errstat=pthread_mutex_unlock(m))) {
399       berrno be;
400       e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
401             be.strerror(errstat));
402    }
403 }
404
405 #endif /* DEBUG_MUTEX */
406
407 #ifdef DEBUG_MEMSET
408 /* These routines are not normally turned on */
409 #undef memset
410 void b_memset(const char *file, int line, void *mem, int val, size_t num)
411 {
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);
415    }
416    memset(mem, val, num);
417 }
418 #endif
419
420 #if !defined(HAVE_WIN32)
421 static int del_pid_file_ok = FALSE;
422 #endif
423
424 /*
425  * Create a standard "Unix" pid file.
426  */
427 void create_pid_file(char *dir, const char *progname, int port)
428 {
429 #if !defined(HAVE_WIN32)
430    int pidfd, len;
431    int oldpid;
432    char  pidbuf[20];
433    POOLMEM *fname = get_pool_memory(PM_FNAME);
434    struct stat statp;
435
436    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
437    if (stat(fname, &statp) == 0) {
438       /* File exists, see what we have */
439       *pidbuf = 0;
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));
444       }
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);
449       }
450       /* He is not alive, so take over file ownership */
451       unlink(fname);                  /* remove stale pid file */
452    }
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);
457       close(pidfd);
458       del_pid_file_ok = TRUE;         /* we created it so we can delete it */
459    } else {
460       Emsg2(M_ERROR_TERM, 0, _("Could not open pid file. %s ERR=%s\n"), fname, strerror(errno));
461    }
462    free_pool_memory(fname);
463 #endif
464 }
465
466
467 /*
468  * Delete the pid file if we created it
469  */
470 int delete_pid_file(char *dir, const char *progname, int port)
471 {
472 #if !defined(HAVE_WIN32)
473    POOLMEM *fname = get_pool_memory(PM_FNAME);
474
475    if (!del_pid_file_ok) {
476       free_pool_memory(fname);
477       return 0;
478    }
479    del_pid_file_ok = FALSE;
480    Mmsg(&fname, "%s/%s.%d.pid", dir, progname, port);
481    unlink(fname);
482    free_pool_memory(fname);
483 #endif
484    return 1;
485 }
486
487 struct s_state_hdr {
488    char id[14];
489    int32_t version;
490    uint64_t last_jobs_addr;
491    uint64_t reserved[20];
492 };
493
494 static struct s_state_hdr state_hdr = {
495    "Bacula State\n",
496    3,
497    0
498 };
499
500 /*
501  * Open and read the state file for the daemon
502  */
503 void read_state_file(char *dir, const char *progname, int port)
504 {
505    int sfd;
506    ssize_t stat;
507    bool ok = false;
508    POOLMEM *fname = get_pool_memory(PM_FNAME);
509    struct s_state_hdr hdr;
510    int hdr_size = sizeof(hdr);
511
512    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
513    /* If file exists, see what we have */
514 // Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
515    if ((sfd = open(fname, O_RDONLY|O_BINARY)) < 0) {
516       Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n",
517                     sfd, sizeof(hdr), strerror(errno));
518       goto bail_out;
519    }
520    if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
521       Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n",
522                     sfd, (int)stat, hdr_size, strerror(errno));
523       goto bail_out;
524    }
525    if (hdr.version != state_hdr.version) {
526       Dmsg2(010, "Bad hdr version. Wanted %d got %d\n",
527          state_hdr.version, hdr.version);
528       goto bail_out;
529    }
530    hdr.id[13] = 0;
531    if (strcmp(hdr.id, state_hdr.id) != 0) {
532       Dmsg0(000, "State file header id invalid.\n");
533       goto bail_out;
534    }
535 // Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
536    if (!read_last_jobs_list(sfd, hdr.last_jobs_addr)) {
537       goto bail_out;
538    }
539    ok = true;
540 bail_out:
541    if (sfd >= 0) {
542       close(sfd);
543    }
544    if (!ok) {
545       unlink(fname);
546     }
547    free_pool_memory(fname);
548 }
549
550 /*
551  * Write the state file
552  */
553 void write_state_file(char *dir, const char *progname, int port)
554 {
555    int sfd;
556    bool ok = false;
557    POOLMEM *fname = get_pool_memory(PM_FNAME);
558
559    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
560    /* Create new state file */
561    unlink(fname);
562    if ((sfd = open(fname, O_CREAT|O_WRONLY|O_BINARY, 0640)) < 0) {
563       berrno be;
564       Dmsg2(000, "Could not create state file. %s ERR=%s\n", fname, be.strerror());
565       Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, be.strerror());
566       goto bail_out;
567    }
568    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
569       berrno be;
570       Dmsg1(000, "Write hdr error: ERR=%s\n", be.strerror());
571       goto bail_out;
572    }
573 // Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
574    state_hdr.last_jobs_addr = sizeof(state_hdr);
575    state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);
576 // Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
577    if (lseek(sfd, 0, SEEK_SET) < 0) {
578       berrno be;
579       Dmsg1(000, "lseek error: ERR=%s\n", be.strerror());
580       goto bail_out;
581    }
582    if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
583       berrno be;
584       Pmsg1(000, _("Write final hdr error: ERR=%s\n"), be.strerror());
585       goto bail_out;
586    }
587    ok = true;
588 // Dmsg1(010, "rewrote header = %d\n", sizeof(state_hdr));
589 bail_out:
590    if (sfd >= 0) {
591       close(sfd);
592    }
593    if (!ok) {
594       unlink(fname);
595    }
596    free_pool_memory(fname);
597 }
598
599
600 /*
601  * Drop to privilege new userid and new gid if non-NULL
602  */
603 void drop(char *uname, char *gname)
604 {
605 #if   defined(HAVE_PWD_H) && defined(HAVE_GRP_H)
606    struct passwd *passw = NULL;
607    struct group *group = NULL;
608    gid_t gid;
609    uid_t uid;
610    char username[1000];         
611
612    Dmsg2(900, "uname=%s gname=%s\n", uname?uname:"NONE", gname?gname:"NONE");
613    if (!uname && !gname) {
614       return;                            /* Nothing to do */
615    }
616
617    if (uname) {
618       if ((passw = getpwnam(uname)) == NULL) {
619          berrno be;
620          Emsg2(M_ERROR_TERM, 0, _("Could not find userid=%s: ERR=%s\n"), uname,
621             be.strerror());
622       }
623    } else {
624       if ((passw = getpwuid(getuid())) == NULL) {
625          berrno be;
626          Emsg1(M_ERROR_TERM, 0, _("Could not find password entry. ERR=%s\n"),
627             be.strerror());
628       } else {
629          uname = passw->pw_name;
630       }
631    }
632    /* Any OS uname pointer may get overwritten, so save name, uid, and gid */
633    bstrncpy(username, uname, sizeof(username));
634    uid = passw->pw_uid;
635    gid = passw->pw_gid;
636    if (gname) {
637       if ((group = getgrnam(gname)) == NULL) {
638          berrno be;
639          Emsg2(M_ERROR_TERM, 0, _("Could not find group=%s: ERR=%s\n"), gname,
640             be.strerror());
641       }
642       gid = group->gr_gid;
643    }
644    if (initgroups(username, gid)) {
645       berrno be;
646       if (gname) {
647          Emsg3(M_ERROR_TERM, 0, _("Could not initgroups for group=%s, userid=%s: ERR=%s\n"),         
648             gname, username, be.strerror());
649       } else {
650          Emsg2(M_ERROR_TERM, 0, _("Could not initgroups for userid=%s: ERR=%s\n"),         
651             username, be.strerror());
652       }
653    }
654    if (gname) {
655       if (setgid(gid)) {
656          berrno be;
657          Emsg2(M_ERROR_TERM, 0, _("Could not set group=%s: ERR=%s\n"), gname,
658             be.strerror());
659       }
660    }
661    if (setuid(uid)) {
662       berrno be;
663       Emsg1(M_ERROR_TERM, 0, _("Could not set specified userid: %s\n"), username);
664    }
665 #endif
666 }
667
668
669 /* BSDI does not have this.  This is a *poor* simulation */
670 #ifndef HAVE_STRTOLL
671 long long int
672 strtoll(const char *ptr, char **endptr, int base)
673 {
674    return (long long int)strtod(ptr, endptr);
675 }
676 #endif
677
678 /*
679  * Bacula's implementation of fgets(). The difference is that it handles
680  *   being interrupted by a signal (e.g. a SIGCHLD).
681  */
682 #undef fgetc
683 char *bfgets(char *s, int size, FILE *fd)
684 {
685    char *p = s;
686    int ch;
687    *p = 0;
688    for (int i=0; i < size-1; i++) {
689       do {
690          errno = 0;
691          ch = fgetc(fd);
692       } while (ch == -1 && (errno == EINTR || errno == EAGAIN));
693       if (ch == -1) {
694          if (i == 0) {
695             return NULL;
696          } else {
697             return s;
698          }
699       }
700       *p++ = ch;
701       *p = 0;
702       if (ch == '\r') { /* Support for Mac/Windows file format */
703          ch = fgetc(fd);
704          if (ch == '\n') { /* Windows (\r\n) */
705             *p++ = ch;
706             *p = 0;
707          }
708          else { /* Mac (\r only) */
709             (void)ungetc(ch, fd); /* Push next character back to fd */
710          }
711          break;
712       }
713       if (ch == '\n') {
714          break;
715       }
716    }
717    return s;
718 }
719
720 /*
721  * Make a "unique" filename.  It is important that if
722  *   called again with the same "what" that the result
723  *   will be identical. This allows us to use the file
724  *   without saving its name, and re-generate the name
725  *   so that it can be deleted.
726  */
727 void make_unique_filename(POOLMEM **name, int Id, char *what)
728 {
729    Mmsg(name, "%s/%s.%s.%d.tmp", working_directory, my_name, what, Id);
730 }