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