xref: /openbsd-src/usr.bin/rsync/session.c (revision 173dc8749401a03b492e3d8eaa9358ba3cce4e24)
1*173dc874Sderaadt /*	$OpenBSD: session.c,v 1.9 2021/09/02 21:06:06 deraadt Exp $ */
260a32ee9Sbenno /*
360a32ee9Sbenno  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
460a32ee9Sbenno  *
560a32ee9Sbenno  * Permission to use, copy, modify, and distribute this software for any
660a32ee9Sbenno  * purpose with or without fee is hereby granted, provided that the above
760a32ee9Sbenno  * copyright notice and this permission notice appear in all copies.
860a32ee9Sbenno  *
960a32ee9Sbenno  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1060a32ee9Sbenno  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1160a32ee9Sbenno  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1260a32ee9Sbenno  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1360a32ee9Sbenno  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1460a32ee9Sbenno  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1560a32ee9Sbenno  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1660a32ee9Sbenno  */
1760a32ee9Sbenno 
1860a32ee9Sbenno #include <assert.h>
1960a32ee9Sbenno #include <stdint.h>
2060a32ee9Sbenno #include <stdlib.h>
2160a32ee9Sbenno #include <unistd.h>
2260a32ee9Sbenno 
2360a32ee9Sbenno #include "extern.h"
2460a32ee9Sbenno 
2560a32ee9Sbenno /*
2660a32ee9Sbenno  * Accept how much we've read, written, and file-size, and print them in
2760a32ee9Sbenno  * a human-readable fashion (with GB, MB, etc. prefixes).
2860a32ee9Sbenno  * This only prints as the client.
2960a32ee9Sbenno  */
3060a32ee9Sbenno static void
stats_log(struct sess * sess,uint64_t tread,uint64_t twrite,uint64_t tsize)3160a32ee9Sbenno stats_log(struct sess *sess,
3260a32ee9Sbenno 	uint64_t tread, uint64_t twrite, uint64_t tsize)
3360a32ee9Sbenno {
3460a32ee9Sbenno 	double		 tr, tw, ts;
3560a32ee9Sbenno 	const char	*tru = "B", *twu = "B", *tsu = "B";
3660a32ee9Sbenno 	int		 trsz = 0, twsz = 0, tssz = 0;
3760a32ee9Sbenno 
38b2a7eac7Sbenno 	assert(verbose);
3960a32ee9Sbenno 	if (sess->opts->server)
4060a32ee9Sbenno 		return;
4160a32ee9Sbenno 
4260a32ee9Sbenno 	if (tread >= 1024 * 1024 * 1024) {
4360a32ee9Sbenno 		tr = tread / (1024.0 * 1024.0 * 1024.0);
4460a32ee9Sbenno 		tru = "GB";
4560a32ee9Sbenno 		trsz = 3;
4660a32ee9Sbenno 	} else if (tread >= 1024 * 1024) {
4760a32ee9Sbenno 		tr = tread / (1024.0 * 1024.0);
4860a32ee9Sbenno 		tru = "MB";
4960a32ee9Sbenno 		trsz = 2;
5060a32ee9Sbenno 	} else if (tread >= 1024) {
5160a32ee9Sbenno 		tr = tread / 1024.0;
5260a32ee9Sbenno 		tru = "KB";
5360a32ee9Sbenno 		trsz = 1;
5460a32ee9Sbenno 	} else
5560a32ee9Sbenno 		tr = tread;
5660a32ee9Sbenno 
5760a32ee9Sbenno 	if (twrite >= 1024 * 1024 * 1024) {
5860a32ee9Sbenno 		tw = twrite / (1024.0 * 1024.0 * 1024.0);
5960a32ee9Sbenno 		twu = "GB";
6060a32ee9Sbenno 		twsz = 3;
6160a32ee9Sbenno 	} else if (twrite >= 1024 * 1024) {
6260a32ee9Sbenno 		tw = twrite / (1024.0 * 1024.0);
6360a32ee9Sbenno 		twu = "MB";
6460a32ee9Sbenno 		twsz = 2;
6560a32ee9Sbenno 	} else if (twrite >= 1024) {
6660a32ee9Sbenno 		tw = twrite / 1024.0;
6760a32ee9Sbenno 		twu = "KB";
6860a32ee9Sbenno 		twsz = 1;
6960a32ee9Sbenno 	} else
7060a32ee9Sbenno 		tw = twrite;
7160a32ee9Sbenno 
7260a32ee9Sbenno 	if (tsize >= 1024 * 1024 * 1024) {
7360a32ee9Sbenno 		ts = tsize / (1024.0 * 1024.0 * 1024.0);
7460a32ee9Sbenno 		tsu = "GB";
7560a32ee9Sbenno 		tssz = 3;
7660a32ee9Sbenno 	} else if (tsize >= 1024 * 1024) {
7760a32ee9Sbenno 		ts = tsize / (1024.0 * 1024.0);
7860a32ee9Sbenno 		tsu = "MB";
7960a32ee9Sbenno 		tssz = 2;
8060a32ee9Sbenno 	} else if (tsize >= 1024) {
8160a32ee9Sbenno 		ts = tsize / 1024.0;
8260a32ee9Sbenno 		tsu = "KB";
8360a32ee9Sbenno 		tssz = 1;
8460a32ee9Sbenno 	} else
8560a32ee9Sbenno 		ts = tsize;
8660a32ee9Sbenno 
87b2a7eac7Sbenno 	LOG1("Transfer complete: "
8802f20df6Sderaadt 	    "%.*lf %s sent, %.*lf %s read, %.*lf %s file size",
8960a32ee9Sbenno 	    trsz, tr, tru,
9060a32ee9Sbenno 	    twsz, tw, twu,
9160a32ee9Sbenno 	    tssz, ts, tsu);
9260a32ee9Sbenno }
9360a32ee9Sbenno 
9460a32ee9Sbenno /*
9560a32ee9Sbenno  * At the end of transmission, we write our statistics if we're the
9660a32ee9Sbenno  * server, then log only if we're not the server.
9760a32ee9Sbenno  * Either way, only do this if we're in verbose mode.
9860a32ee9Sbenno  * Returns zero on failure, non-zero on success.
9960a32ee9Sbenno  */
10060a32ee9Sbenno int
sess_stats_send(struct sess * sess,int fd)10160a32ee9Sbenno sess_stats_send(struct sess *sess, int fd)
10260a32ee9Sbenno {
10360a32ee9Sbenno 	uint64_t tw, tr, ts;
10460a32ee9Sbenno 
105b2a7eac7Sbenno 	if (verbose == 0)
10660a32ee9Sbenno 		return 1;
10760a32ee9Sbenno 
10860a32ee9Sbenno 	tw = sess->total_write;
10960a32ee9Sbenno 	tr = sess->total_read;
11060a32ee9Sbenno 	ts = sess->total_size;
11160a32ee9Sbenno 
11260a32ee9Sbenno 	if (sess->opts->server) {
113aa1dcd86Sderaadt 		if (!io_write_ulong(sess, fd, tr)) {
114b2a7eac7Sbenno 			ERRX1("io_write_ulong");
11560a32ee9Sbenno 			return 0;
116aa1dcd86Sderaadt 		} else if (!io_write_ulong(sess, fd, tw)) {
117b2a7eac7Sbenno 			ERRX1("io_write_ulong");
11860a32ee9Sbenno 			return 0;
119aa1dcd86Sderaadt 		} else if (!io_write_ulong(sess, fd, ts)) {
120b2a7eac7Sbenno 			ERRX1("io_write_ulong");
12160a32ee9Sbenno 			return 0;
12260a32ee9Sbenno 		}
12360a32ee9Sbenno 	}
12460a32ee9Sbenno 
12560a32ee9Sbenno 	stats_log(sess, tr, tw, ts);
12660a32ee9Sbenno 	return 1;
12760a32ee9Sbenno }
12860a32ee9Sbenno 
12960a32ee9Sbenno /*
13060a32ee9Sbenno  * At the end of the transmission, we have some statistics to read.
13160a32ee9Sbenno  * Only do this (1) if we're in verbose mode and (2) if we're the
13260a32ee9Sbenno  * server.
13360a32ee9Sbenno  * Then log the findings.
13460a32ee9Sbenno  * Return zero on failure, non-zero on success.
13560a32ee9Sbenno  */
13660a32ee9Sbenno int
sess_stats_recv(struct sess * sess,int fd)13760a32ee9Sbenno sess_stats_recv(struct sess *sess, int fd)
13860a32ee9Sbenno {
13960a32ee9Sbenno 	uint64_t tr, tw, ts;
14060a32ee9Sbenno 
141b2a7eac7Sbenno 	if (sess->opts->server || verbose == 0)
14260a32ee9Sbenno 		return 1;
14360a32ee9Sbenno 
14460a32ee9Sbenno 	if (!io_read_ulong(sess, fd, &tw)) {
145b2a7eac7Sbenno 		ERRX1("io_read_ulong");
14660a32ee9Sbenno 		return 0;
14760a32ee9Sbenno 	} else if (!io_read_ulong(sess, fd, &tr)) {
148b2a7eac7Sbenno 		ERRX1("io_read_ulong");
14960a32ee9Sbenno 		return 0;
15060a32ee9Sbenno 	} else if (!io_read_ulong(sess, fd, &ts)) {
151b2a7eac7Sbenno 		ERRX1("io_read_ulong");
15260a32ee9Sbenno 		return 0;
15360a32ee9Sbenno 	}
15460a32ee9Sbenno 
15560a32ee9Sbenno 	stats_log(sess, tr, tw, ts);
15660a32ee9Sbenno 	return 1;
15760a32ee9Sbenno }
158