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

Diff for /src/usr.bin/rsync/flist.c between version 1.24 and 1.25

version 1.24, 2019/04/04 04:19:54 version 1.25, 2019/05/08 20:00:25
Line 81 
Line 81 
   
         new = calloc(*sz, sizeof(struct flist));          new = calloc(*sz, sizeof(struct flist));
         if (new == NULL) {          if (new == NULL) {
                 ERR(sess, "calloc");                  ERR("calloc");
                 return 0;                  return 0;
         }          }
   
Line 106 
Line 106 
                 if (strcmp(f->path, fnext->path) == 0) {                  if (strcmp(f->path, fnext->path) == 0) {
                         new[j++] = *f;                          new[j++] = *f;
                         i++;                          i++;
                         WARNX(sess, "%s: duplicate path: %s",                          WARNX("%s: duplicate path: %s",
                             f->wpath, f->path);                              f->wpath, f->path);
                         free(fnext->path);                          free(fnext->path);
                         free(fnext->link);                          free(fnext->link);
Line 114 
Line 114 
                         continue;                          continue;
                 }                  }
   
                 ERRX(sess, "%s: duplicate working path for "                  ERRX("%s: duplicate working path for "
                     "possibly different file: %s, %s",                      "possibly different file: %s, %s",
                     f->wpath, f->path, fnext->path);                      f->wpath, f->path, fnext->path);
                 free(new);                  free(new);
Line 166 
Line 166 
                         if (cp != NULL && cp[1] != '\0')                          if (cp != NULL && cp[1] != '\0')
                                 continue;                                  continue;
                         fl[i].st.flags |= FLSTAT_TOP_DIR;                          fl[i].st.flags |= FLSTAT_TOP_DIR;
                         LOG4(sess, "%s: top-level", fl[i].wpath);                          LOG4("%s: top-level", fl[i].wpath);
                 }                  }
         } else if (flsz) {          } else if (flsz) {
                 fl[0].st.flags |= FLSTAT_TOP_DIR;                  fl[0].st.flags |= FLSTAT_TOP_DIR;
                 LOG4(sess, "%s: top-level", fl[0].wpath);                  LOG4("%s: top-level", fl[0].wpath);
         }          }
 }  }
   
Line 191 
Line 191 
                 return 1;                  return 1;
   
         if (ent->fts_info == FTS_DC) {          if (ent->fts_info == FTS_DC) {
                 WARNX(sess, "%s: directory cycle", ent->fts_path);                  WARNX("%s: directory cycle", ent->fts_path);
         } else if (ent->fts_info == FTS_DNR) {          } else if (ent->fts_info == FTS_DNR) {
                 errno = ent->fts_errno;                  errno = ent->fts_errno;
                 WARN(sess, "%s: unreadable directory", ent->fts_path);                  WARN("%s: unreadable directory", ent->fts_path);
         } else if (ent->fts_info == FTS_DOT) {          } else if (ent->fts_info == FTS_DOT) {
                 WARNX(sess, "%s: skipping dot-file", ent->fts_path);                  WARNX("%s: skipping dot-file", ent->fts_path);
         } else if (ent->fts_info == FTS_ERR) {          } else if (ent->fts_info == FTS_ERR) {
                 errno = ent->fts_errno;                  errno = ent->fts_errno;
                 WARN(sess, "%s", ent->fts_path);                  WARN("%s", ent->fts_path);
         } else if (ent->fts_info == FTS_DEFAULT) {          } else if (ent->fts_info == FTS_DEFAULT) {
                 if ((sess->opts->devices && (S_ISBLK(ent->fts_statp->st_mode) ||                  if ((sess->opts->devices && (S_ISBLK(ent->fts_statp->st_mode) ||
                     S_ISCHR(ent->fts_statp->st_mode))) ||                      S_ISCHR(ent->fts_statp->st_mode))) ||
Line 208 
Line 208 
                     S_ISSOCK(ent->fts_statp->st_mode)))) {                      S_ISSOCK(ent->fts_statp->st_mode)))) {
                         return 1;                          return 1;
                 }                  }
                 WARNX(sess, "%s: skipping special", ent->fts_path);                  WARNX("%s: skipping special", ent->fts_path);
         } else if (ent->fts_info == FTS_NS) {          } else if (ent->fts_info == FTS_NS) {
                 errno = ent->fts_errno;                  errno = ent->fts_errno;
                 WARN(sess, "%s: could not stat", ent->fts_path);                  WARN("%s: could not stat", ent->fts_path);
         }          }
   
         return 0;          return 0;
Line 265 
Line 265 
   
         /* Double-check that we've no pending multiplexed data. */          /* Double-check that we've no pending multiplexed data. */
   
         LOG2(sess, "sending file metadata list: %zu", flsz);          LOG2("sending file metadata list: %zu", flsz);
   
         for (i = 0; i < flsz; i++) {          for (i = 0; i < flsz; i++) {
                 f = &fl[i];                  f = &fl[i];
Line 284 
Line 284 
                 if (sess->mplex_reads &&                  if (sess->mplex_reads &&
                     io_read_check(sess, fdin) &&                      io_read_check(sess, fdin) &&
                      !io_read_flush(sess, fdin)) {                       !io_read_flush(sess, fdin)) {
                         ERRX1(sess, "io_read_flush");                          ERRX1("io_read_flush");
                         goto out;                          goto out;
                 }                  }
   
Line 299 
Line 299 
                 if ((FLSTAT_TOP_DIR & f->st.flags))                  if ((FLSTAT_TOP_DIR & f->st.flags))
                         flag |= FLIST_TOP_LEVEL;                          flag |= FLIST_TOP_LEVEL;
   
                 LOG3(sess, "%s: sending file metadata: "                  LOG3("%s: sending file metadata: "
                         "size %jd, mtime %jd, mode %o",                          "size %jd, mtime %jd, mode %o",
                         fn, (intmax_t)f->st.size,                          fn, (intmax_t)f->st.size,
                         (intmax_t)f->st.mtime, f->st.mode);                          (intmax_t)f->st.mtime, f->st.mode);
Line 308 
Line 308 
                 /* FIXME: buffer this. */                  /* FIXME: buffer this. */
   
                 if (!io_write_byte(sess, fdout, flag)) {                  if (!io_write_byte(sess, fdout, flag)) {
                         ERRX1(sess, "io_write_byte");                          ERRX1("io_write_byte");
                         goto out;                          goto out;
                 } else if (!io_write_int(sess, fdout, sz)) {                  } else if (!io_write_int(sess, fdout, sz)) {
                         ERRX1(sess, "io_write_int");                          ERRX1("io_write_int");
                         goto out;                          goto out;
                 } else if (!io_write_buf(sess, fdout, fn, sz)) {                  } else if (!io_write_buf(sess, fdout, fn, sz)) {
                         ERRX1(sess, "io_write_buf");                          ERRX1("io_write_buf");
                         goto out;                          goto out;
                 } else if (!io_write_long(sess, fdout, f->st.size)) {                  } else if (!io_write_long(sess, fdout, f->st.size)) {
                         ERRX1(sess, "io_write_long");                          ERRX1("io_write_long");
                         goto out;                          goto out;
                 } else if (!io_write_uint(sess, fdout, (uint32_t)f->st.mtime)) {                  } else if (!io_write_uint(sess, fdout, (uint32_t)f->st.mtime)) {
                         ERRX1(sess, "io_write_uint");                          ERRX1("io_write_uint");
                         goto out;                          goto out;
                 } else if (!io_write_uint(sess, fdout, f->st.mode)) {                  } else if (!io_write_uint(sess, fdout, f->st.mode)) {
                         ERRX1(sess, "io_write_uint");                          ERRX1("io_write_uint");
                         goto out;                          goto out;
                 }                  }
   
Line 331 
Line 331 
   
                 if (sess->opts->preserve_uids) {                  if (sess->opts->preserve_uids) {
                         if (!io_write_uint(sess, fdout, f->st.uid)) {                          if (!io_write_uint(sess, fdout, f->st.uid)) {
                                 ERRX1(sess, "io_write_uint");                                  ERRX1("io_write_uint");
                                 goto out;                                  goto out;
                         }                          }
                         if (!idents_add(sess, 0, &uids, &uidsz, f->st.uid)) {                          if (!idents_add(sess, 0, &uids, &uidsz, f->st.uid)) {
                                 ERRX1(sess, "idents_add");                                  ERRX1("idents_add");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
Line 344 
Line 344 
   
                 if (sess->opts->preserve_gids) {                  if (sess->opts->preserve_gids) {
                         if (!io_write_uint(sess, fdout, f->st.gid)) {                          if (!io_write_uint(sess, fdout, f->st.gid)) {
                                 ERRX1(sess, "io_write_uint");                                  ERRX1("io_write_uint");
                                 goto out;                                  goto out;
                         }                          }
                         if (!idents_add(sess, 1, &gids, &gidsz, f->st.gid)) {                          if (!idents_add(sess, 1, &gids, &gidsz, f->st.gid)) {
                                 ERRX1(sess, "idents_add");                                  ERRX1("idents_add");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
Line 360 
Line 360 
                     (sess->opts->specials && (S_ISFIFO(f->st.mode) ||                      (sess->opts->specials && (S_ISFIFO(f->st.mode) ||
                     S_ISSOCK(f->st.mode)))) {                      S_ISSOCK(f->st.mode)))) {
                         if (!io_write_int(sess, fdout, f->st.rdev)) {                          if (!io_write_int(sess, fdout, f->st.rdev)) {
                                 ERRX1(sess, "io_write_int");                                  ERRX1("io_write_int");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
Line 373 
Line 373 
                         sz = strlen(f->link);                          sz = strlen(f->link);
                         assert(sz < INT32_MAX);                          assert(sz < INT32_MAX);
                         if (!io_write_int(sess, fdout, sz)) {                          if (!io_write_int(sess, fdout, sz)) {
                                 ERRX1(sess, "io_write_int");                                  ERRX1("io_write_int");
                                 goto out;                                  goto out;
                         }                          }
                         if (!io_write_buf(sess, fdout, fn, sz)) {                          if (!io_write_buf(sess, fdout, fn, sz)) {
                                 ERRX1(sess, "io_write_buf");                                  ERRX1("io_write_buf");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
Line 389 
Line 389 
         /* Signal end of file list. */          /* Signal end of file list. */
   
         if (!io_write_byte(sess, fdout, 0)) {          if (!io_write_byte(sess, fdout, 0)) {
                 ERRX1(sess, "io_write_byte");                  ERRX1("io_write_byte");
                 goto out;                  goto out;
         }          }
   
         /* Conditionally write identifier lists. */          /* Conditionally write identifier lists. */
   
         if (sess->opts->preserve_uids && !sess->opts->numeric_ids) {          if (sess->opts->preserve_uids && !sess->opts->numeric_ids) {
                 LOG2(sess, "sending uid list: %zu", uidsz);                  LOG2("sending uid list: %zu", uidsz);
                 if (!idents_send(sess, fdout, uids, uidsz)) {                  if (!idents_send(sess, fdout, uids, uidsz)) {
                         ERRX1(sess, "idents_send");                          ERRX1("idents_send");
                         goto out;                          goto out;
                 }                  }
         }          }
   
         if (sess->opts->preserve_gids && !sess->opts->numeric_ids) {          if (sess->opts->preserve_gids && !sess->opts->numeric_ids) {
                 LOG2(sess, "sending gid list: %zu", gidsz);                  LOG2("sending gid list: %zu", gidsz);
                 if (!idents_send(sess, fdout, gids, gidsz)) {                  if (!idents_send(sess, fdout, gids, gidsz)) {
                         ERRX1(sess, "idents_send");                          ERRX1("idents_send");
                         goto out;                          goto out;
                 }                  }
         }          }
Line 444 
Line 444 
   
         if (FLIST_NAME_SAME & flags) {          if (FLIST_NAME_SAME & flags) {
                 if (!io_read_byte(sess, fd, &bval)) {                  if (!io_read_byte(sess, fd, &bval)) {
                         ERRX1(sess, "io_read_byte");                          ERRX1("io_read_byte");
                         return 0;                          return 0;
                 }                  }
                 partial = bval;                  partial = bval;
Line 454 
Line 454 
   
         if (FLIST_NAME_LONG & flags) {          if (FLIST_NAME_LONG & flags) {
                 if (!io_read_size(sess, fd, &pathlen)) {                  if (!io_read_size(sess, fd, &pathlen)) {
                         ERRX1(sess, "io_read_size");                          ERRX1("io_read_size");
                         return 0;                          return 0;
                 }                  }
         } else {          } else {
                 if (!io_read_byte(sess, fd, &bval)) {                  if (!io_read_byte(sess, fd, &bval)) {
                         ERRX1(sess, "io_read_byte");                          ERRX1("io_read_byte");
                         return 0;                          return 0;
                 }                  }
                 pathlen = bval;                  pathlen = bval;
Line 469 
Line 469 
         /* FIXME: maximum pathname length. */          /* FIXME: maximum pathname length. */
   
         if ((len = pathlen + partial) == 0) {          if ((len = pathlen + partial) == 0) {
                 ERRX(sess, "security violation: zero-length pathname");                  ERRX("security violation: zero-length pathname");
                 return 0;                  return 0;
         }          }
   
         if ((f->path = malloc(len + 1)) == NULL) {          if ((f->path = malloc(len + 1)) == NULL) {
                 ERR(sess, "malloc");                  ERR("malloc");
                 return 0;                  return 0;
         }          }
         f->path[len] = '\0';          f->path[len] = '\0';
Line 483 
Line 483 
                 memcpy(f->path, last, partial);                  memcpy(f->path, last, partial);
   
         if (!io_read_buf(sess, fd, f->path + partial, pathlen)) {          if (!io_read_buf(sess, fd, f->path + partial, pathlen)) {
                 ERRX1(sess, "io_read_buf");                  ERRX1("io_read_buf");
                 return 0;                  return 0;
         }          }
   
         if (f->path[0] == '/') {          if (f->path[0] == '/') {
                 ERRX(sess, "security violation: absolute pathname: %s",                  ERRX("security violation: absolute pathname: %s",
                     f->path);                      f->path);
                 return 0;                  return 0;
         }          }
Line 497 
Line 497 
             (len > 2 && strcmp(f->path + len - 3, "/..") == 0) ||              (len > 2 && strcmp(f->path + len - 3, "/..") == 0) ||
             (len > 2 && strncmp(f->path, "../", 3) == 0) ||              (len > 2 && strncmp(f->path, "../", 3) == 0) ||
             strcmp(f->path, "..") == 0) {              strcmp(f->path, "..") == 0) {
                 ERRX(sess, "%s: security violation: backtracking pathname",                  ERRX("%s: security violation: backtracking pathname",
                     f->path);                      f->path);
                 return 0;                  return 0;
         }          }
Line 526 
Line 526 
         pp = recallocarray(*fl, *max,          pp = recallocarray(*fl, *max,
                 *max + FLIST_CHUNK_SIZE, sizeof(struct flist));                  *max + FLIST_CHUNK_SIZE, sizeof(struct flist));
         if (pp == NULL) {          if (pp == NULL) {
                 ERR(sess, "recallocarray");                  ERR("recallocarray");
                 return 0;                  return 0;
         }          }
         *fl = pp;          *fl = pp;
Line 551 
Line 551 
          */           */
   
         if ((f->path = strdup(path)) == NULL) {          if ((f->path = strdup(path)) == NULL) {
                 ERR(sess, "strdup");                  ERR("strdup");
                 return 0;                  return 0;
         }          }
   
Line 573 
Line 573 
         if (S_ISLNK(st->st_mode)) {          if (S_ISLNK(st->st_mode)) {
                 f->link = symlink_read(sess, f->path);                  f->link = symlink_read(sess, f->path);
                 if (f->link == NULL) {                  if (f->link == NULL) {
                         ERRX1(sess, "symlink_read");                          ERRX1("symlink_read");
                         return 0;                          return 0;
                 }                  }
         }          }
Line 604 
Line 604 
   
         for (;;) {          for (;;) {
                 if (!io_read_byte(sess, fd, &flag)) {                  if (!io_read_byte(sess, fd, &flag)) {
                         ERRX1(sess, "io_read_byte");                          ERRX1("io_read_byte");
                         goto out;                          goto out;
                 } else if (flag == 0)                  } else if (flag == 0)
                         break;                          break;
   
                 if (!flist_realloc(sess, &fl, &flsz, &flmax)) {                  if (!flist_realloc(sess, &fl, &flsz, &flmax)) {
                         ERRX1(sess, "flist_realloc");                          ERRX1("flist_realloc");
                         goto out;                          goto out;
                 }                  }
   
Line 620 
Line 620 
                 /* Filename first. */                  /* Filename first. */
   
                 if (!flist_recv_name(sess, fd, ff, flag, last)) {                  if (!flist_recv_name(sess, fd, ff, flag, last)) {
                         ERRX1(sess, "flist_recv_name");                          ERRX1("flist_recv_name");
                         goto out;                          goto out;
                 }                  }
   
                 /* Read the file size. */                  /* Read the file size. */
   
                 if (!io_read_long(sess, fd, &lval)) {                  if (!io_read_long(sess, fd, &lval)) {
                         ERRX1(sess, "io_read_long");                          ERRX1("io_read_long");
                         goto out;                          goto out;
                 }                  }
                 ff->st.size = lval;                  ff->st.size = lval;
Line 636 
Line 636 
   
                 if (!(FLIST_TIME_SAME & flag)) {                  if (!(FLIST_TIME_SAME & flag)) {
                         if (!io_read_uint(sess, fd, &uival)) {                          if (!io_read_uint(sess, fd, &uival)) {
                                 ERRX1(sess, "io_read_int");                                  ERRX1("io_read_int");
                                 goto out;                                  goto out;
                         }                          }
                         ff->st.mtime = uival;   /* beyond 2038 */                          ff->st.mtime = uival;   /* beyond 2038 */
                 } else if (fflast == NULL) {                  } else if (fflast == NULL) {
                         ERRX(sess, "same time without last entry");                          ERRX("same time without last entry");
                         goto out;                          goto out;
                 }  else                  }  else
                         ff->st.mtime = fflast->st.mtime;                          ff->st.mtime = fflast->st.mtime;
Line 650 
Line 650 
   
                 if (!(FLIST_MODE_SAME & flag)) {                  if (!(FLIST_MODE_SAME & flag)) {
                         if (!io_read_uint(sess, fd, &uival)) {                          if (!io_read_uint(sess, fd, &uival)) {
                                 ERRX1(sess, "io_read_int");                                  ERRX1("io_read_int");
                                 goto out;                                  goto out;
                         }                          }
                         ff->st.mode = uival;                          ff->st.mode = uival;
                 } else if (fflast == NULL) {                  } else if (fflast == NULL) {
                         ERRX(sess, "same mode without last entry");                          ERRX("same mode without last entry");
                         goto out;                          goto out;
                 } else                  } else
                         ff->st.mode = fflast->st.mode;                          ff->st.mode = fflast->st.mode;
Line 665 
Line 665 
                 if (sess->opts->preserve_uids) {                  if (sess->opts->preserve_uids) {
                         if (!(FLIST_UID_SAME & flag)) {                          if (!(FLIST_UID_SAME & flag)) {
                                 if (!io_read_uint(sess, fd, &uival)) {                                  if (!io_read_uint(sess, fd, &uival)) {
                                         ERRX1(sess, "io_read_int");                                          ERRX1("io_read_int");
                                         goto out;                                          goto out;
                                 }                                  }
                                 ff->st.uid = uival;                                  ff->st.uid = uival;
                         } else if (fflast == NULL) {                          } else if (fflast == NULL) {
                                 ERRX(sess, "same uid without last entry");                                  ERRX("same uid without last entry");
                                 goto out;                                  goto out;
                         } else                          } else
                                 ff->st.uid = fflast->st.uid;                                  ff->st.uid = fflast->st.uid;
Line 681 
Line 681 
                 if (sess->opts->preserve_gids) {                  if (sess->opts->preserve_gids) {
                         if (!(FLIST_GID_SAME & flag)) {                          if (!(FLIST_GID_SAME & flag)) {
                                 if (!io_read_uint(sess, fd, &uival)) {                                  if (!io_read_uint(sess, fd, &uival)) {
                                         ERRX1(sess, "io_read_int");                                          ERRX1("io_read_int");
                                         goto out;                                          goto out;
                                 }                                  }
                                 ff->st.gid = uival;                                  ff->st.gid = uival;
                         } else if (fflast == NULL) {                          } else if (fflast == NULL) {
                                 ERRX(sess, "same gid without last entry");                                  ERRX("same gid without last entry");
                                 goto out;                                  goto out;
                         } else                          } else
                                 ff->st.gid = fflast->st.gid;                                  ff->st.gid = fflast->st.gid;
Line 700 
Line 700 
                     S_ISSOCK(ff->st.mode)))) {                      S_ISSOCK(ff->st.mode)))) {
                         if (!(FLIST_RDEV_SAME & flag)) {                          if (!(FLIST_RDEV_SAME & flag)) {
                                 if (!io_read_int(sess, fd, &ival)) {                                  if (!io_read_int(sess, fd, &ival)) {
                                         ERRX1(sess, "io_read_int");                                          ERRX1("io_read_int");
                                         goto out;                                          goto out;
                                 }                                  }
                                 ff->st.rdev = ival;                                  ff->st.rdev = ival;
                         } else if (fflast == NULL) {                          } else if (fflast == NULL) {
                                 ERRX(sess, "same device without last entry");                                  ERRX("same device without last entry");
                                 goto out;                                  goto out;
                         } else                          } else
                                 ff->st.rdev = fflast->st.rdev;                                  ff->st.rdev = fflast->st.rdev;
Line 716 
Line 716 
                 if (S_ISLNK(ff->st.mode) &&                  if (S_ISLNK(ff->st.mode) &&
                     sess->opts->preserve_links) {                      sess->opts->preserve_links) {
                         if (!io_read_size(sess, fd, &lsz)) {                          if (!io_read_size(sess, fd, &lsz)) {
                                 ERRX1(sess, "io_read_size");                                  ERRX1("io_read_size");
                                 goto out;                                  goto out;
                         } else if (lsz == 0) {                          } else if (lsz == 0) {
                                 ERRX(sess, "empty link name");                                  ERRX("empty link name");
                                 goto out;                                  goto out;
                         }                          }
                         ff->link = calloc(lsz + 1, 1);                          ff->link = calloc(lsz + 1, 1);
                         if (ff->link == NULL) {                          if (ff->link == NULL) {
                                 ERR(sess, "calloc");                                  ERR("calloc");
                                 goto out;                                  goto out;
                         }                          }
                         if (!io_read_buf(sess, fd, ff->link, lsz)) {                          if (!io_read_buf(sess, fd, ff->link, lsz)) {
                                 ERRX1(sess, "io_read_buf");                                  ERRX1("io_read_buf");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
   
                 LOG3(sess, "%s: received file metadata: "                  LOG3("%s: received file metadata: "
                         "size %jd, mtime %jd, mode %o, rdev (%d, %d)",                          "size %jd, mtime %jd, mode %o, rdev (%d, %d)",
                         ff->path, (intmax_t)ff->st.size,                          ff->path, (intmax_t)ff->st.size,
                         (intmax_t)ff->st.mtime, ff->st.mode,                          (intmax_t)ff->st.mtime, ff->st.mode,
Line 747 
Line 747 
   
         if (sess->opts->preserve_uids && !sess->opts->numeric_ids) {          if (sess->opts->preserve_uids && !sess->opts->numeric_ids) {
                 if (!idents_recv(sess, fd, &uids, &uidsz)) {                  if (!idents_recv(sess, fd, &uids, &uidsz)) {
                         ERRX1(sess, "idents_recv");                          ERRX1("idents_recv");
                         goto out;                          goto out;
                 }                  }
                 LOG2(sess, "received uid list: %zu", uidsz);                  LOG2("received uid list: %zu", uidsz);
         }          }
   
         if (sess->opts->preserve_gids && !sess->opts->numeric_ids) {          if (sess->opts->preserve_gids && !sess->opts->numeric_ids) {
                 if (!idents_recv(sess, fd, &gids, &gidsz)) {                  if (!idents_recv(sess, fd, &gids, &gidsz)) {
                         ERRX1(sess, "idents_recv");                          ERRX1("idents_recv");
                         goto out;                          goto out;
                 }                  }
                 LOG2(sess, "received gid list: %zu", gidsz);                  LOG2("received gid list: %zu", gidsz);
         }          }
   
         /* Remember to order the received list. */          /* Remember to order the received list. */
   
         LOG2(sess, "received file metadata list: %zu", flsz);          LOG2("received file metadata list: %zu", flsz);
         qsort(fl, flsz, sizeof(struct flist), flist_cmp);          qsort(fl, flsz, sizeof(struct flist), flist_cmp);
         flist_topdirs(sess, fl, flsz);          flist_topdirs(sess, fl, flsz);
         *sz = flsz;          *sz = flsz;
Line 821 
Line 821 
          */           */
   
         if (lstat(root, &st) == -1) {          if (lstat(root, &st) == -1) {
                 ERR(sess, "%s: lstat", root);                  ERR("%s: lstat", root);
                 return 0;                  return 0;
         } else if (S_ISREG(st.st_mode)) {          } else if (S_ISREG(st.st_mode)) {
                 if (!flist_realloc(sess, fl, sz, max)) {                  if (!flist_realloc(sess, fl, sz, max)) {
                         ERRX1(sess, "flist_realloc");                          ERRX1("flist_realloc");
                         return 0;                          return 0;
                 }                  }
                 f = &(*fl)[(*sz) - 1];                  f = &(*fl)[(*sz) - 1];
                 assert(f != NULL);                  assert(f != NULL);
   
                 if (!flist_append(sess, f, &st, root)) {                  if (!flist_append(sess, f, &st, root)) {
                         ERRX1(sess, "flist_append");                          ERRX1("flist_append");
                         return 0;                          return 0;
                 }                  }
                 if (unveil(root, "r") == -1) {                  if (unveil(root, "r") == -1) {
                         ERR(sess, "%s: unveil", root);                          ERR("%s: unveil", root);
                         return 0;                          return 0;
                 }                  }
                 return 1;                  return 1;
         } else if (S_ISLNK(st.st_mode)) {          } else if (S_ISLNK(st.st_mode)) {
                 if (!sess->opts->preserve_links) {                  if (!sess->opts->preserve_links) {
                         WARNX(sess, "%s: skipping symlink", root);                          WARNX("%s: skipping symlink", root);
                         return 1;                          return 1;
                 } else if (!flist_realloc(sess, fl, sz, max)) {                  } else if (!flist_realloc(sess, fl, sz, max)) {
                         ERRX1(sess, "flist_realloc");                          ERRX1("flist_realloc");
                         return 0;                          return 0;
                 }                  }
                 f = &(*fl)[(*sz) - 1];                  f = &(*fl)[(*sz) - 1];
                 assert(f != NULL);                  assert(f != NULL);
   
                 if (!flist_append(sess, f, &st, root)) {                  if (!flist_append(sess, f, &st, root)) {
                         ERRX1(sess, "flist_append");                          ERRX1("flist_append");
                         return 0;                          return 0;
                 }                  }
                 if (unveil(root, "r") == -1) {                  if (unveil(root, "r") == -1) {
                         ERR(sess, "%s: unveil", root);                          ERR("%s: unveil", root);
                         return 0;                          return 0;
                 }                  }
                 return 1;                  return 1;
         } else if (!S_ISDIR(st.st_mode)) {          } else if (!S_ISDIR(st.st_mode)) {
                 WARNX(sess, "%s: skipping special", root);                  WARNX("%s: skipping special", root);
                 return 1;                  return 1;
         }          }
   
Line 894 
Line 894 
          */           */
   
         if ((fts = fts_open(cargv, FTS_PHYSICAL, NULL)) == NULL) {          if ((fts = fts_open(cargv, FTS_PHYSICAL, NULL)) == NULL) {
                 ERR(sess, "fts_open");                  ERR("fts_open");
                 return 0;                  return 0;
         }          }
   
Line 910 
Line 910 
                 assert(ent->fts_statp != NULL);                  assert(ent->fts_statp != NULL);
                 if (S_ISLNK(ent->fts_statp->st_mode) &&                  if (S_ISLNK(ent->fts_statp->st_mode) &&
                     !sess->opts->preserve_links) {                      !sess->opts->preserve_links) {
                         WARNX(sess, "%s: skipping symlink", ent->fts_path);                          WARNX("%s: skipping symlink", ent->fts_path);
                         continue;                          continue;
                 }                  }
   
Line 933 
Line 933 
                                 continue;                                  continue;
   
                         if ((xdev = malloc(sizeof(dev_t))) == NULL) {                          if ((xdev = malloc(sizeof(dev_t))) == NULL) {
                                 ERRX1(sess, "malloc");                                  ERRX1("malloc");
                                 goto out;                                  goto out;
                         }                          }
   
Line 949 
Line 949 
                         if (nxdev)                          if (nxdev)
                                 if ((xdev = realloc(xdev, sizeof(dev_t))) ==                                  if ((xdev = realloc(xdev, sizeof(dev_t))) ==
                                     NULL) {                                      NULL) {
                                         ERRX1(sess, "realloc");                                          ERRX1("realloc");
                                         goto out;                                          goto out;
                                 }                                  }
                         xdev[nxdev] = ent->fts_statp->st_dev;                          xdev[nxdev] = ent->fts_statp->st_dev;
Line 959 
Line 959 
                 /* Allocate a new file entry. */                  /* Allocate a new file entry. */
   
                 if (!flist_realloc(sess, fl, sz, max)) {                  if (!flist_realloc(sess, fl, sz, max)) {
                         ERRX1(sess, "flist_realloc");                          ERRX1("flist_realloc");
                         goto out;                          goto out;
                 }                  }
                 flsz++;                  flsz++;
Line 969 
Line 969 
   
                 if (ent->fts_path[stripdir] == '\0') {                  if (ent->fts_path[stripdir] == '\0') {
                         if (asprintf(&f->path, "%s.", ent->fts_path) < 0) {                          if (asprintf(&f->path, "%s.", ent->fts_path) < 0) {
                                 ERR(sess, "asprintf");                                  ERR("asprintf");
                                 f->path = NULL;                                  f->path = NULL;
                                 goto out;                                  goto out;
                         }                          }
                 } else {                  } else {
                         if ((f->path = strdup(ent->fts_path)) == NULL) {                          if ((f->path = strdup(ent->fts_path)) == NULL) {
                                 ERR(sess, "strdup");                                  ERR("strdup");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
Line 988 
Line 988 
                 if (S_ISLNK(ent->fts_statp->st_mode)) {                  if (S_ISLNK(ent->fts_statp->st_mode)) {
                         f->link = symlink_read(sess, f->path);                          f->link = symlink_read(sess, f->path);
                         if (f->link == NULL) {                          if (f->link == NULL) {
                                 ERRX1(sess, "symlink_read");                                  ERRX1("symlink_read");
                                 goto out;                                  goto out;
                         }                          }
                 }                  }
Line 997 
Line 997 
                 errno = 0;                  errno = 0;
         }          }
         if (errno) {          if (errno) {
                 ERR(sess, "fts_read");                  ERR("fts_read");
                 goto out;                  goto out;
         }          }
         if (unveil(root, "r") == -1) {          if (unveil(root, "r") == -1) {
                 ERR(sess, "%s: unveil", root);                  ERR("%s: unveil", root);
                 goto out;                  goto out;
         }          }
   
         LOG3(sess, "generated %zu filenames: %s", flsz, root);          LOG3("generated %zu filenames: %s", flsz, root);
         rc = 1;          rc = 1;
 out:  out:
         fts_close(fts);          fts_close(fts);
Line 1032 
Line 1032 
                         break;                          break;
   
         if (i == argc) {          if (i == argc) {
                 LOG2(sess, "recursively generated %zu filenames", *sz);                  LOG2("recursively generated %zu filenames", *sz);
                 return 1;                  return 1;
         }          }
   
         ERRX1(sess, "flist_gen_dirent");          ERRX1("flist_gen_dirent");
         flist_free(*flp, max);          flist_free(*flp, max);
         *flp = NULL;          *flp = NULL;
         *sz = 0;          *sz = 0;
Line 1060 
Line 1060 
         assert(argc);          assert(argc);
   
         if ((fl = calloc(argc, sizeof(struct flist))) == NULL) {          if ((fl = calloc(argc, sizeof(struct flist))) == NULL) {
                 ERR(sess, "calloc");                  ERR("calloc");
                 return 0;                  return 0;
         }          }
   
Line 1068 
Line 1068 
                 if (argv[i][0] == '\0')                  if (argv[i][0] == '\0')
                         continue;                          continue;
                 if (lstat(argv[i], &st) == -1) {                  if (lstat(argv[i], &st) == -1) {
                         ERR(sess, "%s: lstat", argv[i]);                          ERR("%s: lstat", argv[i]);
                         goto out;                          goto out;
                 }                  }
   
Line 1080 
Line 1080 
                  */                   */
   
                 if (S_ISDIR(st.st_mode)) {                  if (S_ISDIR(st.st_mode)) {
                         WARNX(sess, "%s: skipping directory", argv[i]);                          WARNX("%s: skipping directory", argv[i]);
                         continue;                          continue;
                 } else if (S_ISLNK(st.st_mode)) {                  } else if (S_ISLNK(st.st_mode)) {
                         if (!sess->opts->preserve_links) {                          if (!sess->opts->preserve_links) {
                                 WARNX(sess, "%s: skipping symlink", argv[i]);                                  WARNX("%s: skipping symlink", argv[i]);
                                 continue;                                  continue;
                         }                          }
                 } else if (!S_ISREG(st.st_mode)) {                  } else if (!S_ISREG(st.st_mode)) {
                         WARNX(sess, "%s: skipping special", argv[i]);                          WARNX("%s: skipping special", argv[i]);
                         continue;                          continue;
                 }                  }
   
Line 1099 
Line 1099 
                 /* Add this file to our file-system worldview. */                  /* Add this file to our file-system worldview. */
   
                 if (unveil(argv[i], "r") == -1) {                  if (unveil(argv[i], "r") == -1) {
                         ERR(sess, "%s: unveil", argv[i]);                          ERR("%s: unveil", argv[i]);
                         goto out;                          goto out;
                 }                  }
                 if (!flist_append(sess, f, &st, argv[i])) {                  if (!flist_append(sess, f, &st, argv[i])) {
                         ERRX1(sess, "flist_append");                          ERRX1("flist_append");
                         goto out;                          goto out;
                 }                  }
         }          }
   
         LOG2(sess, "non-recursively generated %zu filenames", flsz);          LOG2("non-recursively generated %zu filenames", flsz);
         *sz = flsz;          *sz = flsz;
         *flp = fl;          *flp = fl;
         return 1;          return 1;
Line 1141 
Line 1141 
         /* After scanning, lock our file-system view. */          /* After scanning, lock our file-system view. */
   
         if (unveil(NULL, NULL) == -1) {          if (unveil(NULL, NULL) == -1) {
                 ERR(sess, "unveil");                  ERR("unveil");
                 return 0;                  return 0;
         }          }
         if (!rc)          if (!rc)
Line 1154 
Line 1154 
                 return 1;                  return 1;
         }          }
   
         ERRX1(sess, "flist_dedupe");          ERRX1("flist_dedupe");
         flist_free(*flp, *sz);          flist_free(*flp, *sz);
         *flp = NULL;          *flp = NULL;
         *sz = 0;          *sz = 0;
Line 1206 
Line 1206 
                 return 1;                  return 1;
   
         if ((cargv = calloc(cargvs + 1, sizeof(char *))) == NULL) {          if ((cargv = calloc(cargvs + 1, sizeof(char *))) == NULL) {
                 ERR(sess, "calloc");                  ERR("calloc");
                 return 0;                  return 0;
         }          }
   
Line 1221 
Line 1221 
                 assert(cargvs == 1);                  assert(cargvs == 1);
                 assert(S_ISDIR(wfl[0].st.mode));                  assert(S_ISDIR(wfl[0].st.mode));
                 if (asprintf(&cargv[0], "%s/", root) < 0) {                  if (asprintf(&cargv[0], "%s/", root) < 0) {
                         ERR(sess, "asprintf");                          ERR("asprintf");
                         cargv[0] = NULL;                          cargv[0] = NULL;
                         goto out;                          goto out;
                 }                  }
Line 1234 
Line 1234 
                         assert(strcmp(wfl[i].wpath, "."));                          assert(strcmp(wfl[i].wpath, "."));
                         c = asprintf(&cargv[j], "%s/%s", root, wfl[i].wpath);                          c = asprintf(&cargv[j], "%s/%s", root, wfl[i].wpath);
                         if (c < 0) {                          if (c < 0) {
                                 ERR(sess, "asprintf");                                  ERR("asprintf");
                                 cargv[j] = NULL;                                  cargv[j] = NULL;
                                 goto out;                                  goto out;
                         }                          }
                         LOG4(sess, "%s: will scan for deletions", cargv[j]);                          LOG4("%s: will scan for deletions", cargv[j]);
                         j++;                          j++;
                 }                  }
                 assert(j == cargvs);                  assert(j == cargvs);
                 cargv[j] = NULL;                  cargv[j] = NULL;
         }          }
   
         LOG2(sess, "delete from %zu directories", cargvs);          LOG2("delete from %zu directories", cargvs);
   
         /*          /*
          * Next, use the standard hcreate(3) hashtable interface to hash           * Next, use the standard hcreate(3) hashtable interface to hash
Line 1257 
Line 1257 
          */           */
   
         if (!hcreate(wflsz)) {          if (!hcreate(wflsz)) {
                 ERR(sess, "hcreate");                  ERR("hcreate");
                 goto out;                  goto out;
         }          }
   
         for (i = 0; i < wflsz; i++) {          for (i = 0; i < wflsz; i++) {
                 memset(&hent, 0, sizeof(ENTRY));                  memset(&hent, 0, sizeof(ENTRY));
                 if ((hent.key = strdup(wfl[i].wpath)) == NULL) {                  if ((hent.key = strdup(wfl[i].wpath)) == NULL) {
                         ERR(sess, "strdup");                          ERR("strdup");
                         goto out;                          goto out;
                 }                  }
                 if ((hentp = hsearch(hent, ENTER)) == NULL) {                  if ((hentp = hsearch(hent, ENTER)) == NULL) {
                         ERR(sess, "hsearch");                          ERR("hsearch");
                         goto out;                          goto out;
                 } else if (hentp->key != hent.key) {                  } else if (hentp->key != hent.key) {
                         ERRX(sess, "%s: duplicate", wfl[i].wpath);                          ERRX("%s: duplicate", wfl[i].wpath);
                         free(hent.key);                          free(hent.key);
                         goto out;                          goto out;
                 }                  }
Line 1284 
Line 1284 
          */           */
   
         if ((fts = fts_open(cargv, FTS_PHYSICAL, NULL)) == NULL) {          if ((fts = fts_open(cargv, FTS_PHYSICAL, NULL)) == NULL) {
                 ERR(sess, "fts_open");                  ERR("fts_open");
                 goto out;                  goto out;
         }          }
   
Line 1312 
Line 1312 
                         flag = 0;                          flag = 0;
                         for (i = 0; i < wflsz; i++) {                          for (i = 0; i < wflsz; i++) {
                                 if (stat(wfl[i].path, &st) == -1) {                                  if (stat(wfl[i].path, &st) == -1) {
                                         ERR(sess, "%s: stat", wfl[i].path);                                          ERR("%s: stat", wfl[i].path);
                                         goto out;                                          goto out;
                                 }                                  }
                                 if (ent->fts_statp->st_dev == st.st_dev) {                                  if (ent->fts_statp->st_dev == st.st_dev) {
Line 1334 
Line 1334 
                 /* Not found: we'll delete it. */                  /* Not found: we'll delete it. */
   
                 if (!flist_realloc(sess, fl, sz, &max)) {                  if (!flist_realloc(sess, fl, sz, &max)) {
                         ERRX1(sess, "flist_realloc");                          ERRX1("flist_realloc");
                         goto out;                          goto out;
                 }                  }
                 f = &(*fl)[*sz - 1];                  f = &(*fl)[*sz - 1];
   
                 if ((f->path = strdup(ent->fts_path)) == NULL) {                  if ((f->path = strdup(ent->fts_path)) == NULL) {
                         ERR(sess, "strdup");                          ERR("strdup");
                         goto out;                          goto out;
                 }                  }
                 f->wpath = f->path + stripdir;                  f->wpath = f->path + stripdir;
Line 1349 
Line 1349 
         }          }
   
         if (errno) {          if (errno) {
                 ERR(sess, "fts_read");                  ERR("fts_read");
                 goto out;                  goto out;
         }          }
   
Line 1384 
Line 1384 
         assert(sess->opts->recursive);          assert(sess->opts->recursive);
   
         for (i = flsz - 1; i >= 0; i--) {          for (i = flsz - 1; i >= 0; i--) {
                 LOG1(sess, "%s: deleting", fl[i].wpath);                  LOG1("%s: deleting", fl[i].wpath);
                 if (sess->opts->dry_run)                  if (sess->opts->dry_run)
                         continue;                          continue;
                 assert(root != -1);                  assert(root != -1);
                 flag = S_ISDIR(fl[i].st.mode) ? AT_REMOVEDIR : 0;                  flag = S_ISDIR(fl[i].st.mode) ? AT_REMOVEDIR : 0;
                 if (unlinkat(root, fl[i].wpath, flag) == -1 &&                  if (unlinkat(root, fl[i].wpath, flag) == -1 &&
                     errno != ENOENT) {                      errno != ENOENT) {
                         ERR(sess, "%s: unlinkat", fl[i].wpath);                          ERR("%s: unlinkat", fl[i].wpath);
                         return 0;                          return 0;
                 }                  }
         }          }

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25