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