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

Diff for /src/usr.bin/rsync/downloader.c between version 1.1 and 1.2

version 1.1, 2019/02/10 23:18:28 version 1.2, 2019/02/10 23:24:14
Line 51 
Line 51 
  */   */
 struct  download {  struct  download {
         enum downloadst     state; /* state of affairs */          enum downloadst     state; /* state of affairs */
         size_t              idx; /* index of current file */          size_t              idx; /* index of current file */
         struct blkset       blk; /* its blocks */          struct blkset       blk; /* its blocks */
         void               *map; /* mmap of current file */          void               *map; /* mmap of current file */
         size_t              mapsz; /* length of mapsz */          size_t              mapsz; /* length of mapsz */
         int                 ofd; /* open origin file */          int                 ofd; /* open origin file */
         int                 fd; /* open output file */          int                 fd; /* open output file */
         char               *fname; /* output filename */          char               *fname; /* output filename */
         MD4_CTX             ctx; /* current hashing context */          MD4_CTX             ctx; /* current hashing context */
         off_t               downloaded; /* total downloaded */          off_t               downloaded; /* total downloaded */
         off_t               total; /* total in file */          off_t               total; /* total in file */
         const struct flist *fl; /* file list */          const struct flist *fl; /* file list */
Line 75 
Line 75 
  * Simply log the filename.   * Simply log the filename.
  */   */
 static void  static void
 log_file(struct sess *sess,  log_file(struct sess *sess,
         const struct download *dl, const struct flist *f)          const struct download *dl, const struct flist *f)
 {  {
         float            frac, tot = dl->total;          float            frac, tot = dl->total;
Line 85 
Line 85 
         if (sess->opts->server)          if (sess->opts->server)
                 return;                  return;
   
         frac = 0 == dl->total ? 100.0 :          frac = 0 == dl->total ? 100.0 :
                 100.0 * dl->downloaded / dl->total;                  100.0 * dl->downloaded / dl->total;
   
         if (dl->total > 1024 * 1024 * 1024) {          if (dl->total > 1024 * 1024 * 1024) {
Line 102 
Line 102 
                 unit = "KB";                  unit = "KB";
         }          }
   
         LOG1(sess, "%s (%.*f %s, %.1f%% downloaded)",          LOG1(sess, "%s (%.*f %s, %.1f%% downloaded)",
                 f->path, prec, tot, unit, frac);                  f->path, prec, tot, unit, frac);
 }  }
   
Line 155 
Line 155 
         }          }
         if (-1 != p->fd) {          if (-1 != p->fd) {
                 close(p->fd);                  close(p->fd);
                 if (cleanup && NULL != p->fname)                  if (cleanup && NULL != p->fname)
                         unlinkat(p->rootfd, p->fname, 0);                          unlinkat(p->rootfd, p->fname, 0);
                 p->fd = -1;                  p->fd = -1;
         }          }
Line 171 
Line 171 
  * On success, download_free() must be called with the pointer.   * On success, download_free() must be called with the pointer.
  */   */
 struct download *  struct download *
 download_alloc(struct sess *sess, int fdin,  download_alloc(struct sess *sess, int fdin,
         const struct flist *fl, size_t flsz, int rootfd)          const struct flist *fl, size_t flsz, int rootfd)
 {  {
         struct download *p;          struct download *p;
Line 191 
Line 191 
         p->obuf = NULL;          p->obuf = NULL;
         p->obufmax = OBUF_SIZE;          p->obufmax = OBUF_SIZE;
         if (p->obufmax &&          if (p->obufmax &&
             NULL == (p->obuf = malloc(p->obufmax))) {              NULL == (p->obuf = malloc(p->obufmax))) {
                 ERR(sess, "malloc");                  ERR(sess, "malloc");
                 free(p);                  free(p);
                 return NULL;                  return NULL;
Line 223 
Line 223 
  * Returns zero on failure, non-zero on success.   * Returns zero on failure, non-zero on success.
  */   */
 static int  static int
 buf_copy(struct sess *sess,  buf_copy(struct sess *sess,
         const char *buf, size_t sz, struct download *p)          const char *buf, size_t sz, struct download *p)
 {  {
         size_t   rem, tocopy;          size_t   rem, tocopy;
Line 231 
Line 231 
   
         assert(p->obufsz <= p->obufmax);          assert(p->obufsz <= p->obufmax);
   
         /*          /*
          * Copy as much as we can.           * Copy as much as we can.
          * If we've copied everything, exit.           * If we've copied everything, exit.
          * If we have no pre-write buffer (obufmax of zero), this never           * If we have no pre-write buffer (obufmax of zero), this never
Line 268 
Line 268 
                 p->obufsz = 0;                  p->obufsz = 0;
         }          }
   
         /*          /*
          * Now drain anything left.           * Now drain anything left.
          * If we have no pre-write buffer, this is it.           * If we have no pre-write buffer, this is it.
          */           */
Line 302 
Line 302 
         size_t           sz, dirlen, tok;          size_t           sz, dirlen, tok;
         const char      *cp;          const char      *cp;
         mode_t           perm;          mode_t           perm;
         struct stat      st;          struct stat      st;
         char            *buf = NULL;          char            *buf = NULL;
         unsigned char    ourmd[MD4_DIGEST_LENGTH],          unsigned char    ourmd[MD4_DIGEST_LENGTH],
                          md[MD4_DIGEST_LENGTH];                           md[MD4_DIGEST_LENGTH];
         struct timespec  tv[2];          struct timespec  tv[2];
   
Line 332 
Line 332 
                 if (sess->opts->dry_run)                  if (sess->opts->dry_run)
                         return 1;                          return 1;
   
                 /*                  /*
                  * Now get our block information.                   * Now get our block information.
                  * This is all we'll need to reconstruct the file from                   * This is all we'll need to reconstruct the file from
                  * the map, as block sizes are regular.                   * the map, as block sizes are regular.
Line 344 
Line 344 
                         goto out;                          goto out;
                 }                  }
   
                 /*                  /*
                  * Next, we want to open the existing file for using as                   * Next, we want to open the existing file for using as
                  * block input.                   * block input.
                  * We do this in a non-blocking way, so if the open                   * We do this in a non-blocking way, so if the open
Line 355 
Line 355 
   
                 p->state = DOWNLOAD_READ_LOCAL;                  p->state = DOWNLOAD_READ_LOCAL;
                 f = &p->fl[idx];                  f = &p->fl[idx];
                 p->ofd = openat(p->rootfd, f->path,                  p->ofd = openat(p->rootfd, f->path,
                         O_RDONLY | O_NONBLOCK, 0);                          O_RDONLY | O_NONBLOCK, 0);
   
                 if (-1 == p->ofd && ENOENT != errno) {                  if (-1 == p->ofd && ENOENT != errno) {
Line 388 
Line 388 
         if (DOWNLOAD_READ_LOCAL == p->state) {          if (DOWNLOAD_READ_LOCAL == p->state) {
                 assert(NULL == p->fname);                  assert(NULL == p->fname);
   
                 /*                  /*
                  * Try to fstat() the file descriptor if valid and make                   * Try to fstat() the file descriptor if valid and make
                  * sure that we're still a regular file.                   * sure that we're still a regular file.
                  * Then, if it has non-zero size, mmap() it for hashing.                   * Then, if it has non-zero size, mmap() it for hashing.
Line 405 
Line 405 
   
                 if (-1 != p->ofd && st.st_size > 0) {                  if (-1 != p->ofd && st.st_size > 0) {
                         p->mapsz = st.st_size;                          p->mapsz = st.st_size;
                         p->map = mmap(NULL, p->mapsz,                          p->map = mmap(NULL, p->mapsz,
                                 PROT_READ, MAP_SHARED, p->ofd, 0);                                  PROT_READ, MAP_SHARED, p->ofd, 0);
                         if (MAP_FAILED == p->map) {                          if (MAP_FAILED == p->map) {
                                 ERR(sess, "%s: mmap", f->path);                                  ERR(sess, "%s: mmap", f->path);
Line 417 
Line 417 
   
                 *ofd = -1;                  *ofd = -1;
   
                 /*                  /*
                  * Create the temporary file.                   * Create the temporary file.
                  * Use a simple scheme of path/.FILE.RANDOM, where we                   * Use a simple scheme of path/.FILE.RANDOM, where we
                  * fill in RANDOM with an arc4random number.                   * fill in RANDOM with an arc4random number.
Line 434 
Line 434 
                             f->path + dirlen + 1, hash) < 0)                              f->path + dirlen + 1, hash) < 0)
                                 p->fname = NULL;                                  p->fname = NULL;
                 } else {                  } else {
                         if (asprintf(&p->fname, ".%s.%" PRIu32,                          if (asprintf(&p->fname, ".%s.%" PRIu32,
                             f->path, hash) < 0)                              f->path, hash) < 0)
                                 p->fname = NULL;                                  p->fname = NULL;
                 }                  }
Line 443 
Line 443 
                         goto out;                          goto out;
                 }                  }
   
                 /*                  /*
                  * Inherit permissions from the source file if we're new                   * Inherit permissions from the source file if we're new
                  * or specifically told with -p.                   * or specifically told with -p.
                  */                   */
Line 453 
Line 453 
                 else                  else
                         perm = f->st.mode;                          perm = f->st.mode;
   
                 p->fd = openat(p->rootfd, p->fname,                  p->fd = openat(p->rootfd, p->fname,
                         O_APPEND|O_WRONLY|O_CREAT|O_EXCL, perm);                          O_APPEND|O_WRONLY|O_CREAT|O_EXCL, perm);
   
                 if (-1 == p->fd) {                  if (-1 == p->fd) {
Line 461 
Line 461 
                         goto out;                          goto out;
                 }                  }
   
                 /*                  /*
                  * FIXME: we can technically wait until the temporary                   * FIXME: we can technically wait until the temporary
                  * file is writable, but since it's guaranteed to be                   * file is writable, but since it's guaranteed to be
                  * empty, I don't think this is a terribly expensive                   * empty, I don't think this is a terribly expensive
Line 491 
Line 491 
         if ( ! io_read_int(sess, p->fdin, &rawtok)) {          if ( ! io_read_int(sess, p->fdin, &rawtok)) {
                 ERRX1(sess, "io_read_int");                  ERRX1(sess, "io_read_int");
                 goto out;                  goto out;
         }          }
   
         if (rawtok > 0) {          if (rawtok > 0) {
                 sz = rawtok;                  sz = rawtok;
Line 516 
Line 516 
                 tok = -rawtok - 1;                  tok = -rawtok - 1;
                 if (tok >= p->blk.blksz) {                  if (tok >= p->blk.blksz) {
                         ERRX(sess, "%s: token not in block "                          ERRX(sess, "%s: token not in block "
                                 "set: %zu (have %zu blocks)",                                  "set: %zu (have %zu blocks)",
                                 p->fname, tok, p->blk.blksz);                                  p->fname, tok, p->blk.blksz);
                         goto out;                          goto out;
                 }                  }
Line 552 
Line 552 
         assert(0 == rawtok);          assert(0 == rawtok);
         assert(0 == p->obufsz);          assert(0 == p->obufsz);
   
         /*          /*
          * Make sure our resulting MD4 hashes match.           * Make sure our resulting MD4 hashes match.
          * FIXME: if the MD4 hashes don't match, then our file has           * FIXME: if the MD4 hashes don't match, then our file has
          * changed out from under us.           * changed out from under us.

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2