2 * Create a file, and reset the modes
4 * Kern Sibbald, November MM
10 Copyright (C) 2000-2005 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as ammended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
28 #define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
36 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile);
37 static int path_already_seen(JCR *jcr, char *path, int pnl);
41 * Create the file, or the directory
43 * fname is the original filename
44 * ofile is the output filename (may be in a different directory)
46 * Returns: CF_SKIP if file should be skipped
48 * CF_EXTRACT file created and data to restore
49 * CF_CREATED file created no data to restore
51 * Note, we create the file here, except for special files,
52 * we do not set the attributes because we want to first
53 * write the file, then when the writing is done, set the
55 * So, we return with the file descriptor open for normal
59 int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
61 int new_mode, parent_mode, mode;
68 if (is_win32_stream(attr->data_stream)) {
69 set_win32_backup(bfd);
71 set_portable_backup(bfd);
74 new_mode = attr->statp.st_mode;
75 Dmsg2(300, "newmode=%x file=%s\n", new_mode, attr->ofname);
76 parent_mode = S_IWUSR | S_IXUSR | new_mode;
77 gid = attr->statp.st_gid;
78 uid = attr->statp.st_uid;
80 Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
81 if (lstat(attr->ofname, &mstatp) == 0) {
85 if (attr->statp.st_mtime <= mstatp.st_mtime) {
86 Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
92 if (attr->statp.st_mtime >= mstatp.st_mtime) {
93 Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
99 Jmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
106 switch (attr->type) {
107 case FT_LNKSAVED: /* Hard linked, file already saved */
112 case FT_REGE: /* empty file */
113 case FT_REG: /* regular file */
115 /* Get rid of old copy */
116 if (unlink(attr->ofname) == -1) {
118 Jmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
119 attr->ofname, be.strerror());
120 /* Continue despite error */
124 * Here we do some preliminary work for all the above
125 * types to create the path to the file if it does
126 * not already exist. Below, we will split to
127 * do the file type specific work
129 pnl = separate_path_and_file(jcr, attr->fname, attr->ofname);
135 * If path length is <= 0 we are making a file in the root
136 * directory. Assume that the directory already exists.
140 savechr = attr->ofname[pnl];
141 attr->ofname[pnl] = 0; /* terminate path */
143 if (!path_already_seen(jcr, attr->ofname, pnl)) {
144 Dmsg1(50, "Make path %s\n", attr->ofname);
146 * If we need to make the directory, ensure that it is with
147 * execute bit set (i.e. parent_mode), and preserve what already
148 * exists. Normally, this should do nothing.
150 if (make_path(jcr, attr->ofname, parent_mode, parent_mode, uid, gid, 1, NULL) != 0) {
151 Dmsg1(10, "Could not make path. %s\n", attr->ofname);
152 attr->ofname[pnl] = savechr; /* restore full name */
156 attr->ofname[pnl] = savechr; /* restore full name */
159 /* Now we do the specific work for each file type */
163 Dmsg1(100, "Create file %s\n", attr->ofname);
164 mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /* O_NOFOLLOW; */
165 if (IS_CTG(attr->statp.st_mode)) {
166 mode |= O_CTG; /* set contiguous bit if needed */
168 Dmsg1(50, "Create file: %s\n", attr->ofname);
170 Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
173 if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
175 be.set_errno(bfd->berrno);
176 Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
177 attr->ofname, be.strerror());
181 #ifndef HAVE_WIN32 // none of these exists on MS Windows
182 case FT_RAW: /* Bacula raw device e.g. /dev/sda1 */
183 case FT_FIFO: /* Bacula fifo to save data */
185 if (S_ISFIFO(attr->statp.st_mode)) {
186 Dmsg1(200, "Restore fifo: %s\n", attr->ofname);
187 if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
189 Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
190 attr->ofname, be.strerror());
194 Dmsg1(200, "Restore node: %s\n", attr->ofname);
195 if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
197 Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
198 attr->ofname, be.strerror());
202 if (attr->type == FT_RAW || attr->type == FT_FIFO) {
204 Dmsg1(200, "FT_RAW|FT_FIFO %s\n", attr->ofname);
205 mode = O_WRONLY | O_BINARY;
206 /* Timeout open() in 60 seconds */
207 if (attr->type == FT_FIFO) {
208 tid = start_thread_timer(pthread_self(), 60);
213 Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
215 if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
217 be.set_errno(bfd->berrno);
218 Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
219 attr->ofname, be.strerror());
220 stop_thread_timer(tid);
223 stop_thread_timer(tid);
226 Dmsg1(200, "FT_SPEC %s\n", attr->ofname);
230 Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
231 if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
233 Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
234 attr->ofname, attr->olname, be.strerror());
239 case FT_LNKSAVED: /* Hard linked, file already saved */
240 Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
241 if (link(attr->olname, attr->ofname) != 0) {
243 Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
244 attr->ofname, attr->olname, be.strerror());
249 } /* End inner switch */
253 Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
254 if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
258 * If we are using the Win32 Backup API, we open the
259 * directory so that the security info will be read
262 if (!is_portable_backup(bfd)) {
264 Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
266 if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
268 be.set_errno(bfd->berrno);
270 /* Check for trying to create a drive, if so, skip */
271 if (attr->ofname[1] == ':' && attr->ofname[2] == '/' && attr->ofname[3] == 0) {
275 Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
276 attr->ofname, be.strerror());
284 /* The following should not occur */
294 Jmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
297 Jmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
304 * Returns: > 0 index into path where last path char is.
306 * -1 filename is zero length
308 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
313 /* Separate pathname and filename */
314 for (p=f=ofile; *p; p++) {
316 f = p; /* possible filename */
325 /* The filename length must not be zero here because we
326 * are dealing with a file (i.e. FT_REGE or FT_REG).
328 Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
336 * Primitive caching of path to prevent recreating a pathname
337 * each time as long as we remain in the same directory.
339 static int path_already_seen(JCR *jcr, char *path, int pnl)
341 if (!jcr->cached_path) {
342 jcr->cached_path = get_pool_memory(PM_FNAME);
344 if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
347 pm_strcpy(&jcr->cached_path, path);
348 jcr->cached_pnl = pnl;