]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/create_file.c
Fix bug # 746 - Windows FD crashes when job canceled
[bacula/bacula] / bacula / src / findlib / create_file.c
1 /*
2  *  Create a file, and reset the modes
3  *
4  *    Kern Sibbald, November MM
5  *
6  *   Version $Id$
7  *
8  */
9 /*
10    Bacula® - The Network Backup Solution
11
12    Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
13
14    The main author of Bacula is Kern Sibbald, with contributions from
15    many others, a complete list can be found in the file AUTHORS.
16    This program is Free Software; you can redistribute it and/or
17    modify it under the terms of version two of the GNU General Public
18    License as published by the Free Software Foundation plus additions
19    that are listed in the file LICENSE.
20
21    This program is distributed in the hope that it will be useful, but
22    WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24    General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program; if not, write to the Free Software
28    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29    02110-1301, USA.
30
31    Bacula® is a registered trademark of John Walker.
32    The licensor of Bacula is the Free Software Foundation Europe
33    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34    Switzerland, email:ftf@fsfeurope.org.
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    int new_mode, parent_mode, mode;
75    uid_t uid;
76    gid_t gid;
77    int pnl;
78    bool exists = false;
79    struct stat mstatp;
80
81    if (is_win32_stream(attr->data_stream)) {
82       set_win32_backup(bfd);
83    } else {
84       set_portable_backup(bfd);
85    }
86
87    new_mode = attr->statp.st_mode;
88    Dmsg3(200, "type=%d newmode=%x file=%s\n", attr->type, new_mode, attr->ofname);
89    parent_mode = S_IWUSR | S_IXUSR | new_mode;
90    gid = attr->statp.st_gid;
91    uid = attr->statp.st_uid;
92
93 #ifdef HAVE_WIN32
94    if (!bfd->use_backup_api) {
95       // eliminate invalid windows filename characters from foreign filenames
96       char *ch = (char *)attr->ofname;
97       if (ch[0] != 0 && ch[1] != 0) {
98          ch+=2;
99          while (*ch) {
100             switch (*ch) {
101             case ':':
102             case '<':
103             case '>':
104             case '*':
105             case '?':
106             case '|':
107                *ch = '_';
108                 break;
109             }
110             ch++;
111          }
112       }
113    }
114 #endif
115
116    Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
117    if (lstat(attr->ofname, &mstatp) == 0) {
118       exists = true;
119       switch (replace) {
120       case REPLACE_IFNEWER:
121          if (attr->statp.st_mtime <= mstatp.st_mtime) {
122             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
123             return CF_SKIP;
124          }
125          break;
126
127       case REPLACE_IFOLDER:
128          if (attr->statp.st_mtime >= mstatp.st_mtime) {
129             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
130             return CF_SKIP;
131          }
132          break;
133
134       case REPLACE_NEVER:
135          Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
136          return CF_SKIP;
137
138       case REPLACE_ALWAYS:
139          break;
140       }
141    }
142    switch (attr->type) {
143    case FT_RAW:                       /* raw device to be written */
144    case FT_FIFO:                      /* FIFO to be written to */
145    case FT_LNKSAVED:                  /* Hard linked, file already saved */
146    case FT_LNK:
147    case FT_SPEC:                      /* fifo, ... to be backed up */
148    case FT_REGE:                      /* empty file */
149    case FT_REG:                       /* regular file */
150       /* 
151        * Note, we do not delete FT_RAW because these are device files
152        *  or FIFOs that should already exist. If we blow it away,
153        *  we may blow away a FIFO that is being used to read the
154        *  restore data, or we may blow away a partition definition.
155        */
156       if (exists && attr->type != FT_RAW && attr->type != FT_FIFO) {
157          /* Get rid of old copy */
158          if (unlink(attr->ofname) == -1) {
159             berrno be;
160             Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
161                attr->ofname, be.strerror());
162             /* Continue despite error */
163          }
164       }
165       /*
166        * Here we do some preliminary work for all the above
167        *   types to create the path to the file if it does
168        *   not already exist.  Below, we will split to
169        *   do the file type specific work
170        */
171       pnl = separate_path_and_file(jcr, attr->fname, attr->ofname);
172       if (pnl < 0) {
173          return CF_ERROR;
174       }
175
176       /*
177        * If path length is <= 0 we are making a file in the root
178        *  directory. Assume that the directory already exists.
179        */
180       if (pnl > 0) {
181          char savechr;
182          savechr = attr->ofname[pnl];
183          attr->ofname[pnl] = 0;                 /* terminate path */
184
185          if (!path_already_seen(jcr, attr->ofname, pnl)) {
186             Dmsg1(100, "Make path %s\n", attr->ofname);
187             /*
188              * If we need to make the directory, ensure that it is with
189              * execute bit set (i.e. parent_mode), and preserve what already
190              * exists. Normally, this should do nothing.
191              */
192             if (make_path(jcr, attr->ofname, parent_mode, parent_mode, uid, gid, 1, NULL) != 0) {
193                Dmsg1(10, "Could not make path. %s\n", attr->ofname);
194                attr->ofname[pnl] = savechr;     /* restore full name */
195                return CF_ERROR;
196             }
197          }
198          attr->ofname[pnl] = savechr;           /* restore full name */
199       }
200
201       /* Now we do the specific work for each file type */
202       switch(attr->type) {
203       case FT_REGE:
204       case FT_REG:
205          Dmsg1(100, "Create file %s\n", attr->ofname);
206          mode =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
207          if (IS_CTG(attr->statp.st_mode)) {
208             mode |= O_CTG;               /* set contiguous bit if needed */
209          }
210          Dmsg1(50, "Create file: %s\n", attr->ofname);
211          if (is_bopen(bfd)) {
212             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
213             bclose(bfd);
214          }
215       
216
217          if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
218             berrno be;
219             be.set_errno(bfd->berrno);
220             Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
221                   attr->ofname, be.strerror());
222             return CF_ERROR;
223          }
224          return CF_EXTRACT;
225
226 #ifndef HAVE_WIN32  // none of these exists on MS Windows
227       case FT_RAW:                    /* Bacula raw device e.g. /dev/sda1 */
228       case FT_FIFO:                   /* Bacula fifo to save data */
229       case FT_SPEC:
230          if (S_ISFIFO(attr->statp.st_mode)) {
231             Dmsg1(200, "Restore fifo: %s\n", attr->ofname);
232             if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
233                berrno be;
234                Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
235                      attr->ofname, be.strerror());
236                return CF_ERROR;
237             }
238          } else if(S_ISSOCK(attr->statp.st_mode)) {
239              Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
240          } else {
241             Dmsg1(200, "Restore node: %s\n", attr->ofname);
242             if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
243                berrno be;
244                Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
245                      attr->ofname, be.strerror());
246                return CF_ERROR;
247             }
248          }
249          if (attr->type == FT_RAW || attr->type == FT_FIFO) {
250             btimer_t *tid;
251             Dmsg1(200, "FT_RAW|FT_FIFO %s\n", attr->ofname);
252             mode =  O_WRONLY | O_BINARY;
253             /* Timeout open() in 60 seconds */
254             if (attr->type == FT_FIFO) {
255                Dmsg0(200, "Set FIFO timer\n");
256                tid = start_thread_timer(pthread_self(), 60);
257             } else {
258                tid = NULL;
259             }
260             if (is_bopen(bfd)) {
261                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
262             }
263             Dmsg2(200, "open %s mode=0x%x\n", attr->ofname, mode);
264             if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
265                berrno be;
266                be.set_errno(bfd->berrno);
267                Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
268                      attr->ofname, be.strerror());
269                stop_thread_timer(tid);
270                return CF_ERROR;
271             }
272             stop_thread_timer(tid);
273             return CF_EXTRACT;
274          }
275          Dmsg1(200, "FT_SPEC %s\n", attr->ofname);
276          return CF_CREATED;
277
278       case FT_LNK:
279          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
280          if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
281             berrno be;
282             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
283                   attr->ofname, attr->olname, be.strerror());
284             return CF_ERROR;
285          }
286          return CF_CREATED;
287
288       case FT_LNKSAVED:                  /* Hard linked, file already saved */
289          Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
290          if (link(attr->olname, attr->ofname) != 0) {
291             berrno be;
292 #ifdef HAVE_CHFLAGS
293             struct stat s;
294
295         /*
296             * If using BSD user flags, maybe has a file flag
297             * preventing this. So attempt to disable, retry link,
298             * and reset flags.
299             * Note that BSD securelevel may prevent disabling flag.
300         */
301
302             if (stat(attr->olname, &s) == 0 && s.st_flags != 0) {
303                if (chflags(attr->olname, 0) == 0) {
304                   if (link(attr->olname, attr->ofname) != 0) {
305                      /* restore original file flags even when linking failed */
306                      if (chflags(attr->olname, s.st_flags) < 0) {
307                         Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
308                               attr->olname, be.strerror());
309                      }
310 #endif /* HAVE_CHFLAGS */
311             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
312                   attr->ofname, attr->olname, be.strerror());
313             return CF_ERROR;
314 #ifdef HAVE_CHFLAGS
315                   }
316                   /* finally restore original file flags */
317                   if (chflags(attr->olname, s.st_flags) < 0) {
318                      Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
319                             attr->olname, be.strerror());
320                   }
321                } else {
322                  Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"),
323                        attr->olname, be.strerror());
324                }
325             } else {
326               Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
327                     attr->ofname, attr->olname, be.strerror());
328               return CF_ERROR;
329             }
330 #endif /* HAVE_CHFLAGS */
331
332          }
333          return CF_CREATED;
334 #endif
335       } /* End inner switch */
336
337    case FT_DIRBEGIN:
338    case FT_DIREND:
339       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
340       if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
341          return CF_ERROR;
342       }
343       /*
344        * If we are using the Win32 Backup API, we open the
345        *   directory so that the security info will be read
346        *   and saved.
347        */
348       if (!is_portable_backup(bfd)) {
349          if (is_bopen(bfd)) {
350             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
351          }
352          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
353             berrno be;
354             be.set_errno(bfd->berrno);
355 #ifdef HAVE_WIN32
356             /* Check for trying to create a drive, if so, skip */
357             if (attr->ofname[1] == ':' && 
358                 IsPathSeparator(attr->ofname[2]) && 
359                 attr->ofname[3] == '\0') {
360                return CF_SKIP;
361             }
362 #endif
363             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
364                   attr->ofname, be.strerror());
365             return CF_ERROR;
366          }
367          return CF_EXTRACT;
368       } else {
369          return CF_CREATED;
370       }
371
372    /* The following should not occur */
373    case FT_NOACCESS:
374    case FT_NOFOLLOW:
375    case FT_NOSTAT:
376    case FT_DIRNOCHG:
377    case FT_NOCHG:
378    case FT_ISARCH:
379    case FT_NORECURSE:
380    case FT_NOFSCHG:
381    case FT_NOOPEN:
382       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
383       break;
384    default:
385       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
386       break;
387    }
388    return CF_ERROR;
389 }
390
391 /*
392  *  Returns: > 0 index into path where last path char is.
393  *           0  no path
394  *           -1 filename is zero length
395  */
396 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
397 {
398    char *f, *p, *q;
399    int fnl, pnl;
400
401    /* Separate pathname and filename */
402    for (q=p=f=ofile; *p; p++) {
403 #ifdef HAVE_WIN32
404       if (IsPathSeparator(*p)) {
405          f = q;
406          if (IsPathSeparator(p[1])) {
407             p++;
408          }
409       }
410       *q++ = *p;                   /* copy data */
411 #else
412       if (IsPathSeparator(*p)) {
413          f = q;                    /* possible filename */
414       }
415       q++;
416 #endif
417    }
418
419    if (IsPathSeparator(*f)) {
420       f++;
421    }
422    *q = 0;                         /* terminate string */
423
424    fnl = q - f;
425    if (fnl == 0) {
426       /* The filename length must not be zero here because we
427        *  are dealing with a file (i.e. FT_REGE or FT_REG).
428        */
429       Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
430       return -1;
431    }
432    pnl = f - ofile - 1;
433    return pnl;
434 }
435
436 /*
437  * Primitive caching of path to prevent recreating a pathname
438  *   each time as long as we remain in the same directory.
439  */
440 static int path_already_seen(JCR *jcr, char *path, int pnl)
441 {
442    if (!jcr->cached_path) {
443       jcr->cached_path = get_pool_memory(PM_FNAME);
444    }
445    if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
446       return 1;
447    }
448    pm_strcpy(jcr->cached_path, path);
449    jcr->cached_pnl = pnl;
450    return 0;
451 }