Annotation of src/usr.bin/rsync/session.c, Revision 1.7
1.7 ! benno 1: /* $Id: session.c,v 1.6 2019/03/31 09:26:05 deraadt Exp $ */
1.1 benno 2: /*
3: * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #include <sys/param.h>
18:
19: #include <assert.h>
20: #include <stdint.h>
21: #include <stdlib.h>
22: #include <unistd.h>
23:
24: #include "extern.h"
25:
26: /*
27: * Accept how much we've read, written, and file-size, and print them in
28: * a human-readable fashion (with GB, MB, etc. prefixes).
29: * This only prints as the client.
30: */
31: static void
1.2 benno 32: stats_log(struct sess *sess,
1.1 benno 33: uint64_t tread, uint64_t twrite, uint64_t tsize)
34: {
35: double tr, tw, ts;
36: const char *tru = "B", *twu = "B", *tsu = "B";
37: int trsz = 0, twsz = 0, tssz = 0;
38:
1.7 ! benno 39: assert(verbose);
1.1 benno 40: if (sess->opts->server)
41: return;
42:
43: if (tread >= 1024 * 1024 * 1024) {
44: tr = tread / (1024.0 * 1024.0 * 1024.0);
45: tru = "GB";
46: trsz = 3;
47: } else if (tread >= 1024 * 1024) {
48: tr = tread / (1024.0 * 1024.0);
49: tru = "MB";
50: trsz = 2;
51: } else if (tread >= 1024) {
52: tr = tread / 1024.0;
53: tru = "KB";
54: trsz = 1;
55: } else
56: tr = tread;
57:
58: if (twrite >= 1024 * 1024 * 1024) {
59: tw = twrite / (1024.0 * 1024.0 * 1024.0);
60: twu = "GB";
61: twsz = 3;
62: } else if (twrite >= 1024 * 1024) {
63: tw = twrite / (1024.0 * 1024.0);
64: twu = "MB";
65: twsz = 2;
66: } else if (twrite >= 1024) {
67: tw = twrite / 1024.0;
68: twu = "KB";
69: twsz = 1;
70: } else
71: tw = twrite;
72:
73: if (tsize >= 1024 * 1024 * 1024) {
74: ts = tsize / (1024.0 * 1024.0 * 1024.0);
75: tsu = "GB";
76: tssz = 3;
77: } else if (tsize >= 1024 * 1024) {
78: ts = tsize / (1024.0 * 1024.0);
79: tsu = "MB";
80: tssz = 2;
81: } else if (tsize >= 1024) {
82: ts = tsize / 1024.0;
83: tsu = "KB";
84: tssz = 1;
85: } else
86: ts = tsize;
87:
1.7 ! benno 88: LOG1("Transfer complete: "
1.5 deraadt 89: "%.*lf %s sent, %.*lf %s read, %.*lf %s file size",
90: trsz, tr, tru,
91: twsz, tw, twu,
92: tssz, ts, tsu);
1.1 benno 93: }
94:
95: /*
96: * At the end of transmission, we write our statistics if we're the
97: * server, then log only if we're not the server.
98: * Either way, only do this if we're in verbose mode.
99: * Returns zero on failure, non-zero on success.
100: */
101: int
102: sess_stats_send(struct sess *sess, int fd)
103: {
104: uint64_t tw, tr, ts;
105:
1.7 ! benno 106: if (verbose == 0)
1.1 benno 107: return 1;
108:
109: tw = sess->total_write;
110: tr = sess->total_read;
111: ts = sess->total_size;
112:
113: if (sess->opts->server) {
1.6 deraadt 114: if (!io_write_ulong(sess, fd, tr)) {
1.7 ! benno 115: ERRX1("io_write_ulong");
1.1 benno 116: return 0;
1.6 deraadt 117: } else if (!io_write_ulong(sess, fd, tw)) {
1.7 ! benno 118: ERRX1("io_write_ulong");
1.1 benno 119: return 0;
1.6 deraadt 120: } else if (!io_write_ulong(sess, fd, ts)) {
1.7 ! benno 121: ERRX1("io_write_ulong");
1.1 benno 122: return 0;
123: }
124: }
125:
126: stats_log(sess, tr, tw, ts);
127: return 1;
128: }
129:
130: /*
131: * At the end of the transmission, we have some statistics to read.
132: * Only do this (1) if we're in verbose mode and (2) if we're the
133: * server.
134: * Then log the findings.
135: * Return zero on failure, non-zero on success.
136: */
137: int
138: sess_stats_recv(struct sess *sess, int fd)
139: {
140: uint64_t tr, tw, ts;
141:
1.7 ! benno 142: if (sess->opts->server || verbose == 0)
1.1 benno 143: return 1;
144:
1.3 deraadt 145: if (!io_read_ulong(sess, fd, &tw)) {
1.7 ! benno 146: ERRX1("io_read_ulong");
1.1 benno 147: return 0;
1.3 deraadt 148: } else if (!io_read_ulong(sess, fd, &tr)) {
1.7 ! benno 149: ERRX1("io_read_ulong");
1.1 benno 150: return 0;
1.3 deraadt 151: } else if (!io_read_ulong(sess, fd, &ts)) {
1.7 ! benno 152: ERRX1("io_read_ulong");
1.1 benno 153: return 0;
154: }
155:
156: stats_log(sess, tr, tw, ts);
157: return 1;
158: }