2 * Create a file, and reset the modes
4 * Kern Sibbald, November MM
10 Copyright (C) 2000-2006 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 amended 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 Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, 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;
81 if (!bfd->use_backup_api) {
82 // eliminate invalid windows filename characters from foreign filenames
83 char *ch = (char *)attr->ofname;
84 if (ch[0] != 0 && ch[1] != 0) {
103 Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
104 if (lstat(attr->ofname, &mstatp) == 0) {
107 case REPLACE_IFNEWER:
108 if (attr->statp.st_mtime <= mstatp.st_mtime) {
109 Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
114 case REPLACE_IFOLDER:
115 if (attr->statp.st_mtime >= mstatp.st_mtime) {
116 Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
122 Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
129 switch (attr->type) {
130 case FT_RAW: /* raw device to be written */
131 case FT_FIFO: /* FIFO to be written to */
132 case FT_LNKSAVED: /* Hard linked, file already saved */
134 case FT_SPEC: /* fifo, ... to be backed up */
135 case FT_REGE: /* empty file */
136 case FT_REG: /* regular file */
138 * Note, we do not delete FT_RAW because these are device files
139 * or FIFOs that should already exist. If we blow it away,
140 * we may blow away a FIFO that is being used to read the
141 * restore data, or we may blow away a partition definition.
143 if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) {
144 /* Get rid of old copy */
145 if (unlink(attr->ofname) == -1) {
147 Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
148 attr->ofname, be.strerror());
149 /* Continue despite error */
153 * Here we do some preliminary work for all the above
154 * types to create the path to the file if it does
155 * not already exist. Below, we will split to
156 * do the file type specific work
158 pnl = separate_path_and_file(jcr, attr->fname, attr->ofname);
164 * If path length is <= 0 we are making a file in the root
165 * directory. Assume that the directory already exists.
169 savechr = attr->ofname[pnl];
170 attr->ofname[pnl] = 0; /* terminate path */
172 if (!path_already_seen(jcr, attr->ofname, pnl)) {
173 Dmsg1(100, "Make path %s\n", attr->ofname);
175 * If we need to make the directory, ensure that it is with
176 * execute bit set (i.e. parent_mode), and preserve what already
177 * exists. Normally, this should do nothing.
179 if (make_path(jcr, attr->ofname, parent_mode, parent_mode, uid, gid, 1, NULL) != 0) {
180 Dmsg1(10, "Could not make path. %s\n", attr->ofname);
181 attr->ofname[pnl] = savechr; /* restore full name */
185 attr->ofname[pnl] = savechr; /* restore full name */
188 /* Now we do the specific work for each file type */
192 Dmsg1(100, "Create file %s\n", attr->ofname);
193 mode = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /* O_NOFOLLOW; */
194 if (IS_CTG(attr->statp.st_mode)) {
195 mode |= O_CTG; /* set contiguous bit if needed */
197 Dmsg1(50, "Create file: %s\n", attr->ofname);
199 Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
204 if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
206 be.set_errno(bfd->berrno);
207 Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
208 attr->ofname, be.strerror());
213 #ifndef HAVE_WIN32 // none of these exists on MS Windows
214 case FT_RAW: /* Bacula raw device e.g. /dev/sda1 */
215 case FT_FIFO: /* Bacula fifo to save data */
217 if (S_ISFIFO(attr->statp.st_mode)) {
218 Dmsg1(200, "Restore fifo: %s\n", attr->ofname);
219 if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
221 Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
222 attr->ofname, be.strerror());
225 } else if(S_ISSOCK(attr->statp.st_mode)) {
226 Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
228 Dmsg1(200, "Restore node: %s\n", attr->ofname);
229 if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
231 Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
232 attr->ofname, be.strerror());
236 if (attr->type == FT_RAW || attr->type == FT_FIFO) {
238 Dmsg1(200, "FT_RAW|FT_FIFO %s\n", attr->ofname);
239 mode = O_WRONLY | O_BINARY;
240 /* Timeout open() in 60 seconds */
241 if (attr->type == FT_FIFO) {
242 Dmsg0(200, "Set FIFO timer\n");
243 tid = start_thread_timer(pthread_self(), 60);
248 Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
250 Dmsg2(200, "open %s mode=0x%x\n", attr->ofname, mode);
251 if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
253 be.set_errno(bfd->berrno);
254 Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
255 attr->ofname, be.strerror());
256 stop_thread_timer(tid);
259 stop_thread_timer(tid);
262 Dmsg1(200, "FT_SPEC %s\n", attr->ofname);
266 Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
267 if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
269 Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
270 attr->ofname, attr->olname, be.strerror());
275 case FT_LNKSAVED: /* Hard linked, file already saved */
276 Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
277 if (link(attr->olname, attr->ofname) != 0) {
279 Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
280 attr->ofname, attr->olname, be.strerror());
285 } /* End inner switch */
289 Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
290 if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
294 * If we are using the Win32 Backup API, we open the
295 * directory so that the security info will be read
298 if (!is_portable_backup(bfd)) {
300 Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
302 if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
304 be.set_errno(bfd->berrno);
306 /* Check for trying to create a drive, if so, skip */
307 if (attr->ofname[1] == ':' &&
308 IsPathSeparator(attr->ofname[2]) &&
309 attr->ofname[3] == '\0') {
313 Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
314 attr->ofname, be.strerror());
322 /* The following should not occur */
332 Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
335 Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
342 * Returns: > 0 index into path where last path char is.
344 * -1 filename is zero length
346 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
351 /* Separate pathname and filename */
352 for (q=p=f=ofile; *p; p++) {
354 if (IsPathSeparator(*p)) {
356 if (IsPathSeparator(p[1])) {
360 *q++ = *p; /* copy data */
362 if (IsPathSeparator(*p)) {
363 f = q; /* possible filename */
369 if (IsPathSeparator(*f)) {
372 *q = 0; /* terminate string */
376 /* The filename length must not be zero here because we
377 * are dealing with a file (i.e. FT_REGE or FT_REG).
379 Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
387 * Primitive caching of path to prevent recreating a pathname
388 * each time as long as we remain in the same directory.
390 static int path_already_seen(JCR *jcr, char *path, int pnl)
392 if (!jcr->cached_path) {
393 jcr->cached_path = get_pool_memory(PM_FNAME);
395 if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
398 pm_strcpy(jcr->cached_path, path);
399 jcr->cached_pnl = pnl;