]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/savecwd.c
ebl Fix #1173 where prune_volume() returns a volume from the scratch.
[bacula/bacula] / bacula / src / findlib / savecwd.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-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 /*
30  *  Kern Sibbald, August MMVII
31  *
32  *  Version $Id$
33  */
34
35 #include "bacula.h"
36 #include "savecwd.h"
37
38 /* 
39  * Attempt to save the current working directory by various means so that
40  *  we can optimize code by doing a cwd and then restore the cwd.
41  */
42
43 #ifdef HAVE_FCHDIR
44 static bool fchdir_failed = false;          /* set if we get a fchdir failure */
45 #else
46 static bool fchdir_failed = true;           /* set if we get a fchdir failure */
47 #endif
48
49 /* 
50  * Save current working directory.
51  * Returns: true if OK
52  *          false if failed
53  */
54 bool saveCWD::save(JCR *jcr)
55 {
56    release();                                /* clean up */
57    if (!fchdir_failed) {
58       m_fd = open(".", O_RDONLY);
59       if (m_fd < 0) {
60          berrno be;
61          Jmsg1(jcr, M_ERROR, 0, _("Cannot open current directory: ERR=%s\n"), be.bstrerror());
62          m_saved = false;
63          return false;
64       }
65    }
66
67    if (fchdir_failed) {
68       POOLMEM *buf = get_memory(5000);
69       m_cwd = (POOLMEM *)getcwd(buf, sizeof_pool_memory(buf));
70       if (m_cwd == NULL) {
71          berrno be;
72          Jmsg1(jcr, M_ERROR, 0, _("Cannot get current directory: ERR=%s\n"), be.bstrerror());
73          free_pool_memory(buf);
74          m_saved = false;
75          return false;
76       }
77    }
78    m_saved = true;
79    return true;
80 }
81
82 /*
83  * Restore previous working directory.
84  * Returns: true if OK
85  *          false if failed
86  */
87 bool saveCWD::restore(JCR *jcr)
88 {
89    if (!m_saved) {
90       return true;
91    }
92    m_saved = false;
93    if (m_fd >= 0) {
94       if (fchdir(m_fd) != 0) {
95          berrno be;
96          Jmsg1(jcr, M_ERROR, 0, _("Cannot reset current directory: ERR=%s\n"), be.bstrerror());
97          close(m_fd);
98          m_fd = -1;
99          fchdir_failed = true;
100          chdir("/");                  /* punt */
101          return false;
102       }
103       return true;
104    }
105    if (chdir(m_cwd) < 0) {
106       berrno be;
107       Jmsg1(jcr, M_ERROR, 0, _("Cannot reset current directory: ERR=%s\n"), be.bstrerror());
108       chdir("/");
109       free_pool_memory(m_cwd);
110       m_cwd = NULL;
111       return false;
112    }
113    return true;
114 }       
115
116 void saveCWD::release()
117 {
118    if (!m_saved) {
119       return;
120    }
121    m_saved = false;
122    if (m_fd >= 0) {
123       close(m_fd);
124       m_fd = -1;
125    }
126    if (m_cwd) {
127       free_pool_memory(m_cwd);
128       m_cwd = NULL;
129    }
130 }