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