]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/findlib/create_file.c
- Fix the block listing bug pointed out by Arno.
[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    Copyright (C) 2000-2005 Kern Sibbald
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License
14    version 2 as amended with additional clauses defined in the
15    file LICENSE in the main source directory.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
20    the file LICENSE for additional details.
21
22  */
23
24 #include "bacula.h"
25 #include "find.h"
26
27 #ifndef S_IRWXUGO
28 #define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
29 #endif
30
31 #ifndef IS_CTG
32 #define IS_CTG(x) 0
33 #define O_CTG 0
34 #endif
35
36 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile);
37 static int path_already_seen(JCR *jcr, char *path, int pnl);
38
39
40 /*
41  * Create the file, or the directory
42  *
43  *  fname is the original filename
44  *  ofile is the output filename (may be in a different directory)
45  *
46  * Returns:  CF_SKIP     if file should be skipped
47  *           CF_ERROR    on error
48  *           CF_EXTRACT  file created and data to restore
49  *           CF_CREATED  file created no data to restore
50  *
51  *   Note, we create the file here, except for special files,
52  *     we do not set the attributes because we want to first
53  *     write the file, then when the writing is done, set the
54  *     attributes.
55  *   So, we return with the file descriptor open for normal
56  *     files.
57  *
58  */
59 int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
60 {
61    int new_mode, parent_mode, mode;
62    uid_t uid;
63    gid_t gid;
64    int pnl;
65    bool exists = false;
66    struct stat mstatp;
67
68    if (is_win32_stream(attr->data_stream)) {
69       set_win32_backup(bfd);
70    } else {
71       set_portable_backup(bfd);
72    }
73
74    new_mode = attr->statp.st_mode;
75    Dmsg2(300, "newmode=%x file=%s\n", new_mode, attr->ofname);
76    parent_mode = S_IWUSR | S_IXUSR | new_mode;
77    gid = attr->statp.st_gid;
78    uid = attr->statp.st_uid;
79
80    Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
81    if (lstat(attr->ofname, &mstatp) == 0) {
82       exists = true;
83       switch (replace) {
84       case REPLACE_IFNEWER:
85          if (attr->statp.st_mtime <= mstatp.st_mtime) {
86             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
87             return CF_SKIP;
88          }
89          break;
90
91       case REPLACE_IFOLDER:
92          if (attr->statp.st_mtime >= mstatp.st_mtime) {
93             Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
94             return CF_SKIP;
95          }
96          break;
97
98       case REPLACE_NEVER:
99          Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
100          return CF_SKIP;
101
102       case REPLACE_ALWAYS:
103          break;
104       }
105    }
106    switch (attr->type) {
107    case FT_LNKSAVED:                  /* Hard linked, file already saved */
108    case FT_LNK:
109    case FT_RAW:
110    case FT_FIFO:
111    case FT_SPEC:
112    case FT_REGE:                      /* empty file */
113    case FT_REG:                       /* regular file */
114       /* 
115        * Note, we do not delete FT_RAW because these are device files
116        *  or FIFOs that should already exist. If we blow it away,
117        *  we may blow away a FIFO that is being used to read the
118        *  restore data, or we may blow away a partition definition.
119        */
120       if (exists && attr->type != FT_RAW) {
121          /* Get rid of old copy */
122          if (unlink(attr->ofname) == -1) {
123             berrno be;
124             Qmsg(jcr, M_ERROR, 0, _("File %s already exists and could not be replaced. ERR=%s.\n"),
125                attr->ofname, be.strerror());
126             /* Continue despite error */
127          }
128       }
129       /*
130        * Here we do some preliminary work for all the above
131        *   types to create the path to the file if it does
132        *   not already exist.  Below, we will split to
133        *   do the file type specific work
134        */
135       pnl = separate_path_and_file(jcr, attr->fname, attr->ofname);
136       if (pnl < 0) {
137          return CF_ERROR;
138       }
139
140       /*
141        * If path length is <= 0 we are making a file in the root
142        *  directory. Assume that the directory already exists.
143        */
144       if (pnl > 0) {
145          char savechr;
146          savechr = attr->ofname[pnl];
147          attr->ofname[pnl] = 0;                 /* terminate path */
148
149          if (!path_already_seen(jcr, attr->ofname, pnl)) {
150             Dmsg1(100, "Make path %s\n", attr->ofname);
151             /*
152              * If we need to make the directory, ensure that it is with
153              * execute bit set (i.e. parent_mode), and preserve what already
154              * exists. Normally, this should do nothing.
155              */
156             if (make_path(jcr, attr->ofname, parent_mode, parent_mode, uid, gid, 1, NULL) != 0) {
157                Dmsg1(10, "Could not make path. %s\n", attr->ofname);
158                attr->ofname[pnl] = savechr;     /* restore full name */
159                return CF_ERROR;
160             }
161          }
162          attr->ofname[pnl] = savechr;           /* restore full name */
163       }
164
165       /* Now we do the specific work for each file type */
166       switch(attr->type) {
167       case FT_REGE:
168       case FT_REG:
169          Dmsg1(100, "Create file %s\n", attr->ofname);
170          mode =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
171          if (IS_CTG(attr->statp.st_mode)) {
172             mode |= O_CTG;               /* set contiguous bit if needed */
173          }
174          Dmsg1(50, "Create file: %s\n", attr->ofname);
175          if (is_bopen(bfd)) {
176             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
177             bclose(bfd);
178          }
179          /*
180           * If the open fails, we attempt to cd into the directory
181           *  and create the file with a relative path rather than
182           *  the full absolute path.  This is for Win32 where
183           *  path names may be too long to create.
184           */
185          if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
186             berrno be;
187             int stat;
188             Dmsg2(000, "bopen failed errno=%d: ERR=%s\n", bfd->berrno,  
189                be.strerror(bfd->berrno));
190             if (strlen(attr->ofname) > 250) {   /* Microsoft limitation */
191                char savechr;
192                char *p, *e;
193                struct saved_cwd cwd;
194                savechr = attr->ofname[pnl];
195                attr->ofname[pnl] = 0;                 /* terminate path */
196                Dmsg1(000, "Do chdir %s\n", attr->ofname);
197                if (save_cwd(&cwd) != 0) {
198                   Qmsg0(jcr, M_ERROR, 0, _("Could not save_dirn"));
199                   attr->ofname[pnl] = savechr;
200                   return CF_ERROR;
201                }
202                p = attr->ofname;
203                while ((e = strchr(p, '/'))) {
204                   *e = 0;
205                   if (chdir(p) < 0) {
206                      berrno be;
207                      Qmsg2(jcr, M_ERROR, 0, _("Could not chdir to %s: ERR=%s\n"),
208                            attr->ofname, be.strerror());
209                      restore_cwd(&cwd, NULL, NULL);
210                      free_cwd(&cwd);
211                      attr->ofname[pnl] = savechr;
212                      *e = '/';
213                      return CF_ERROR;
214                   }
215                   *e = '/';
216                   p = e + 1;
217                }
218                if (chdir(p) < 0) {
219                   berrno be;
220                   Qmsg2(jcr, M_ERROR, 0, _("Could not chdir to %s: ERR=%s\n"),
221                         attr->ofname, be.strerror());
222                   restore_cwd(&cwd, NULL, NULL);
223                   free_cwd(&cwd);
224                   attr->ofname[pnl] = savechr;
225                   return CF_ERROR;
226                }
227                attr->ofname[pnl] = savechr;
228                Dmsg1(000, "Do open %s\n", &attr->ofname[pnl+1]);
229                if ((bopen(bfd, &attr->ofname[pnl+1], mode, S_IRUSR | S_IWUSR)) < 0) {
230                   stat = CF_ERROR;
231                } else {
232                   stat = CF_EXTRACT;
233                }
234                restore_cwd(&cwd, NULL, NULL);
235                free_cwd(&cwd);
236                if (stat == CF_EXTRACT) {
237                   return CF_EXTRACT;
238                }
239             }
240             Qmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
241                   attr->ofname, be.strerror(bfd->berrno));
242             return CF_ERROR;
243          }
244          return CF_EXTRACT;
245 #ifndef HAVE_WIN32  // none of these exists on MS Windows
246       case FT_RAW:                    /* Bacula raw device e.g. /dev/sda1 */
247       case FT_FIFO:                   /* Bacula fifo to save data */
248       case FT_SPEC:
249          if (S_ISFIFO(attr->statp.st_mode)) {
250             Dmsg1(200, "Restore fifo: %s\n", attr->ofname);
251             if (mkfifo(attr->ofname, attr->statp.st_mode) != 0 && errno != EEXIST) {
252                berrno be;
253                Qmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"),
254                      attr->ofname, be.strerror());
255                return CF_ERROR;
256             }
257          } else if(S_ISSOCK(attr->statp.st_mode)) {
258              Dmsg1(200, "Skipping restore of socket: %s\n", attr->ofname);
259          } else {
260             Dmsg1(200, "Restore node: %s\n", attr->ofname);
261             if (mknod(attr->ofname, attr->statp.st_mode, attr->statp.st_rdev) != 0 && errno != EEXIST) {
262                berrno be;
263                Qmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"),
264                      attr->ofname, be.strerror());
265                return CF_ERROR;
266             }
267          }
268          if (attr->type == FT_RAW || attr->type == FT_FIFO) {
269             btimer_t *tid;
270             Dmsg1(200, "FT_RAW|FT_FIFO %s\n", attr->ofname);
271             mode =  O_WRONLY | O_BINARY;
272             /* Timeout open() in 60 seconds */
273             if (attr->type == FT_FIFO) {
274                tid = start_thread_timer(pthread_self(), 60);
275             } else {
276                tid = NULL;
277             }
278             if (is_bopen(bfd)) {
279                Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
280             }
281             if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
282                berrno be;
283                be.set_errno(bfd->berrno);
284                Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
285                      attr->ofname, be.strerror());
286                stop_thread_timer(tid);
287                return CF_ERROR;
288             }
289             stop_thread_timer(tid);
290             return CF_EXTRACT;
291          }
292          Dmsg1(200, "FT_SPEC %s\n", attr->ofname);
293          return CF_CREATED;
294
295       case FT_LNK:
296          Dmsg2(130, "FT_LNK should restore: %s -> %s\n", attr->ofname, attr->olname);
297          if (symlink(attr->olname, attr->ofname) != 0 && errno != EEXIST) {
298             berrno be;
299             Qmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"),
300                   attr->ofname, attr->olname, be.strerror());
301             return CF_ERROR;
302          }
303          return CF_CREATED;
304
305       case FT_LNKSAVED:                  /* Hard linked, file already saved */
306          Dmsg2(130, "Hard link %s => %s\n", attr->ofname, attr->olname);
307          if (link(attr->olname, attr->ofname) != 0) {
308             berrno be;
309             Qmsg3(jcr, M_ERROR, 0, _("Could not hard link %s -> %s: ERR=%s\n"),
310                   attr->ofname, attr->olname, be.strerror());
311             return CF_ERROR;
312          }
313          return CF_CREATED;
314 #endif
315       } /* End inner switch */
316
317    case FT_DIRBEGIN:
318    case FT_DIREND:
319       Dmsg2(200, "Make dir mode=%o dir=%s\n", new_mode, attr->ofname);
320       if (make_path(jcr, attr->ofname, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
321          return CF_ERROR;
322       }
323       /*
324        * If we are using the Win32 Backup API, we open the
325        *   directory so that the security info will be read
326        *   and saved.
327        */
328       if (!is_portable_backup(bfd)) {
329          if (is_bopen(bfd)) {
330             Qmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
331          }
332          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
333             berrno be;
334             be.set_errno(bfd->berrno);
335 #ifdef HAVE_WIN32
336             /* Check for trying to create a drive, if so, skip */
337             if (attr->ofname[1] == ':' && attr->ofname[2] == '/' && attr->ofname[3] == 0) {
338                return CF_SKIP;
339             }
340 #endif
341             Qmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
342                   attr->ofname, be.strerror());
343             return CF_ERROR;
344          }
345          return CF_EXTRACT;
346       } else {
347          return CF_CREATED;
348       }
349
350    /* The following should not occur */
351    case FT_NOACCESS:
352    case FT_NOFOLLOW:
353    case FT_NOSTAT:
354    case FT_DIRNOCHG:
355    case FT_NOCHG:
356    case FT_ISARCH:
357    case FT_NORECURSE:
358    case FT_NOFSCHG:
359    case FT_NOOPEN:
360       Qmsg2(jcr, M_ERROR, 0, _("Original file %s not saved: type=%d\n"), attr->fname, attr->type);
361       break;
362    default:
363       Qmsg2(jcr, M_ERROR, 0, _("Unknown file type %d; not restored: %s\n"), attr->type, attr->fname);
364       break;
365    }
366    return CF_ERROR;
367 }
368
369 /*
370  *  Returns: > 0 index into path where last path char is.
371  *           0  no path
372  *           -1 filename is zero length
373  */
374 static int separate_path_and_file(JCR *jcr, char *fname, char *ofile)
375 {
376    char *f, *p;
377    int fnl, pnl;
378
379    /* Separate pathname and filename */
380    for (p=f=ofile; *p; p++) {
381       if (*p == '/') {
382          f = p;                    /* possible filename */
383       }
384    }
385    if (*f == '/') {
386       f++;
387    }
388
389    fnl = p - f;
390    if (fnl == 0) {
391       /* The filename length must not be zero here because we
392        *  are dealing with a file (i.e. FT_REGE or FT_REG).
393        */
394       Qmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
395       return -1;
396    }
397    pnl = f - ofile - 1;
398    return pnl;
399 }
400
401 /*
402  * Primitive caching of path to prevent recreating a pathname
403  *   each time as long as we remain in the same directory.
404  */
405 static int path_already_seen(JCR *jcr, char *path, int pnl)
406 {
407    if (!jcr->cached_path) {
408       jcr->cached_path = get_pool_memory(PM_FNAME);
409    }
410    if (jcr->cached_pnl == pnl && strcmp(path, jcr->cached_path) == 0) {
411       return 1;
412    }
413    pm_strcpy(&jcr->cached_path, path);
414    jcr->cached_pnl = pnl;
415    return 0;
416 }