]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/create_file.c
ab5b5e28b799bc4d79859007f224f0341af56012
[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 #ifdef S_IFDOOR     // Solaris high speed RPC mechanism
242          } else if (S_ISDOOR(attr->statp.st_mode)) {
243              Dmsg1(200, "Skipping restore of door file: %s\n", attr->ofname);
244 #endif
245 #ifdef S_IFPORT     // Solaris event port for handling AIO
246          } else if (S_ISPORT(attr->statp.st_mode)) {
247              Dmsg1(200, "Skipping restore of event port file: %s\n", attr->ofname);
248 #endif
249          } else {
250             Dmsg1(400, "Restore node: %s\n", attr->ofname);
251             if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
252                berrno be;
253                Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
254                      attr->ofname, be.strerror());
255                return CF_ERROR;
256             }
257          }
258          /*
259           * Here we are going to attempt to restore to a FIFO, which
260           *   means that the FIFO must already exist, AND there must
261           *   be some process already attempting to read from the
262           *   FIFO, so we open it write-only. 
263           */
264          if (attr->type == FT_RAW || attr->type == FT_FIFO) {
265             btimer_t *tid;
266             Dmsg1(400, "FT_RAW|FT_FIFO %s\n", attr->ofname);
267             mode =  O_WRONLY | O_BINARY;
268             /* Timeout open() in 60 seconds */
269             if (attr->type == FT_FIFO) {
270                Dmsg0(400, "Set FIFO timer\n");
271                tid = start_thread_timer(pthread_self(), 60);
272             } else {
273                tid = NULL;
274             }
275             if (is_bopen(bfd)) {
276                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
277             }
278             Dmsg2(400, "open %s mode=0x%x\n", attr->ofname, mode);
279             if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
280                berrno be;
281                be.set_errno(bfd->berrno);
282                Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
283                      attr->ofname, be.strerror());
284                Dmsg2(400, "Could not open %s: ERR=%s\n", attr->ofname, be.strerror());
285                stop_thread_timer(tid);
286                return CF_ERROR;
287             }
288             stop_thread_timer(tid);
289             return CF_EXTRACT;
290          }
291          Dmsg1(400, "FT_SPEC %s\n", attr->ofname);
292          return CF_CREATED;
293
294       case FT_LNK:
295          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
296          if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
297             berrno be;
298             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
299                   attr->ofname, attr->olname, be.strerror());
300             return CF_ERROR;
301          }
302          return CF_CREATED;
303
304       case FT_LNKSAVED:                  /* Hard linked, file already saved */
305          Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
306          if (link(attr->olname, attr->ofname) != 0) {
307             berrno be;
308 #ifdef HAVE_CHFLAGS
309             struct stat s;
310
311         /*
312             * If using BSD user flags, maybe has a file flag
313             * preventing this. So attempt to disable, retry link,
314             * and reset flags.
315             * Note that BSD securelevel may prevent disabling flag.
316         */
317
318             if (stat(attr->olname, &s) == 0 && s.st_flags != 0) {
319                if (chflags(attr->olname, 0) == 0) {
320                   if (link(attr->olname, attr->ofname) != 0) {
321                      /* restore original file flags even when linking failed */
322                      if (chflags(attr->olname, s.st_flags) < 0) {
323                         Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
324                               attr->olname, be.strerror());
325                      }
326 #endif /* HAVE_CHFLAGS */
327             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
328                   attr->ofname, attr->olname, be.strerror());
329             return CF_ERROR;
330 #ifdef HAVE_CHFLAGS
331                   }
332                   /* finally restore original file flags */
333                   if (chflags(attr->olname, s.st_flags) < 0) {
334                      Qmsg2(jcr, M_ERROR, 0, _("Could not restore file flags for file %s: ERR=%s\n"),
335                             attr->olname, be.strerror());
336                   }
337                } else {
338                  Qmsg2(jcr, M_ERROR, 0, _("Could not reset file flags for file %s: ERR=%s\n"),
339                        attr->olname, be.strerror());
340                }
341             } else {
342               Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
343                     attr->ofname, attr->olname, be.strerror());
344               return CF_ERROR;
345             }
346 #endif /* HAVE_CHFLAGS */
347
348          }
349          return CF_CREATED;
350 #endif
351       } /* End inner switch */
352
353    case FT_DIRBEGIN:
354    case FT_DIREND:
355       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
356       if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
357          return CF_ERROR;
358       }
359       /*
360        * If we are using the Win32 Backup API, we open the
361        *   directory so that the security info will be read
362        *   and saved.
363        */
364       if (!is_portable_backup(bfd)) {
365          if (is_bopen(bfd)) {
366             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
367          }
368          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
369             berrno be;
370             be.set_errno(bfd->berrno);
371 #ifdef HAVE_WIN32
372             /* Check for trying to create a drive, if so, skip */
373             if (attr->ofname[1] == ':' && 
374                 IsPathSeparator(attr->ofname[2]) && 
375                 attr->ofname[3] == '\0') {
376                return CF_SKIP;
377             }
378 #endif
379             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
380                   attr->ofname, be.strerror());
381             return CF_ERROR;
382          }
383          return CF_EXTRACT;
384       } else {
385          return CF_CREATED;
386       }
387
388    /* The following should not occur */
389    case FT_NOACCESS:
390    case FT_NOFOLLOW:
391    case FT_NOSTAT:
392    case FT_DIRNOCHG:
393    case FT_NOCHG:
394    case FT_ISARCH:
395    case FT_NORECURSE:
396    case FT_NOFSCHG:
397    case FT_NOOPEN:
398       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
399       break;
400    default:
401       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
402       break;
403    }
404    return CF_ERROR;
405 }
406
407 /*
408  *  Returns: > 0 index into path where last path char is.
409  *           0  no path
410  *           -1 filename is zero length
411  */
412 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
413 {
414    char *f, *p, *q;
415    int fnl, pnl;
416
417    /* Separate pathname and filename */
418    for (q=p=f=ofile; *p; p++) {
419 #ifdef HAVE_WIN32
420       if (IsPathSeparator(*p)) {
421          f = q;
422          if (IsPathSeparator(p[1])) {
423             p++;
424          }
425       }
426       *q++ = *p;                   /* copy data */
427 #else
428       if (IsPathSeparator(*p)) {
429          f = q;                    /* possible filename */
430       }
431       q++;
432 #endif
433    }
434
435    if (IsPathSeparator(*f)) {
436       f++;
437    }
438    *q = 0;                         /* terminate string */
439
440    fnl = q - f;
441    if (fnl == 0) {
442       /* The filename length must not be zero here because we
443        *  are dealing with a file (i.e. FT_REGE or FT_REG).
444        */
445       Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
446       return -1;
447    }
448    pnl = f - ofile - 1;
449    return pnl;
450 }
451
452 /*
453  * Primitive caching of path to prevent recreating a pathname
454  *   each time as long as we remain in the same directory.
455  */
456 static int path_already_seen(JCR *jcr, char *path, int pnl)
457 {
458    if (!jcr->cached_path) {
459       jcr->cached_path = get_pool_memory(PM_FNAME);
460    }
461    if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
462       return 1;
463    }
464    pm_strcpy(jcr->cached_path, path);
465    jcr->cached_pnl = pnl;
466    return 0;
467 }