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