]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/findlib/create_file.c
- Fix handling of temp file in mtx_changer.in, reported as
[bacula/bacula] / bacula / src / findlib / create_file.c
index b7f196d3a403a47404de544a69455b9162e646a0..223d99ecd63e7a5974cb5251d5016604283ca18d 100644 (file)
@@ -7,22 +7,17 @@
  *
  */
 /*
-   Copyright (C) 2000-2004 Kern Sibbald and John Walker
+   Copyright (C) 2000-2005 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
 
@@ -116,7 +111,13 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
    case FT_SPEC:
    case FT_REGE:                      /* empty file */
    case FT_REG:                       /* regular file */
-      if (exists) {
+      /* 
+       * Note, we do not delete FT_RAW because these are device files
+       *  or FIFOs that should already exist. If we blow it away,
+       *  we may blow away a FIFO that is being used to read the
+       *  restore data, or we may blow away a partition definition.
+       */
+      if (exists && attr->type != FT_RAW) {
          /* Get rid of old copy */
          if (unlink(attr->ofname) == -1) {
             berrno be;
@@ -146,7 +147,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
          attr->ofname[pnl] = 0;                 /* terminate path */
 
          if (!path_already_seen(jcr, attr->ofname, pnl)) {
-            Dmsg1(50, "Make path %s\n", attr->ofname);
+            Dmsg1(100, "Make path %s\n", attr->ofname);
             /*
              * If we need to make the directory, ensure that it is with
              * execute bit set (i.e. parent_mode), and preserve what already
@@ -172,14 +173,72 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
          }
          Dmsg1(50, "Create file: %s\n", attr->ofname);
          if (is_bopen(bfd)) {
-            Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
+            Jmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
             bclose(bfd);
          }
+         /*
+          * If the open fails, we attempt to cd into the directory
+          *  and create the file with a relative path rather than
+          *  the full absolute path.  This is for Win32 where
+          *  path names may be too long to create.
+          */
          if ((bopen(bfd, attr->ofname, mode, S_IRUSR | S_IWUSR)) < 0) {
             berrno be;
-            be.set_errno(bfd->berrno);
+            int stat;
+            Dmsg2(000, "bopen failed errno=%d: ERR=%s\n", bfd->berrno,  
+               be.strerror(bfd->berrno));
+            if (strlen(attr->ofname) > 250) {   /* Microsoft limitation */
+               char savechr;
+               char *p, *e;
+               struct saved_cwd cwd;
+               savechr = attr->ofname[pnl];
+               attr->ofname[pnl] = 0;                 /* terminate path */
+               Dmsg1(000, "Do chdir %s\n", attr->ofname);
+               if (save_cwd(&cwd) != 0) {
+                  Jmsg0(jcr, M_ERROR, 0, _("Could not save_dirn"));
+                  attr->ofname[pnl] = savechr;
+                  return CF_ERROR;
+               }
+               p = attr->ofname;
+               while ((e = strchr(p, '/'))) {
+                  *e = 0;
+                  if (chdir(p) < 0) {
+                     berrno be;
+                     Jmsg2(jcr, M_ERROR, 0, _("Could not chdir to %s: ERR=%s\n"),
+                           attr->ofname, be.strerror());
+                     restore_cwd(&cwd, NULL, NULL);
+                     free_cwd(&cwd);
+                     attr->ofname[pnl] = savechr;
+                     *e = '/';
+                     return CF_ERROR;
+                  }
+                  *e = '/';
+                  p = e + 1;
+               }
+               if (chdir(p) < 0) {
+                  berrno be;
+                  Jmsg2(jcr, M_ERROR, 0, _("Could not chdir to %s: ERR=%s\n"),
+                        attr->ofname, be.strerror());
+                  restore_cwd(&cwd, NULL, NULL);
+                  free_cwd(&cwd);
+                  attr->ofname[pnl] = savechr;
+                  return CF_ERROR;
+               }
+               attr->ofname[pnl] = savechr;
+               Dmsg1(000, "Do open %s\n", &attr->ofname[pnl+1]);
+               if ((bopen(bfd, &attr->ofname[pnl+1], mode, S_IRUSR | S_IWUSR)) < 0) {
+                  stat = CF_ERROR;
+               } else {
+                  stat = CF_EXTRACT;
+               }
+               restore_cwd(&cwd, NULL, NULL);
+               free_cwd(&cwd);
+               if (stat == CF_EXTRACT) {
+                  return CF_EXTRACT;
+               }
+            }
             Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"),
-                  attr->ofname, be.strerror());
+                  attr->ofname, be.strerror(bfd->berrno));
             return CF_ERROR;
          }
          return CF_EXTRACT;
@@ -215,7 +274,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
                tid = NULL;
             }
             if (is_bopen(bfd)) {
-               Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
+               Jmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
             }
             if ((bopen(bfd, attr->ofname, mode, 0)) < 0) {
                berrno be;
@@ -266,7 +325,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
        */
       if (!is_portable_backup(bfd)) {
          if (is_bopen(bfd)) {
-            Jmsg1(jcr, M_ERROR, 0, "bpkt already open fid=%d\n", bfd->fid);
+            Jmsg1(jcr, M_ERROR, 0, _("bpkt already open fid=%d\n"), bfd->fid);
          }
          if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
             berrno be;