[BACK]Return to uploader.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rsync

Diff for /src/usr.bin/rsync/uploader.c between version 1.14 and 1.15

version 1.14, 2019/02/17 16:34:04 version 1.15, 2019/02/18 21:34:54
Line 163 
Line 163 
 }  }
   
 /*  /*
    * Handle a symbolic link.
    * If we encounter directories existing in the symbolic link's place,
    * then try to unlink the directory.
    * Otherwise, simply overwrite with the symbolic link by renaming.
  * Return <0 on failure 0 on success.   * Return <0 on failure 0 on success.
  */   */
 static int  static int
Line 184 
Line 188 
                 return 0;                  return 0;
         }          }
   
         /* See if the symlink already exists. */          /*
            * See if the symlink already exists.
            * If it's a directory, then try to unlink the directory prior
            * to overwriting with a symbolic link.
            * If it's a non-directory, we just overwrite it.
            */
   
         assert(p->rootfd != -1);          assert(p->rootfd != -1);
         rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);          rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
         if (rc != -1 && !S_ISLNK(st.st_mode)) {          if (rc != -1 && !S_ISLNK(st.st_mode)) {
                 if (S_ISDIR(st.st_mode)) {                  if (S_ISDIR(st.st_mode) &&
                         if (unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {                      unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
                                 WARN(sess, "%s", f->path);                          ERR(sess, "%s: unlinkat", f->path);
                                 return -1;                          return -1;
                         }  
                 }                  }
                 rc = -1; /* overwrite object with symlink */                  rc = -1;
         } else if (rc == -1 && errno != ENOENT) {          } else if (rc == -1 && errno != ENOENT) {
                 WARN(sess, "%s: fstatat", f->path);                  ERR(sess, "%s: fstatat", f->path);
                 return -1;                  return -1;
         }          }
   
Line 209 
Line 217 
         if (rc != -1) {          if (rc != -1) {
                 b = symlinkat_read(sess, p->rootfd, f->path);                  b = symlinkat_read(sess, p->rootfd, f->path);
                 if (b == NULL) {                  if (b == NULL) {
                         ERRX1(sess, "%s: symlinkat_read", f->path);                          ERRX1(sess, "symlinkat_read");
                         return -1;                          return -1;
                 }                  }
                 if (strcmp(f->link, b)) {                  if (strcmp(f->link, b)) {
Line 223 
Line 231 
                 b = NULL;                  b = NULL;
         }          }
   
           /*
            * Create the temporary file as a symbolic link, then rename the
            * temporary file as the real one, overwriting anything there.
            */
   
         if (rc == -1 || updatelink) {          if (rc == -1 || updatelink) {
                 LOG3(sess, "%s: creating "                  LOG3(sess, "%s: creating "
                         "symlink: %s", f->path, f->link);                          "symlink: %s", f->path, f->link);
                   if (mktemplate(sess, &temp,
                 if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {                      f->path, sess->opts->recursive) == -1) {
                         ERR(sess, "asprintf");                          ERRX1(sess, "mktemplate");
                         return -1;                          return -1;
                 }                  }
                 if (mkstemplinkat(f->link, p->rootfd, temp) == NULL) {                  if (mkstemplinkat(f->link, p->rootfd, temp) == NULL) {
                         WARN(sess, "%s: symlinkat", temp);                          ERR(sess, "mkstemplinkat");
                         free(temp);                          free(temp);
                         return -1;                          return -1;
                 }                  }
                 newlink = 1;                  newlink = 1;
         }          }
   
         rsync_set_metadata_at(sess, newlink, p->rootfd, f,          rsync_set_metadata_at(sess, newlink,
             newlink ? temp : f->path);                  p->rootfd, f, newlink ? temp : f->path);
   
         if (newlink) {          if (newlink) {
                 if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {                  if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
Line 257 
Line 270 
 }  }
   
 /*  /*
    * See pre_link(), but for devices.
    * FIXME: this is very similar to the other pre_xxx() functions.
  * Return <0 on failure 0 on success.   * Return <0 on failure 0 on success.
  */   */
 static int  static int
Line 278 
Line 293 
                 return 0;                  return 0;
         }          }
   
         /* See if the dev already exists */          /*
         assert(p->rootfd != -1);           * See if the dev already exists.
            * If a non-device exists in its place, we'll replace that.
            * If it replaces a directory, remove the directory first.
            */
   
           assert(p->rootfd != -1);
         rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);          rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
   
         if (rc != -1 && !(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))) {          if (rc != -1 && !(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))) {
                 if (S_ISDIR(st.st_mode)) {                  if (S_ISDIR(st.st_mode) &&
                         if (unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {                      unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
                                 WARN(sess, "%s", f->path);                          ERR(sess, "%s: unlinkat", f->path);
                                 return -1;                          return -1;
                         }  
                 }                  }
                 rc = -1; /* overwrite object with dev */                  rc = -1;
         } else if (rc == -1 && errno != ENOENT) {          } else if (rc == -1 && errno != ENOENT) {
                 WARN(sess, "%s: fstatat", f->path);                  ERR(sess, "%s: fstatat", f->path);
                 return -1;                  return -1;
         }          }
   
         /*          /* Make sure existing device is of the correct type. */
          * If the device already exists make sure it is of the correct type.  
          */  
   
         if (rc != -1) {          if (rc != -1) {
                 if ((f->st.mode & (S_IFCHR|S_IFBLK)) !=                  if ((f->st.mode & (S_IFCHR|S_IFBLK)) !=
                     (st.st_mode & (S_IFCHR|S_IFBLK)) || f->st.rdev !=                      (st.st_mode & (S_IFCHR|S_IFBLK)) ||
                     st.st_rdev) {                      f->st.rdev != st.st_rdev) {
                         LOG3(sess, "%s: updating dev", f->path);                          LOG3(sess, "%s: updating device", f->path);
                         updatedev = 1;                          updatedev = 1;
                 }                  }
         }          }
   
         if (rc == -1 || updatedev) {          if (rc == -1 || updatedev) {
                 newdev = 1;                  newdev = 1;
                 if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {                  if (mktemplate(sess, &temp, f->path,
                         ERR(sess, "asprintf");                      sess->opts->recursive) == -1) {
                           ERRX1(sess, "mktemplate");
                         return -1;                          return -1;
                 }                  }
                 if (mkstempnodat(p->rootfd, temp, f->st.mode &                  if (mkstempnodat(p->rootfd, temp,
                     (S_IFCHR|S_IFBLK), f->st.rdev) == NULL) {                      f->st.mode & (S_IFCHR|S_IFBLK), f->st.rdev) == NULL) {
                         WARN(sess, "%s: mknodat", temp);                          ERR(sess, "mkstempnodat");
                         free(temp);                          free(temp);
                         return -1;                          return -1;
                 }                  }
         }          }
   
         rsync_set_metadata_at(sess, newdev, p->rootfd, f,          rsync_set_metadata_at(sess, newdev,
             newdev ? temp : f->path);                  p->rootfd, f, newdev ? temp : f->path);
   
         if (newdev) {          if (newdev) {
                 if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {                  if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
Line 335 
Line 352 
                 }                  }
                 free(temp);                  free(temp);
         }          }
   
         log_file(sess, f);          log_file(sess, f);
         return 0;          return 0;
 }  }
   
 /*  /*
    * See pre_link(), but for FIFOs.
    * FIXME: this is very similar to the other pre_xxx() functions.
  * Return <0 on failure 0 on success.   * Return <0 on failure 0 on success.
  */   */
 static int  static int
Line 361 
Line 381 
                 return 0;                  return 0;
         }          }
   
         /* See if the fifo already exists */          /*
         assert(p->rootfd != -1);           * See if the fifo already exists.
            * If it exists as a non-FIFO, unlink it (if a directory) then
            * mark it from replacement.
            */
   
           assert(p->rootfd != -1);
         rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);          rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
   
         if (rc != -1 && !S_ISFIFO(st.st_mode)) {          if (rc != -1 && !S_ISFIFO(st.st_mode)) {
                 if (S_ISDIR(st.st_mode)) {                  if (S_ISDIR(st.st_mode) &&
                         if (unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {                      unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
                                 WARN(sess, "%s", f->path);                          ERR(sess, "%s: unlinkat", f->path);
                                 return -1;                          return -1;
                         }  
                 }                  }
                 rc = -1; /* overwrite object with fifo */                  rc = -1;
         } else if (rc == -1 && errno != ENOENT) {          } else if (rc == -1 && errno != ENOENT) {
                 WARN(sess, "%s: fstatat", f->path);                  ERR(sess, "%s: fstatat", f->path);
                 return -1;                  return -1;
         }          }
   
         if (rc == -1) {          if (rc == -1) {
                 newfifo = 1;                  newfifo = 1;
                 if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {                  if (mktemplate(sess, &temp, f->path,
                         ERR(sess, "asprintf");                      sess->opts->recursive) == -1) {
                           ERRX1(sess, "mktemplate");
                         return -1;                          return -1;
                 }                  }
                 if (mkstempfifoat(p->rootfd, temp) == NULL) {                  if (mkstempfifoat(p->rootfd, temp) == NULL) {
                         WARN(sess, "%s: mkfifoat", temp);                          ERR(sess, "mkstempfifoat");
                         free(temp);                          free(temp);
                         return -1;                          return -1;
                 }                  }
         }          }
   
         rsync_set_metadata_at(sess, newfifo, p->rootfd, f,          rsync_set_metadata_at(sess, newfifo,
             newfifo ? temp : f->path);                  p->rootfd, f, newfifo ? temp : f->path);
   
         if (newfifo) {          if (newfifo) {
                 if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {                  if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
Line 404 
Line 428 
                 }                  }
                 free(temp);                  free(temp);
         }          }
   
         log_file(sess, f);          log_file(sess, f);
         return 0;          return 0;
 }  }
   
 /*  /*
    * See pre_link(), but for socket files.
    * FIXME: this is very similar to the other pre_xxx() functions.
  * Return <0 on failure 0 on success.   * Return <0 on failure 0 on success.
  */   */
 static int  static int
Line 430 
Line 457 
                 return 0;                  return 0;
         }          }
   
           /*
            * See if the fifo already exists.
            * If it exists as a non-FIFO, unlink it (if a directory) then
            * mark it from replacement.
            */
   
           assert(-1 != p->rootfd);
         rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);          rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
   
         if (rc != -1 && !S_ISSOCK(st.st_mode)) {          if (rc != -1 && !S_ISSOCK(st.st_mode)) {
                 if (S_ISDIR(st.st_mode)) {                  if (S_ISDIR(st.st_mode) &&
                         if (unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {                      unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
                                 WARN(sess, "%s", f->path);                          ERR(sess, "%s: unlinkat", f->path);
                                 return -1;                          return -1;
                         }  
                 }                  }
                 rc = -1; /* overwrite object with sock */                  rc = -1;
         } else if (rc == -1 && errno != ENOENT) {          } else if (rc == -1 && errno != ENOENT) {
                 WARN(sess, "%s: fstatat", f->path);                  ERR(sess, "%s: fstatat", f->path);
                 return -1;                  return -1;
         }          }
   
         if (rc == -1) {          if (rc == -1) {
                 newsock = 1;                  newsock = 1;
                   if (mktemplate(sess, &temp, f->path,
                 if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {                      sess->opts->recursive) == -1) {
                         ERR(sess, "asprintf");                          ERRX1(sess, "mktemplate");
                         return -1;                          return -1;
                 }                  }
   
                 if (mkstempsock(p->root, temp) == NULL) {                  if (mkstempsock(p->root, temp) == NULL) {
                         WARN(sess, "%s: mksockat", temp);                          ERR(sess, "mkstempsock");
                         free(temp);                          free(temp);
                         return -1;                          return -1;
                 }                  }
         }          }
   
         rsync_set_metadata_at(sess, newsock, p->rootfd, f,          rsync_set_metadata_at(sess, newsock,
             newsock ? temp : f->path);                  p->rootfd, f, newsock ? temp : f->path);
   
         if (newsock) {          if (newsock) {
                 if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {                  if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
Line 472 
Line 504 
                 }                  }
                 free(temp);                  free(temp);
         }          }
   
         log_file(sess, f);          log_file(sess, f);
         return 0;          return 0;
 }  }
Line 501 
Line 534 
   
         assert(p->rootfd != -1);          assert(p->rootfd != -1);
         rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);          rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
   
         if (rc == -1 && errno != ENOENT) {          if (rc == -1 && errno != ENOENT) {
                 WARN(sess, "%s: fstatat", f->path);                  ERR(sess, "%s: fstatat", f->path);
                 return -1;                  return -1;
         } else if (rc != -1 && !S_ISDIR(st.st_mode)) {          } else if (rc != -1 && !S_ISDIR(st.st_mode)) {
                 WARNX(sess, "%s: not a directory", f->path);                  ERRX(sess, "%s: not a directory", f->path);
                 return -1;                  return -1;
         } else if (rc != -1) {          } else if (rc != -1) {
                 /*                  /*
Line 526 
Line 560 
   
         LOG3(sess, "%s: creating directory", f->path);          LOG3(sess, "%s: creating directory", f->path);
         if (mkdirat(p->rootfd, f->path, 0777 & ~p->oumask) == -1) {          if (mkdirat(p->rootfd, f->path, 0777 & ~p->oumask) == -1) {
                 WARN(sess, "%s: mkdirat", f->path);                  ERR(sess, "%s: mkdirat", f->path);
                 return -1;                  return -1;
         }          }
   
Line 824 
Line 858 
                 /* Go back to the event loop, if necessary. */                  /* Go back to the event loop, if necessary. */
   
                 u->state = (*fileinfd == -1) ?                  u->state = (*fileinfd == -1) ?
                     UPLOAD_WRITE_LOCAL : UPLOAD_READ_LOCAL;                          UPLOAD_WRITE_LOCAL : UPLOAD_READ_LOCAL;
                 if (u->state == UPLOAD_READ_LOCAL)                  if (u->state == UPLOAD_READ_LOCAL)
                         return 1;                          return 1;
         }          }
Line 885 
Line 919 
                 mapsz = st.st_size;                  mapsz = st.st_size;
                 map = mmap(NULL, mapsz, PROT_READ, MAP_SHARED, *fileinfd, 0);                  map = mmap(NULL, mapsz, PROT_READ, MAP_SHARED, *fileinfd, 0);
                 if (map == MAP_FAILED) {                  if (map == MAP_FAILED) {
                         WARN(sess, "%s: mmap", u->fl[u->idx].path);                          ERR(sess, "%s: mmap", u->fl[u->idx].path);
                         close(*fileinfd);                          close(*fileinfd);
                         *fileinfd = -1;                          *fileinfd = -1;
                         return -1;                          return -1;

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15