]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/create_file.c
Detect mount/junction points and ignore junctions in Windows
[bacula/bacula] / bacula / src / findlib / create_file.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2011 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 three of the GNU Affero 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 Affero 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  *  Create a file, and reset the modes
30  *
31  *    Kern Sibbald, November MM
32  *
33  *   Version $Id$
34  *
35  */
36
37 #include "bacula.h"
38 #include "find.h"
39
40 #ifndef S_IRWXUGO
41 #define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
42 #endif
43
44 #ifndef IS_CTG
45 #define IS_CTG(x) 0
46 #define O_CTG 0
47 #endif
48
49 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile);
50 static int path_already_seen(JCR *jcr, char *path, int pnl);
51
52
53 /*
54  * Create the file, or the directory
55  *
56  *  fname is the original filename
57  *  ofile is the output filename (may be in a different directory)
58  *
59  * Returns:  CF_SKIP     if file should be skipped
60  *           CF_ERROR    on error
61  *           CF_EXTRACT  file created and data to restore
62  *           CF_CREATED  file created no data to restore
63  *
64  *   Note, we create the file here, except for special files,
65  *     we do not set the attributes because we want to first
66  *     write the file, then when the writing is done, set the
67  *     attributes.
68  *   So, we return with the file descriptor open for normal
69  *     files.
70  *
71  */
72 int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
73 {
74    mode_t new_mode, parent_mode;
75    int flags;
76    uid_t uid;
77    gid_t gid;
78    int pnl;
79    bool exists = false;
80    struct stat mstatp;
81
82    bfd->reparse_point = false;
83    if (is_win32_stream(attr->data_stream)) {
84       set_win32_backup(bfd);
85    } else {
86       set_portable_backup(bfd);
87    }
88
89    new_mode = attr->statp.st_mode;
90    Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname);
91    parent_mode = S_IWUSR | S_IXUSR | new_mode;
92    gid = attr->statp.st_gid;
93    uid = attr->statp.st_uid;
94
95 #ifdef HAVE_WIN32
96    if (!bfd->use_backup_api) {
97       // eliminate invalid windows filename characters from foreign filenames
98       char *ch = (char *)attr->ofname;
99       if (ch[0] != 0 && ch[1] != 0) {
100          ch += 2;
101          while (*ch) {
102             switch (*ch) {
103             case ':':
104             case '<':
105             case '>':
106             case '*':
107             case '?':
108             case '|':
109                *ch = '_';
110                 break;
111             }
112             ch++;
113          }
114       }
115    }
116 #endif
117    Dmsg3(200, "Create %s Replace=%c FT=%d\n", attr->ofname, (char)replace, attr->type);
118    if (lstat(attr->ofname, &mstatp) == 0) {
119       exists = true;
120       /*
121        * For directories we do not apply the replace options, because
122        * we must always create directories that do not exist, and thus
123        * when the directory end record comes, the directory exists.  So
124        * we always apply the FT_DIREND record for directories.
125        */
126       if (attr->type != FT_DIREND) {
127          switch (replace) {
128          case REPLACE_IFNEWER:
129             if (attr->statp.st_mtime <= mstatp.st_mtime) {
130                Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
131                return CF_SKIP;
132             }
133             break;
134
135          case REPLACE_IFOLDER:
136             if (attr->statp.st_mtime >= mstatp.st_mtime) {
137                Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
138                return CF_SKIP;
139             }
140             break;
141
142          case REPLACE_NEVER:
143             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
144             return CF_SKIP;
145
146          case REPLACE_ALWAYS:
147             break;
148          }
149       }
150    }
151    switch (attr->type) {
152    case FT_RAW:                       /* raw device to be written */
153    case FT_FIFO:                      /* FIFO to be written to */
154    case FT_LNKSAVED:                  /* Hard linked, file already saved */
155    case FT_LNK:
156    case FT_SPEC:                      /* fifo, ... to be backed up */
157    case FT_REGE:                      /* empty file */
158    case FT_REG:                       /* regular file */
159       /* 
160        * Note, we do not delete FT_RAW because these are device files
161        *  or FIFOs that should already exist. If we blow it away,
162        *  we may blow away a FIFO that is being used to read the
163        *  restore data, or we may blow away a partition definition.
164        */
165       if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) {
166          /* Get rid of old copy */
167          Dmsg1(400, "unlink %s\n", attr->ofname);
168          if (unlink(attr->ofname) == -1) {
169             berrno be;
170             Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
171                attr->ofname, be.bstrerror());
172             /* Continue despite error */
173          }
174       }
175       /*
176        * Here we do some preliminary work for all the above
177        *   types to create the path to the file if it does
178        *   not already exist.  Below, we will split to
179        *   do the file type specific work
180        */
181       pnl = separate_path_and_file(jcr, attr->fname, attr->ofname);
182       if (pnl < 0) {
183          return CF_ERROR;
184       }
185
186       /*
187        * If path length is <= 0 we are making a file in the root
188        *  directory. Assume that the directory already exists.
189        */
190       if (pnl > 0) {
191          char savechr;
192          savechr = attr->ofname[pnl];
193          attr->ofname[pnl] = 0;                 /* terminate path */
194
195          if (!path_already_seen(jcr, attr->ofname, pnl)) {
196             /*
197              * If we need to make the directory, ensure that it is with
198              * execute bit set (i.e. parent_mode), and preserve what already
199              * exists. Normally, this should do nothing.
200              */
201             Dmsg1(400, "makepath %s\n", attr->ofname);
202             if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
203                Dmsg1(10, "Could not make path. %s\n", attr->ofname);
204                attr->ofname[pnl] = savechr;     /* restore full name */
205                return CF_ERROR;
206             }
207          }
208          attr->ofname[pnl] = savechr;           /* restore full name */
209       }
210
211       /* Now we do the specific work for each file type */
212       switch(attr->type) {
213       case FT_REGE:
214       case FT_REG:
215          Dmsg1(100, "Create=%s\n", attr->ofname);
216          flags =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
217          if (IS_CTG(attr->statp.st_mode)) {
218             flags |= O_CTG;              /* set contiguous bit if needed */
219          }
220          if (is_bopen(bfd)) {
221             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
222             bclose(bfd);
223          }
224       
225
226          if ((bopen(bfd, attr->ofname, flags, S_IRUSR | S_IWUSR)) < 0) {
227             berrno be;
228             be.set_errno(bfd->berrno);
229             Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
230                   attr->ofname, be.bstrerror());
231             Dmsg2(100,"Could not create %s: ERR=%s\n", attr->ofname, be.bstrerror());
232             return CF_ERROR;
233          }
234          return CF_EXTRACT;
235
236 #ifndef HAVE_WIN32  // none of these exist in MS Windows
237       case FT_RAW:                    /* Bacula raw device e.g. /dev/sda1 */
238       case FT_FIFO:                   /* Bacula fifo to save data */
239       case FT_SPEC:
240          if (S_ISFIFO(attr->statp.st_mode)) {
241             Dmsg1(400, "Restore fifo: %s\n", attr->ofname);
242             if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
243                berrno be;
244                Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
245                      attr->ofname, be.bstrerror());
246                return CF_ERROR;
247             }
248          } else if (S_ISSOCK(attr->statp.st_mode)) {
249              Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
250 #ifdef S_IFDOOR     // Solaris high speed RPC mechanism
251          } else if (S_ISDOOR(attr->statp.st_mode)) {
252              Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname);
253 #endif
254 #ifdef S_IFPORT     // Solaris event port for handling AIO
255          } else if (S_ISPORT(attr->statp.st_mode)) {
256              Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname);
257 #endif
258          } else {
259             Dmsg1(400, "Restore node: %s\n", attr->ofname);
260             if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
261                berrno be;
262                Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
263                      attr->ofname, be.bstrerror());
264                return CF_ERROR;
265             }
266          }
267          /*
268           * Here we are going to attempt to restore to a FIFO, which
269           *   means that the FIFO must already exist, AND there must
270           *   be some process already attempting to read from the
271           *   FIFO, so we open it write-only. 
272           */
273          if (attr->type == FT_RAW || attr->type == FT_FIFO) {
274             btimer_t *tid;
275             Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname);
276             flags =  O_WRONLY | O_BINARY;
277             /* Timeout open() in 60 seconds */
278             if (attr->type == FT_FIFO) {
279                Dmsg0(400, "Set FIFO timer\n");
280                tid = start_thread_timer(jcr, pthread_self(), 60);
281             } else {
282                tid = NULL;
283             }
284             if (is_bopen(bfd)) {
285                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
286             }
287             Dmsg2(400, "open %s flags=0x%x\n", attr->ofname, flags);
288             if ((bopen(bfd, attr->ofname, flags, 0)) < 0) {
289                berrno be;
290                be.set_errno(bfd->berrno);
291                Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
292                      attr->ofname, be.bstrerror());
293                Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.bstrerror());
294                stop_thread_timer(tid);
295                return CF_ERROR;
296             }
297             stop_thread_timer(tid);
298             return CF_EXTRACT;
299          }
300          Dmsg1(400, "FT_SPEC %s\n", attr->ofname);
301          return CF_CREATED;
302
303       case FT_LNK:
304          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
305          if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
306             berrno be;
307             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
308                   attr->ofname, attr->olname, be.bstrerror());
309             return CF_ERROR;
310          }
311          return CF_CREATED;
312
313       case FT_LNKSAVED:                  /* Hard linked, file already saved */
314          Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
315          if (link(attr->olname, attr->ofname) != 0) {
316             berrno be;
317 #ifdef HAVE_CHFLAGS
318             struct stat s;
319
320         /*
321             * If using BSD user flags, maybe has a file flag
322             * preventing this. So attempt to disable, retry link,
323             * and reset flags.
324             * Note that BSD securelevel may prevent disabling flag.
325         */
326
327             if (stat(attr->olname, &s) == 0 && s.st_flags != 0) {
328                if (chflags(attr->olname, 0) == 0) {
329                   if (link(attr->olname, attr->ofname) != 0) {
330                      /* restore original file flags even when linking failed */
331                      if (chflags(attr->olname, s.st_flags) < 0) {
332                         Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
333                               attr->olname, be.bstrerror());
334                      }
335 #endif /* HAVE_CHFLAGS */
336             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
337                   attr->ofname, attr->olname, be.bstrerror());
338             Dmsg3(200, "Could not hard link %s -> %s: ERR=%s\n",
339                   attr->ofname, attr->olname, be.bstrerror());
340             return CF_ERROR;
341 #ifdef HAVE_CHFLAGS
342                   }
343                   /* finally restore original file flags */
344                   if (chflags(attr->olname, s.st_flags) < 0) {
345                      Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
346                             attr->olname, be.bstrerror());
347                   }
348                } else {
349                  Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"),
350                        attr->olname, be.bstrerror());
351                }
352             } else {
353               Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
354                     attr->ofname, attr->olname, be.bstrerror());
355               return CF_ERROR;
356             }
357 #endif /* HAVE_CHFLAGS */
358
359          }
360          return CF_CREATED;
361 #endif
362       } /* End inner switch */
363
364    case FT_REPARSE:
365    case FT_JUNCTION:
366       bfd->reparse_point = true;
367       /* Fall through wanted */
368    case FT_DIRBEGIN:
369    case FT_DIREND:
370       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
371       if (!makepath(attr, attr->ofname, new_mode, parent_mode, uid, gid, 0)) {
372          return CF_ERROR;
373       }
374       /*
375        * If we are using the Win32 Backup API, we open the
376        *   directory so that the security info will be read
377        *   and saved.
378        */
379       if (!is_portable_backup(bfd)) {
380          if (is_bopen(bfd)) {
381             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
382          }
383          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
384             berrno be;
385             be.set_errno(bfd->berrno);
386 #ifdef HAVE_WIN32
387             /* Check for trying to create a drive, if so, skip */
388             if (attr->ofname[1] == ':' && 
389                 IsPathSeparator(attr->ofname[2]) && 
390                 attr->ofname[3] == '\0') {
391                return CF_SKIP;
392             }
393 #endif
394             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
395                   attr->ofname, be.bstrerror());
396             return CF_ERROR;
397          }
398          return CF_EXTRACT;
399       } else {
400          return CF_CREATED;
401       }
402
403    case FT_DELETED:
404       Qmsg2(jcr, M_INFO, 0, _("Original file %s have been deleted: type=%d\n"), attr->fname, attr->type);
405       break;
406    /* The following should not occur */
407    case FT_NOACCESS:
408    case FT_NOFOLLOW:
409    case FT_NOSTAT:
410    case FT_DIRNOCHG:
411    case FT_NOCHG:
412    case FT_ISARCH:
413    case FT_NORECURSE:
414    case FT_NOFSCHG:
415    case FT_NOOPEN:
416       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
417       break;
418    default:
419       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
420       break;
421    }
422    return CF_ERROR;
423 }
424
425 /*
426  *  Returns: > 0 index into path where last path char is.
427  *           0  no path
428  *           -1 filename is zero length
429  */
430 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
431 {
432    char *f, *p, *q;
433    int fnl, pnl;
434
435    /* Separate pathname and filename */
436    for (q=p=f=ofile; *p; p++) {
437 #ifdef HAVE_WIN32
438       if (IsPathSeparator(*p)) {
439          f = q;
440          if (IsPathSeparator(p[1])) {
441             p++;
442          }
443       }
444       *q++ = *p;                   /* copy data */
445 #else
446       if (IsPathSeparator(*p)) {
447          f = q;                    /* possible filename */
448       }
449       q++;
450 #endif
451    }
452
453    if (IsPathSeparator(*f)) {
454       f++;
455    }
456    *q = 0;                         /* terminate string */
457
458    fnl = q - f;
459    if (fnl == 0) {
460       /* The filename length must not be zero here because we
461        *  are dealing with a file (i.e. FT_REGE or FT_REG).
462        */
463       Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
464       return -1;
465    }
466    pnl = f - ofile - 1;
467    return pnl;
468 }
469
470 /*
471  * Primitive caching of path to prevent recreating a pathname
472  *   each time as long as we remain in the same directory.
473  */
474 static int path_already_seen(JCR *jcr, char *path, int pnl)
475 {
476    if (!jcr->cached_path) {
477       jcr->cached_path = get_pool_memory(PM_FNAME);
478    }
479    if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
480       return 1;
481    }
482    pm_strcpy(jcr->cached_path, path);
483    jcr->cached_pnl = pnl;
484    return 0;
485 }