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