xref: /openbsd-src/usr.bin/rsync/uploader.c (revision 24bb5fcea3ed904bc467217bdaadb5dfc618d5bf)
1 /*	$OpenBSD: uploader.c,v 1.29 2021/06/30 13:10:04 claudio Exp $ */
2 /*
3  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
4  * Copyright (c) 2019 Florian Obser <florian@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #include <sys/mman.h>
19 #include <sys/stat.h>
20 
21 #include <assert.h>
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <inttypes.h>
25 #include <math.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
30 #include <unistd.h>
31 
32 #include "extern.h"
33 
34 enum	uploadst {
35 	UPLOAD_FIND_NEXT = 0, /* find next to upload to sender */
36 	UPLOAD_WRITE, /* wait to write to sender */
37 	UPLOAD_FINISHED /* nothing more to do in phase */
38 };
39 
40 /*
41  * Used to keep track of data flowing from the receiver to the sender.
42  * This is managed by the receiver process.
43  */
44 struct	upload {
45 	enum uploadst	    state;
46 	char		   *buf; /* if not NULL, pending upload */
47 	size_t		    bufsz; /* size of buf */
48 	size_t		    bufmax; /* maximum size of buf */
49 	size_t		    bufpos; /* position in buf */
50 	size_t		    idx; /* current transfer index */
51 	mode_t		    oumask; /* umask for creating files */
52 	char		   *root; /* destination directory path */
53 	int		    rootfd; /* destination directory */
54 	size_t		    csumlen; /* checksum length */
55 	int		    fdout; /* write descriptor to sender */
56 	const struct flist *fl; /* file list */
57 	size_t		    flsz; /* size of file list */
58 	int		   *newdir; /* non-zero if mkdir'd */
59 };
60 
61 /*
62  * Log a directory by emitting the file and a trailing slash, just to
63  * show the operator that we're a directory.
64  */
65 static void
66 log_dir(struct sess *sess, const struct flist *f)
67 {
68 	size_t	 sz;
69 
70 	if (sess->opts->server)
71 		return;
72 	sz = strlen(f->path);
73 	assert(sz > 0);
74 	LOG1("%s%s", f->path, (f->path[sz - 1] == '/') ? "" : "/");
75 }
76 
77 /*
78  * Log a link by emitting the file and the target, just to show the
79  * operator that we're a link.
80  */
81 static void
82 log_symlink(struct sess *sess, const struct flist *f)
83 {
84 
85 	if (!sess->opts->server)
86 		LOG1("%s -> %s", f->path, f->link);
87 }
88 
89 /*
90  * Simply log the filename.
91  */
92 static void
93 log_file(struct sess *sess, const struct flist *f)
94 {
95 
96 	if (!sess->opts->server)
97 		LOG1("%s", f->path);
98 }
99 
100 /*
101  * Prepare the overall block set's metadata.
102  * We always have at least one block.
103  * The block size is an important part of the algorithm.
104  * I use the same heuristic as the reference rsync, but implemented in a
105  * bit more of a straightforward way.
106  * In general, the individual block length is the rounded square root of
107  * the total file size.
108  * The minimum block length is 700.
109  */
110 static void
111 init_blkset(struct blkset *p, off_t sz)
112 {
113 	double	 v;
114 
115 	if (sz >= (BLOCK_SIZE_MIN * BLOCK_SIZE_MIN)) {
116 		/* Simple rounded-up integer square root. */
117 
118 		v = sqrt(sz);
119 		p->len = ceil(v);
120 
121 		/*
122 		 * Always be a multiple of eight.
123 		 * There's no reason to do this, but rsync does.
124 		 */
125 
126 		if ((p->len % 8) > 0)
127 			p->len += 8 - (p->len % 8);
128 	} else
129 		p->len = BLOCK_SIZE_MIN;
130 
131 	p->size = sz;
132 	if ((p->blksz = sz / p->len) == 0)
133 		p->rem = sz;
134 	else
135 		p->rem = sz % p->len;
136 
137 	/* If we have a remainder, then we need an extra block. */
138 
139 	if (p->rem)
140 		p->blksz++;
141 }
142 
143 /*
144  * For each block, prepare the block's metadata.
145  * We use the mapped "map" file to set our checksums.
146  */
147 static void
148 init_blk(struct blk *p, const struct blkset *set, off_t offs,
149 	size_t idx, const void *map, const struct sess *sess)
150 {
151 
152 	p->idx = idx;
153 	/* Block length inherits for all but the last. */
154 	p->len = idx < set->blksz - 1 ? set->len : set->rem;
155 	p->offs = offs;
156 
157 	p->chksum_short = hash_fast(map, p->len);
158 	hash_slow(map, p->len, p->chksum_long, sess);
159 }
160 
161 /*
162  * Handle a symbolic link.
163  * If we encounter directories existing in the symbolic link's place,
164  * then try to unlink the directory.
165  * Otherwise, simply overwrite with the symbolic link by renaming.
166  * Return <0 on failure 0 on success.
167  */
168 static int
169 pre_link(struct upload *p, struct sess *sess)
170 {
171 	struct stat		 st;
172 	const struct flist	*f;
173 	int			 rc, newlink = 0, updatelink = 0;
174 	char			*b, *temp = NULL;
175 
176 	f = &p->fl[p->idx];
177 	assert(S_ISLNK(f->st.mode));
178 
179 	if (!sess->opts->preserve_links) {
180 		WARNX("%s: ignoring symlink", f->path);
181 		return 0;
182 	}
183 	if (sess->opts->dry_run) {
184 		log_symlink(sess, f);
185 		return 0;
186 	}
187 
188 	/*
189 	 * See if the symlink already exists.
190 	 * If it's a directory, then try to unlink the directory prior
191 	 * to overwriting with a symbolic link.
192 	 * If it's a non-directory, we just overwrite it.
193 	 */
194 
195 	assert(p->rootfd != -1);
196 	rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
197 
198 	if (rc == -1 && errno != ENOENT) {
199 		ERR("%s: fstatat", f->path);
200 		return -1;
201 	}
202 	if (rc != -1 && !S_ISLNK(st.st_mode)) {
203 		if (S_ISDIR(st.st_mode) &&
204 		    unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
205 			ERR("%s: unlinkat", f->path);
206 			return -1;
207 		}
208 		rc = -1;
209 	}
210 
211 	/*
212 	 * If the symbolic link already exists, then make sure that it
213 	 * points to the correct place.
214 	 */
215 
216 	if (rc != -1) {
217 		b = symlinkat_read(p->rootfd, f->path);
218 		if (b == NULL) {
219 			ERRX1("symlinkat_read");
220 			return -1;
221 		}
222 		if (strcmp(f->link, b)) {
223 			free(b);
224 			b = NULL;
225 			LOG3("%s: updating symlink: %s", f->path, f->link);
226 			updatelink = 1;
227 		}
228 		free(b);
229 		b = NULL;
230 	}
231 
232 	/*
233 	 * Create the temporary file as a symbolic link, then rename the
234 	 * temporary file as the real one, overwriting anything there.
235 	 */
236 
237 	if (rc == -1 || updatelink) {
238 		LOG3("%s: creating symlink: %s", f->path, f->link);
239 		if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {
240 			ERRX1("mktemplate");
241 			return -1;
242 		}
243 		if (mkstemplinkat(f->link, p->rootfd, temp) == NULL) {
244 			ERR("mkstemplinkat");
245 			free(temp);
246 			return -1;
247 		}
248 		newlink = 1;
249 	}
250 
251 	rsync_set_metadata_at(sess, newlink,
252 		p->rootfd, f, newlink ? temp : f->path);
253 
254 	if (newlink) {
255 		if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
256 			ERR("%s: renameat %s", temp, f->path);
257 			(void)unlinkat(p->rootfd, temp, 0);
258 			free(temp);
259 			return -1;
260 		}
261 		free(temp);
262 	}
263 
264 	log_symlink(sess, f);
265 	return 0;
266 }
267 
268 /*
269  * See pre_link(), but for devices.
270  * FIXME: this is very similar to the other pre_xxx() functions.
271  * Return <0 on failure 0 on success.
272  */
273 static int
274 pre_dev(struct upload *p, struct sess *sess)
275 {
276 	struct stat		 st;
277 	const struct flist	*f;
278 	int			 rc, newdev = 0, updatedev = 0;
279 	char			*temp = NULL;
280 
281 	f = &p->fl[p->idx];
282 	assert(S_ISBLK(f->st.mode) || S_ISCHR(f->st.mode));
283 
284 	if (!sess->opts->devices || getuid() != 0) {
285 		WARNX("skipping non-regular file %s", f->path);
286 		return 0;
287 	}
288 	if (sess->opts->dry_run) {
289 		log_file(sess, f);
290 		return 0;
291 	}
292 
293 	/*
294 	 * See if the dev already exists.
295 	 * If a non-device exists in its place, we'll replace that.
296 	 * If it replaces a directory, remove the directory first.
297 	 */
298 
299 	assert(p->rootfd != -1);
300 	rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
301 
302 	if (rc == -1 && errno != ENOENT) {
303 		ERR("%s: fstatat", f->path);
304 		return -1;
305 	}
306 	if (rc != -1 && !(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))) {
307 		if (S_ISDIR(st.st_mode) &&
308 		    unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
309 			ERR("%s: unlinkat", f->path);
310 			return -1;
311 		}
312 		rc = -1;
313 	}
314 
315 	/* Make sure existing device is of the correct type. */
316 
317 	if (rc != -1) {
318 		if ((f->st.mode & (S_IFCHR|S_IFBLK)) !=
319 		    (st.st_mode & (S_IFCHR|S_IFBLK)) ||
320 		    f->st.rdev != st.st_rdev) {
321 			LOG3("%s: updating device", f->path);
322 			updatedev = 1;
323 		}
324 	}
325 
326 	if (rc == -1 || updatedev) {
327 		newdev = 1;
328 		if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {
329 			ERRX1("mktemplate");
330 			return -1;
331 		}
332 		if (mkstempnodat(p->rootfd, temp,
333 		    f->st.mode & (S_IFCHR|S_IFBLK), f->st.rdev) == NULL) {
334 			ERR("mkstempnodat");
335 			free(temp);
336 			return -1;
337 		}
338 	}
339 
340 	rsync_set_metadata_at(sess, newdev,
341 	    p->rootfd, f, newdev ? temp : f->path);
342 
343 	if (newdev) {
344 		if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
345 			ERR("%s: renameat %s", temp, f->path);
346 			(void)unlinkat(p->rootfd, temp, 0);
347 			free(temp);
348 			return -1;
349 		}
350 		free(temp);
351 	}
352 
353 	log_file(sess, f);
354 	return 0;
355 }
356 
357 /*
358  * See pre_link(), but for FIFOs.
359  * FIXME: this is very similar to the other pre_xxx() functions.
360  * Return <0 on failure 0 on success.
361  */
362 static int
363 pre_fifo(struct upload *p, struct sess *sess)
364 {
365 	struct stat		 st;
366 	const struct flist	*f;
367 	int			 rc, newfifo = 0;
368 	char			*temp = NULL;
369 
370 	f = &p->fl[p->idx];
371 	assert(S_ISFIFO(f->st.mode));
372 
373 	if (!sess->opts->specials) {
374 		WARNX("skipping non-regular file %s", f->path);
375 		return 0;
376 	}
377 	if (sess->opts->dry_run) {
378 		log_file(sess, f);
379 		return 0;
380 	}
381 
382 	/*
383 	 * See if the fifo already exists.
384 	 * If it exists as a non-FIFO, unlink it (if a directory) then
385 	 * mark it from replacement.
386 	 */
387 
388 	assert(p->rootfd != -1);
389 	rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
390 
391 	if (rc == -1 && errno != ENOENT) {
392 		ERR("%s: fstatat", f->path);
393 		return -1;
394 	}
395 	if (rc != -1 && !S_ISFIFO(st.st_mode)) {
396 		if (S_ISDIR(st.st_mode) &&
397 		    unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
398 			ERR("%s: unlinkat", f->path);
399 			return -1;
400 		}
401 		rc = -1;
402 	}
403 
404 	if (rc == -1) {
405 		newfifo = 1;
406 		if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {
407 			ERRX1("mktemplate");
408 			return -1;
409 		}
410 		if (mkstempfifoat(p->rootfd, temp) == NULL) {
411 			ERR("mkstempfifoat");
412 			free(temp);
413 			return -1;
414 		}
415 	}
416 
417 	rsync_set_metadata_at(sess, newfifo,
418 		p->rootfd, f, newfifo ? temp : f->path);
419 
420 	if (newfifo) {
421 		if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
422 			ERR("%s: renameat %s", temp, f->path);
423 			(void)unlinkat(p->rootfd, temp, 0);
424 			free(temp);
425 			return -1;
426 		}
427 		free(temp);
428 	}
429 
430 	log_file(sess, f);
431 	return 0;
432 }
433 
434 /*
435  * See pre_link(), but for socket files.
436  * FIXME: this is very similar to the other pre_xxx() functions.
437  * Return <0 on failure 0 on success.
438  */
439 static int
440 pre_sock(struct upload *p, struct sess *sess)
441 {
442 	struct stat		 st;
443 	const struct flist	*f;
444 	int			 rc, newsock = 0;
445 	char			*temp = NULL;
446 
447 	f = &p->fl[p->idx];
448 	assert(S_ISSOCK(f->st.mode));
449 
450 	if (!sess->opts->specials) {
451 		WARNX("skipping non-regular file %s", f->path);
452 		return 0;
453 	}
454 	if (sess->opts->dry_run) {
455 		log_file(sess, f);
456 		return 0;
457 	}
458 
459 	/*
460 	 * See if the fifo already exists.
461 	 * If it exists as a non-FIFO, unlink it (if a directory) then
462 	 * mark it from replacement.
463 	 */
464 
465 	assert(p->rootfd != -1);
466 	rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
467 
468 	if (rc == -1 && errno != ENOENT) {
469 		ERR("%s: fstatat", f->path);
470 		return -1;
471 	}
472 	if (rc != -1 && !S_ISSOCK(st.st_mode)) {
473 		if (S_ISDIR(st.st_mode) &&
474 		    unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
475 			ERR("%s: unlinkat", f->path);
476 			return -1;
477 		}
478 		rc = -1;
479 	}
480 
481 	if (rc == -1) {
482 		newsock = 1;
483 		if (mktemplate(&temp, f->path, sess->opts->recursive) == -1) {
484 			ERRX1("mktemplate");
485 			return -1;
486 		}
487 		if (mkstempsock(p->root, temp) == NULL) {
488 			ERR("mkstempsock");
489 			free(temp);
490 			return -1;
491 		}
492 	}
493 
494 	rsync_set_metadata_at(sess, newsock,
495 		p->rootfd, f, newsock ? temp : f->path);
496 
497 	if (newsock) {
498 		if (renameat(p->rootfd, temp, p->rootfd, f->path) == -1) {
499 			ERR("%s: renameat %s", temp, f->path);
500 			(void)unlinkat(p->rootfd, temp, 0);
501 			free(temp);
502 			return -1;
503 		}
504 		free(temp);
505 	}
506 
507 	log_file(sess, f);
508 	return 0;
509 }
510 
511 /*
512  * If not found, create the destination directory in prefix order.
513  * Create directories using the existing umask.
514  * Return <0 on failure 0 on success.
515  */
516 static int
517 pre_dir(const struct upload *p, struct sess *sess)
518 {
519 	struct stat	 st;
520 	int		 rc;
521 	const struct flist *f;
522 
523 	f = &p->fl[p->idx];
524 	assert(S_ISDIR(f->st.mode));
525 
526 	if (!sess->opts->recursive) {
527 		WARNX("%s: ignoring directory", f->path);
528 		return 0;
529 	}
530 	if (sess->opts->dry_run) {
531 		log_dir(sess, f);
532 		return 0;
533 	}
534 
535 	assert(p->rootfd != -1);
536 	rc = fstatat(p->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW);
537 
538 	if (rc == -1 && errno != ENOENT) {
539 		ERR("%s: fstatat", f->path);
540 		return -1;
541 	}
542 	if (rc != -1 && !S_ISDIR(st.st_mode)) {
543 		ERRX("%s: not a directory", f->path);
544 		return -1;
545 	} else if (rc != -1) {
546 		/*
547 		 * FIXME: we should fchmod the permissions here as well,
548 		 * as we may locally have shut down writing into the
549 		 * directory and that doesn't work.
550 		 */
551 		LOG3("%s: updating directory", f->path);
552 		return 0;
553 	}
554 
555 	/*
556 	 * We want to make the directory with default permissions (using
557 	 * our old umask, which we've since unset), then adjust
558 	 * permissions (assuming preserve_perms or new) afterward in
559 	 * case it's u-w or something.
560 	 */
561 
562 	LOG3("%s: creating directory", f->path);
563 	if (mkdirat(p->rootfd, f->path, 0777 & ~p->oumask) == -1) {
564 		ERR("%s: mkdirat", f->path);
565 		return -1;
566 	}
567 
568 	p->newdir[p->idx] = 1;
569 	log_dir(sess, f);
570 	return 0;
571 }
572 
573 /*
574  * Process the directory time and mode for "idx" in the file list.
575  * Returns zero on failure, non-zero on success.
576  */
577 static int
578 post_dir(struct sess *sess, const struct upload *u, size_t idx)
579 {
580 	struct timespec	 tv[2];
581 	int		 rc;
582 	struct stat	 st;
583 	const struct flist *f;
584 
585 	f = &u->fl[idx];
586 	assert(S_ISDIR(f->st.mode));
587 
588 	/* We already warned about the directory in pre_process_dir(). */
589 
590 	if (!sess->opts->recursive)
591 		return 1;
592 	if (sess->opts->dry_run)
593 		return 1;
594 
595 	if (fstatat(u->rootfd, f->path, &st, AT_SYMLINK_NOFOLLOW) == -1) {
596 		ERR("%s: fstatat", f->path);
597 		return 0;
598 	}
599 	if (!S_ISDIR(st.st_mode)) {
600 		WARNX("%s: not a directory", f->path);
601 		return 0;
602 	}
603 
604 	/*
605 	 * Update the modification time if we're a new directory *or* if
606 	 * we're preserving times and the time has changed.
607 	 * FIXME: run rsync_set_metadata()?
608 	 */
609 
610 	if (u->newdir[idx] ||
611 	    (sess->opts->preserve_times &&
612 	     st.st_mtime != f->st.mtime)) {
613 		tv[0].tv_sec = time(NULL);
614 		tv[0].tv_nsec = 0;
615 		tv[1].tv_sec = f->st.mtime;
616 		tv[1].tv_nsec = 0;
617 		rc = utimensat(u->rootfd, f->path, tv, 0);
618 		if (rc == -1) {
619 			ERR("%s: utimensat", f->path);
620 			return 0;
621 		}
622 		LOG4("%s: updated date", f->path);
623 	}
624 
625 	/*
626 	 * Update the mode if we're a new directory *or* if we're
627 	 * preserving modes and it has changed.
628 	 */
629 
630 	if (u->newdir[idx] ||
631 	    (sess->opts->preserve_perms && st.st_mode != f->st.mode)) {
632 		rc = fchmodat(u->rootfd, f->path, f->st.mode, 0);
633 		if (rc == -1) {
634 			ERR("%s: fchmodat", f->path);
635 			return 0;
636 		}
637 		LOG4("%s: updated mode", f->path);
638 	}
639 
640 	return 1;
641 }
642 
643 /*
644  * Try to open the file at the current index.
645  * If the file does not exist, returns with >0.
646  * Return <0 on failure, 0 on success w/nothing to be done, >0 on
647  * success and the file needs attention.
648  */
649 static int
650 pre_file(const struct upload *p, int *filefd, struct stat *st,
651     struct sess *sess)
652 {
653 	const struct flist *f;
654 	int rc;
655 
656 	f = &p->fl[p->idx];
657 	assert(S_ISREG(f->st.mode));
658 
659 	if (sess->opts->dry_run) {
660 		log_file(sess, f);
661 		if (!io_write_int(sess, p->fdout, p->idx)) {
662 			ERRX1("io_write_int");
663 			return -1;
664 		}
665 		return 0;
666 	}
667 
668 	/*
669 	 * For non dry-run cases, we'll write the acknowledgement later
670 	 * in the rsync_uploader() function.
671 	 */
672 
673 	*filefd = -1;
674 	rc = fstatat(p->rootfd, f->path, st, AT_SYMLINK_NOFOLLOW);
675 
676 	if (rc == -1) {
677 		if (errno == ENOENT)
678 			return 1;
679 
680 		ERR("%s: fstatat", f->path);
681 		return -1;
682 	}
683 	if (!S_ISREG(st->st_mode)) {
684 		if (S_ISDIR(st->st_mode) &&
685 		    unlinkat(p->rootfd, f->path, AT_REMOVEDIR) == -1) {
686 			ERR("%s: unlinkat", f->path);
687 			return -1;
688 		}
689 		return 1;
690 	}
691 
692 	/* quick check if file is the same */
693 	if (st->st_size == f->st.size &&
694 	    st->st_mtime == f->st.mtime) {
695 		LOG3("%s: skipping: up to date", f->path);
696 		if (!rsync_set_metadata_at(sess, 0, p->rootfd, f, f->path)) {
697 			ERRX1("rsync_set_metadata");
698 			return -1;
699 		}
700 		return 0;
701 	}
702 
703 	*filefd = openat(p->rootfd, f->path, O_RDONLY | O_NOFOLLOW, 0);
704 	if (*filefd == -1 && errno != ENOENT) {
705 		ERR("%s: openat", f->path);
706 		return -1;
707 	}
708 
709 	/* file needs attention */
710 	return 1;
711 }
712 
713 /*
714  * Allocate an uploader object in the correct state to start.
715  * Returns NULL on failure or the pointer otherwise.
716  * On success, upload_free() must be called with the allocated pointer.
717  */
718 struct upload *
719 upload_alloc(const char *root, int rootfd, int fdout,
720 	size_t clen, const struct flist *fl, size_t flsz, mode_t msk)
721 {
722 	struct upload	*p;
723 
724 	if ((p = calloc(1, sizeof(struct upload))) == NULL) {
725 		ERR("calloc");
726 		return NULL;
727 	}
728 
729 	p->state = UPLOAD_FIND_NEXT;
730 	p->oumask = msk;
731 	p->root = strdup(root);
732 	if (p->root == NULL) {
733 		ERR("strdup");
734 		free(p);
735 		return NULL;
736 	}
737 	p->rootfd = rootfd;
738 	p->csumlen = clen;
739 	p->fdout = fdout;
740 	p->fl = fl;
741 	p->flsz = flsz;
742 	p->newdir = calloc(flsz, sizeof(int));
743 	if (p->newdir == NULL) {
744 		ERR("calloc");
745 		free(p->root);
746 		free(p);
747 		return NULL;
748 	}
749 	return p;
750 }
751 
752 /*
753  * Perform all cleanups and free.
754  * Passing a NULL to this function is ok.
755  */
756 void
757 upload_free(struct upload *p)
758 {
759 
760 	if (p == NULL)
761 		return;
762 	free(p->root);
763 	free(p->newdir);
764 	free(p->buf);
765 	free(p);
766 }
767 
768 /*
769  * Iterates through all available files and conditionally gets the file
770  * ready for processing to check whether it's up to date.
771  * If not up to date or empty, sends file information to the sender.
772  * If returns 0, we've processed all files there are to process.
773  * If returns >0, we're waiting for POLLIN or POLLOUT data.
774  * Otherwise returns <0, which is an error.
775  */
776 int
777 rsync_uploader(struct upload *u, int *fileinfd,
778 	struct sess *sess, int *fileoutfd)
779 {
780 	struct blkset	    blk;
781 	struct stat	    st;
782 	void		   *mbuf, *bufp;
783 	ssize_t		    msz;
784 	size_t		    i, pos, sz;
785 	off_t		    offs;
786 	int		    c;
787 
788 	/* Once finished this should never get called again. */
789 	assert(u->state != UPLOAD_FINISHED);
790 
791 	/*
792 	 * If we have an upload in progress, then keep writing until the
793 	 * buffer has been fully written.
794 	 * We must only have the output file descriptor working and also
795 	 * have a valid buffer to write.
796 	 */
797 
798 	if (u->state == UPLOAD_WRITE) {
799 		assert(u->buf != NULL);
800 		assert(*fileoutfd != -1);
801 		assert(*fileinfd == -1);
802 
803 		/*
804 		 * Unfortunately, we need to chunk these: if we're
805 		 * the server side of things, then we're multiplexing
806 		 * output and need to wrap this in chunks.
807 		 * This is a major deficiency of rsync.
808 		 * FIXME: add a "fast-path" mode that simply dumps out
809 		 * the buffer non-blocking if we're not mplexing.
810 		 */
811 
812 		if (u->bufpos < u->bufsz) {
813 			sz = MAX_CHUNK < (u->bufsz - u->bufpos) ?
814 				MAX_CHUNK : (u->bufsz - u->bufpos);
815 			c = io_write_buf(sess, u->fdout,
816 				u->buf + u->bufpos, sz);
817 			if (c == 0) {
818 				ERRX1("io_write_nonblocking");
819 				return -1;
820 			}
821 			u->bufpos += sz;
822 			if (u->bufpos < u->bufsz)
823 				return 1;
824 		}
825 
826 		/*
827 		 * Let the UPLOAD_FIND_NEXT state handle things if we
828 		 * finish, as we'll need to write a POLLOUT message and
829 		 * not have a writable descriptor yet.
830 		 */
831 
832 		u->state = UPLOAD_FIND_NEXT;
833 		u->idx++;
834 		return 1;
835 	}
836 
837 	/*
838 	 * If we invoke the uploader without a file currently open, then
839 	 * we iterate through til the next available regular file and
840 	 * start the opening process.
841 	 * This means we must have the output file descriptor working.
842 	 */
843 
844 	if (u->state == UPLOAD_FIND_NEXT) {
845 		assert(*fileinfd == -1);
846 		assert(*fileoutfd != -1);
847 
848 		for ( ; u->idx < u->flsz; u->idx++) {
849 			if (S_ISDIR(u->fl[u->idx].st.mode))
850 				c = pre_dir(u, sess);
851 			else if (S_ISLNK(u->fl[u->idx].st.mode))
852 				c = pre_link(u, sess);
853 			else if (S_ISREG(u->fl[u->idx].st.mode))
854 				c = pre_file(u, fileinfd, &st, sess);
855 			else if (S_ISBLK(u->fl[u->idx].st.mode) ||
856 			    S_ISCHR(u->fl[u->idx].st.mode))
857 				c = pre_dev(u, sess);
858 			else if (S_ISFIFO(u->fl[u->idx].st.mode))
859 				c = pre_fifo(u, sess);
860 			else if (S_ISSOCK(u->fl[u->idx].st.mode))
861 				c = pre_sock(u, sess);
862 			else
863 				c = 0;
864 
865 			if (c < 0)
866 				return -1;
867 			else if (c > 0)
868 				break;
869 		}
870 
871 		/*
872 		 * Whether we've finished writing files or not, we
873 		 * disable polling on the output channel.
874 		 */
875 
876 		*fileoutfd = -1;
877 		if (u->idx == u->flsz) {
878 			assert(*fileinfd == -1);
879 			if (!io_write_int(sess, u->fdout, -1)) {
880 				ERRX1("io_write_int");
881 				return -1;
882 			}
883 			u->state = UPLOAD_FINISHED;
884 			LOG4("uploader: finished");
885 			return 0;
886 		}
887 
888 		/* Go back to the event loop, if necessary. */
889 
890 		u->state = UPLOAD_WRITE;
891 	}
892 
893 	/* Initialies our blocks. */
894 
895 	assert(u->state == UPLOAD_WRITE);
896 	memset(&blk, 0, sizeof(struct blkset));
897 	blk.csum = u->csumlen;
898 
899 	if (*fileinfd != -1 && st.st_size > 0) {
900 		init_blkset(&blk, st.st_size);
901 		assert(blk.blksz);
902 
903 		blk.blks = calloc(blk.blksz, sizeof(struct blk));
904 		if (blk.blks == NULL) {
905 			ERR("calloc");
906 			close(*fileinfd);
907 			*fileinfd = -1;
908 			return -1;
909 		}
910 
911 		if ((mbuf = malloc(blk.len)) == NULL) {
912 			ERR("malloc");
913 			close(*fileinfd);
914 			*fileinfd = -1;
915 			free(blk.blks);
916 			return -1;
917 		}
918 
919 		offs = 0;
920 		i = 0;
921 		do {
922 			msz = pread(*fileinfd, mbuf, blk.len, offs);
923 			if ((size_t)msz != blk.len && (size_t)msz != blk.rem) {
924 				ERR("pread");
925 				close(*fileinfd);
926 				*fileinfd = -1;
927 				free(mbuf);
928 				free(blk.blks);
929 				return -1;
930 			}
931 			init_blk(&blk.blks[i], &blk, offs, i, mbuf, sess);
932 			offs += blk.len;
933 			LOG3(
934 			    "i=%ld, offs=%lld, msz=%ld, blk.len=%lu, blk.rem=%lu",
935 			    i, offs, msz, blk.len, blk.rem);
936 			i++;
937 		} while (i < blk.blksz);
938 
939 		free(mbuf);
940 		close(*fileinfd);
941 		*fileinfd = -1;
942 		LOG3("%s: mapped %jd B with %zu blocks",
943 		    u->fl[u->idx].path, (intmax_t)blk.size,
944 		    blk.blksz);
945 	} else {
946 		if (*fileinfd != -1) {
947 			close(*fileinfd);
948 			*fileinfd = -1;
949 		}
950 		blk.len = MAX_CHUNK; /* Doesn't matter. */
951 		LOG3("%s: not mapped", u->fl[u->idx].path);
952 	}
953 
954 	assert(*fileinfd == -1);
955 
956 	/* Make sure the block metadata buffer is big enough. */
957 
958 	u->bufsz =
959 	     sizeof(int32_t) + /* identifier */
960 	     sizeof(int32_t) + /* block count */
961 	     sizeof(int32_t) + /* block length */
962 	     sizeof(int32_t) + /* checksum length */
963 	     sizeof(int32_t) + /* block remainder */
964 	     blk.blksz *
965 	     (sizeof(int32_t) + /* short checksum */
966 	      blk.csum); /* long checksum */
967 
968 	if (u->bufsz > u->bufmax) {
969 		if ((bufp = realloc(u->buf, u->bufsz)) == NULL) {
970 			ERR("realloc");
971 			free(blk.blks);
972 			return -1;
973 		}
974 		u->buf = bufp;
975 		u->bufmax = u->bufsz;
976 	}
977 
978 	u->bufpos = pos = 0;
979 	io_buffer_int(u->buf, &pos, u->bufsz, u->idx);
980 	io_buffer_int(u->buf, &pos, u->bufsz, blk.blksz);
981 	io_buffer_int(u->buf, &pos, u->bufsz, blk.len);
982 	io_buffer_int(u->buf, &pos, u->bufsz, blk.csum);
983 	io_buffer_int(u->buf, &pos, u->bufsz, blk.rem);
984 	for (i = 0; i < blk.blksz; i++) {
985 		io_buffer_int(u->buf, &pos, u->bufsz,
986 			blk.blks[i].chksum_short);
987 		io_buffer_buf(u->buf, &pos, u->bufsz,
988 			blk.blks[i].chksum_long, blk.csum);
989 	}
990 	assert(pos == u->bufsz);
991 
992 	/* Reenable the output poller and clean up. */
993 
994 	*fileoutfd = u->fdout;
995 	free(blk.blks);
996 	return 1;
997 }
998 
999 /*
1000  * Fix up the directory permissions and times post-order.
1001  * We can't fix up directory permissions in place because the server may
1002  * want us to have overly-tight permissions---say, those that don't
1003  * allow writing into the directory.
1004  * We also need to do our directory times post-order because making
1005  * files within the directory will change modification times.
1006  * Returns zero on failure, non-zero on success.
1007  */
1008 int
1009 rsync_uploader_tail(struct upload *u, struct sess *sess)
1010 {
1011 	size_t	 i;
1012 
1013 
1014 	if (!sess->opts->preserve_times &&
1015 	    !sess->opts->preserve_perms)
1016 		return 1;
1017 
1018 	LOG2("fixing up directory times and permissions");
1019 
1020 	for (i = 0; i < u->flsz; i++)
1021 		if (S_ISDIR(u->fl[i].st.mode))
1022 			if (!post_dir(sess, u, i))
1023 				return 0;
1024 
1025 	return 1;
1026 }
1027