]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/create_file.c
Update copyright
[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             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
293                   attr->ofname, attr->olname, be.strerror());
294             return CF_ERROR;
295          }
296          return CF_CREATED;
297 #endif
298       } /* End inner switch */
299
300    case FT_DIRBEGIN:
301    case FT_DIREND:
302       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
303       if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
304          return CF_ERROR;
305       }
306       /*
307        * If we are using the Win32 Backup API, we open the
308        *   directory so that the security info will be read
309        *   and saved.
310        */
311       if (!is_portable_backup(bfd)) {
312          if (is_bopen(bfd)) {
313             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
314          }
315          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
316             berrno be;
317             be.set_errno(bfd->berrno);
318 #ifdef HAVE_WIN32
319             /* Check for trying to create a drive, if so, skip */
320             if (attr->ofname[1] == ':' && 
321                 IsPathSeparator(attr->ofname[2]) && 
322                 attr->ofname[3] == '\0') {
323                return CF_SKIP;
324             }
325 #endif
326             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
327                   attr->ofname, be.strerror());
328             return CF_ERROR;
329          }
330          return CF_EXTRACT;
331       } else {
332          return CF_CREATED;
333       }
334
335    /* The following should not occur */
336    case FT_NOACCESS:
337    case FT_NOFOLLOW:
338    case FT_NOSTAT:
339    case FT_DIRNOCHG:
340    case FT_NOCHG:
341    case FT_ISARCH:
342    case FT_NORECURSE:
343    case FT_NOFSCHG:
344    case FT_NOOPEN:
345       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
346       break;
347    default:
348       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
349       break;
350    }
351    return CF_ERROR;
352 }
353
354 /*
355  *  Returns: > 0 index into path where last path char is.
356  *           0  no path
357  *           -1 filename is zero length
358  */
359 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
360 {
361    char *f, *p, *q;
362    int fnl, pnl;
363
364    /* Separate pathname and filename */
365    for (q=p=f=ofile; *p; p++) {
366 #ifdef HAVE_WIN32
367       if (IsPathSeparator(*p)) {
368          f = q;
369          if (IsPathSeparator(p[1])) {
370             p++;
371          }
372       }
373       *q++ = *p;                   /* copy data */
374 #else
375       if (IsPathSeparator(*p)) {
376          f = q;                    /* possible filename */
377       }
378       q++;
379 #endif
380    }
381
382    if (IsPathSeparator(*f)) {
383       f++;
384    }
385    *q = 0;                         /* terminate string */
386
387    fnl = q - f;
388    if (fnl == 0) {
389       /* The filename length must not be zero here because we
390        *  are dealing with a file (i.e. FT_REGE or FT_REG).
391        */
392       Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
393       return -1;
394    }
395    pnl = f - ofile - 1;
396    return pnl;
397 }
398
399 /*
400  * Primitive caching of path to prevent recreating a pathname
401  *   each time as long as we remain in the same directory.
402  */
403 static int path_already_seen(JCR *jcr, char *path, int pnl)
404 {
405    if (!jcr->cached_path) {
406       jcr->cached_path = get_pool_memory(PM_FNAME);
407    }
408    if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
409       return 1;
410    }
411    pm_strcpy(jcr->cached_path, path);
412    jcr->cached_pnl = pnl;
413    return 0;
414 }