DEV64_t and INO64_T should probably be unsigned
[rsync/rsync.git] / io.c
CommitLineData
7a24c346
MP
1/* -*- c-file-style: "linux" -*-
2
ce6c7c63 3 Copyright (C) 1996-2001 by Andrew Tridgell
720b47f2 4 Copyright (C) Paul Mackerras 1996
7a55d06e 5 Copyright (C) 2001 by Martin Pool <mbp@samba.org>
720b47f2
AT
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22/*
08f15335 23 socket and pipe IO utilities used in rsync
720b47f2
AT
24
25 tridge, June 1996
26 */
27#include "rsync.h"
28
8cd9fd4e
AT
29/* if no timeout is specified then use a 60 second select timeout */
30#define SELECT_TIMEOUT 60
31
8d9dc9f9
AT
32static int io_multiplexing_out;
33static int io_multiplexing_in;
679e7657
AT
34static int multiplex_in_fd;
35static int multiplex_out_fd;
8d9dc9f9 36static time_t last_io;
7a55d06e
MP
37static int no_flush;
38
39extern int bwlimit;
720b47f2 40extern int verbose;
6ba9279f 41extern int io_timeout;
a800434a 42extern struct stats stats;
720b47f2 43
7a55d06e
MP
44
45/** Ignore EOF errors while reading a module listing if the remote
46 version is 24 or less. */
47int kludge_around_eof = False;
48
49
554e0a8d 50static int io_error_fd = -1;
720b47f2 51
9dd891bb 52static void read_loop(int fd, char *buf, size_t len);
ff41a59f 53
8d9dc9f9
AT
54static void check_timeout(void)
55{
0adb99b9 56 extern int am_server, am_daemon;
8d9dc9f9 57 time_t t;
90ba34e2
AT
58
59 err_list_push();
8d9dc9f9
AT
60
61 if (!io_timeout) return;
62
63 if (!last_io) {
64 last_io = time(NULL);
65 return;
66 }
67
68 t = time(NULL);
69
86ffe37f 70 if (last_io && io_timeout && (t-last_io) >= io_timeout) {
0adb99b9 71 if (!am_server && !am_daemon) {
ce6c7c63 72 rprintf(FERROR,"io timeout after %d seconds - exiting\n",
0adb99b9
AT
73 (int)(t-last_io));
74 }
65417579 75 exit_cleanup(RERR_TIMEOUT);
8d9dc9f9
AT
76 }
77}
78
554e0a8d
AT
79/* setup the fd used to propogate errors */
80void io_set_error_fd(int fd)
81{
82 io_error_fd = fd;
83}
84
ff41a59f 85/* read some data from the error fd and write it to the write log code */
554e0a8d
AT
86static void read_error_fd(void)
87{
88 char buf[200];
06ce139f 89 size_t n;
554e0a8d 90 int fd = io_error_fd;
ff41a59f
AT
91 int tag, len;
92
8886f8d0
MP
93 /* io_error_fd is temporarily disabled -- is this meant to
94 * prevent indefinite recursion? */
554e0a8d
AT
95 io_error_fd = -1;
96
ff41a59f
AT
97 read_loop(fd, buf, 4);
98 tag = IVAL(buf, 0);
99
100 len = tag & 0xFFFFFF;
101 tag = tag >> 24;
102 tag -= MPLEX_BASE;
103
104 while (len) {
105 n = len;
06ce139f
MP
106 if (n > (sizeof(buf)-1))
107 n = sizeof(buf)-1;
ff41a59f
AT
108 read_loop(fd, buf, n);
109 rwrite((enum logcode)tag, buf, n);
110 len -= n;
554e0a8d
AT
111 }
112
113 io_error_fd = fd;
114}
115
720b47f2 116
7a55d06e
MP
117static void whine_about_eof (void)
118{
119 /**
120 It's almost always an error to get an EOF when we're trying
121 to read from the network, because the protocol is
122 self-terminating.
123
124 However, there is one unfortunate cases where it is not,
125 which is rsync <2.4.6 sending a list of modules on a
126 server, since the list is terminated by closing the socket.
127 So, for the section of the program where that is a problem
128 (start_socket_client), kludge_around_eof is True and we
129 just exit.
130 */
131
132 if (kludge_around_eof)
133 exit_cleanup (0);
134 else {
135 rprintf (FERROR,
136 "%s: connection unexpectedly closed "
137 "(%.0f bytes read so far)\n",
138 RSYNC_NAME, (double)stats.total_read);
139
140 exit_cleanup (RERR_STREAMIO);
141 }
142}
720b47f2 143
7a55d06e
MP
144
145static void die_from_readerr (int err)
146{
147 /* this prevents us trying to write errors on a dead socket */
148 io_multiplexing_close();
149
150 rprintf(FERROR, "%s: read error: %s\n",
151 RSYNC_NAME, strerror (err));
152 exit_cleanup(RERR_STREAMIO);
153}
154
155
156/*!
c3563c46
MP
157 * Read from a socket with IO timeout. return the number of bytes
158 * read. If no bytes can be read then exit, never return a number <= 0.
159 *
8886f8d0
MP
160 * TODO: If the remote shell connection fails, then current versions
161 * actually report an "unexpected EOF" error here. Since it's a
162 * fairly common mistake to try to use rsh when ssh is required, we
163 * should trap that: if we fail to read any data at all, we should
164 * give a better explanation. We can tell whether the connection has
165 * started by looking e.g. at whether the remote version is known yet.
c3563c46 166 */
9dd891bb 167static int read_timeout (int fd, char *buf, size_t len)
8d9dc9f9 168{
4c36ddbe
AT
169 int n, ret=0;
170
ea2111d1
AT
171 io_flush();
172
4c36ddbe 173 while (ret == 0) {
7a55d06e 174 /* until we manage to read *something* */
4c36ddbe
AT
175 fd_set fds;
176 struct timeval tv;
554e0a8d 177 int fd_count = fd+1;
a57873b7 178 int count;
4c36ddbe
AT
179
180 FD_ZERO(&fds);
181 FD_SET(fd, &fds);
554e0a8d
AT
182 if (io_error_fd != -1) {
183 FD_SET(io_error_fd, &fds);
184 if (io_error_fd > fd) fd_count = io_error_fd+1;
185 }
186
8cd9fd4e 187 tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
4c36ddbe
AT
188 tv.tv_usec = 0;
189
554e0a8d
AT
190 errno = 0;
191
a57873b7
AT
192 count = select(fd_count, &fds, NULL, NULL, &tv);
193
194 if (count == 0) {
195 check_timeout();
196 }
197
198 if (count <= 0) {
554e0a8d
AT
199 if (errno == EBADF) {
200 exit_cleanup(RERR_SOCKETIO);
201 }
4c36ddbe
AT
202 continue;
203 }
204
554e0a8d
AT
205 if (io_error_fd != -1 && FD_ISSET(io_error_fd, &fds)) {
206 read_error_fd();
207 }
208
209 if (!FD_ISSET(fd, &fds)) continue;
210
4c36ddbe
AT
211 n = read(fd, buf, len);
212
8d9dc9f9
AT
213 if (n > 0) {
214 buf += n;
215 len -= n;
4c36ddbe
AT
216 ret += n;
217 if (io_timeout)
218 last_io = time(NULL);
219 continue;
7a55d06e
MP
220 } else if (n == 0) {
221 whine_about_eof ();
222 return -1; /* doesn't return */
223 } else if (n == -1) {
224 if (errno == EINTR || errno == EWOULDBLOCK ||
225 errno == EAGAIN)
226 continue;
227 else
228 die_from_readerr (errno);
8d9dc9f9 229 }
4c36ddbe 230 }
8d9dc9f9 231
4c36ddbe
AT
232 return ret;
233}
8d9dc9f9 234
7a55d06e
MP
235
236
237
238/*! Continue trying to read len bytes - don't return until len has
239 been read. */
9dd891bb 240static void read_loop (int fd, char *buf, size_t len)
4c36ddbe
AT
241{
242 while (len) {
243 int n = read_timeout(fd, buf, len);
244
245 buf += n;
246 len -= n;
8d9dc9f9
AT
247 }
248}
249
7a55d06e
MP
250
251/**
252 * Read from the file descriptor handling multiplexing - return number
253 * of bytes read.
254 *
255 * Never returns <= 0.
256 */
9dd891bb 257static int read_unbuffered(int fd, char *buf, size_t len)
8d9dc9f9 258{
6fe25398 259 static size_t remaining;
909ce14f 260 int tag, ret = 0;
8d9dc9f9
AT
261 char line[1024];
262
7a55d06e 263 if (!io_multiplexing_in || fd != multiplex_in_fd)
4c36ddbe 264 return read_timeout(fd, buf, len);
8d9dc9f9
AT
265
266 while (ret == 0) {
267 if (remaining) {
268 len = MIN(len, remaining);
269 read_loop(fd, buf, len);
270 remaining -= len;
271 ret = len;
272 continue;
273 }
274
909ce14f 275 read_loop(fd, line, 4);
ff41a59f 276 tag = IVAL(line, 0);
679e7657 277
8d9dc9f9
AT
278 remaining = tag & 0xFFFFFF;
279 tag = tag >> 24;
280
909ce14f
MP
281 if (tag == MPLEX_BASE)
282 continue;
8d9dc9f9
AT
283
284 tag -= MPLEX_BASE;
285
286 if (tag != FERROR && tag != FINFO) {
909ce14f 287 rprintf(FERROR, "unexpected tag %d\n", tag);
65417579 288 exit_cleanup(RERR_STREAMIO);
8d9dc9f9
AT
289 }
290
909ce14f
MP
291 if (remaining > sizeof(line) - 1) {
292 rprintf(FERROR, "multiplexing overflow %d\n\n",
8d9dc9f9 293 remaining);
65417579 294 exit_cleanup(RERR_STREAMIO);
8d9dc9f9
AT
295 }
296
297 read_loop(fd, line, remaining);
298 line[remaining] = 0;
299
909ce14f 300 rprintf((enum logcode) tag, "%s", line);
8d9dc9f9
AT
301 remaining = 0;
302 }
303
304 return ret;
305}
306
307
909ce14f 308
4c36ddbe
AT
309/* do a buffered read from fd. don't return until all N bytes
310 have been read. If all N can't be read then exit with an error */
9dd891bb 311static void readfd (int fd, char *buffer, size_t N)
720b47f2 312{
6ba9279f 313 int ret;
06ce139f 314 size_t total=0;
6ba9279f 315
6ba9279f 316 while (total < N) {
8d9dc9f9
AT
317 io_flush();
318
7a55d06e 319 ret = read_unbuffered (fd, buffer + total, N-total);
6ba9279f 320 total += ret;
7f28dbee 321 }
1b7c47cb
AT
322
323 stats.total_read += total;
720b47f2
AT
324}
325
326
b7922338 327int32 read_int(int f)
720b47f2 328{
4c36ddbe 329 char b[4];
d730b113
AT
330 int32 ret;
331
4c36ddbe 332 readfd(f,b,4);
d730b113
AT
333 ret = IVAL(b,0);
334 if (ret == (int32)0xffffffff) return -1;
335 return ret;
720b47f2
AT
336}
337
71c46176 338int64 read_longint(int f)
3a6a366f
AT
339{
340 extern int remote_version;
71c46176 341 int64 ret;
3a6a366f
AT
342 char b[8];
343 ret = read_int(f);
71c46176 344
8de330a3
AT
345 if ((int32)ret != (int32)0xffffffff) {
346 return ret;
347 }
71c46176 348
3bee6733 349#ifdef NO_INT64
9486289c 350 rprintf(FERROR,"Integer overflow - attempted 64 bit offset\n");
65417579 351 exit_cleanup(RERR_UNSUPPORTED);
71c46176
AT
352#else
353 if (remote_version >= 16) {
4c36ddbe 354 readfd(f,b,8);
71c46176 355 ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
3a6a366f 356 }
71c46176
AT
357#endif
358
3a6a366f
AT
359 return ret;
360}
361
9dd891bb 362void read_buf(int f,char *buf,size_t len)
720b47f2 363{
4c36ddbe 364 readfd(f,buf,len);
720b47f2
AT
365}
366
9dd891bb 367void read_sbuf(int f,char *buf,size_t len)
575f2fca 368{
7a55d06e 369 read_buf (f,buf,len);
575f2fca
AT
370 buf[len] = 0;
371}
372
182dca5c
AT
373unsigned char read_byte(int f)
374{
4c36ddbe 375 unsigned char c;
7a55d06e 376 read_buf (f, (char *)&c, 1);
4c36ddbe 377 return c;
182dca5c 378}
720b47f2 379
ae682c3e 380/* write len bytes to fd */
9dd891bb 381static void writefd_unbuffered(int fd,char *buf,size_t len)
720b47f2 382{
06ce139f 383 size_t total = 0;
8d9dc9f9 384 fd_set w_fds, r_fds;
4c36ddbe 385 int fd_count, count;
8d9dc9f9 386 struct timeval tv;
720b47f2 387
90ba34e2
AT
388 err_list_push();
389
e44f9a12
AT
390 no_flush++;
391
4c36ddbe 392 while (total < len) {
8d9dc9f9
AT
393 FD_ZERO(&w_fds);
394 FD_ZERO(&r_fds);
395 FD_SET(fd,&w_fds);
554e0a8d 396 fd_count = fd;
4c36ddbe 397
554e0a8d
AT
398 if (io_error_fd != -1) {
399 FD_SET(io_error_fd,&r_fds);
400 if (io_error_fd > fd_count)
401 fd_count = io_error_fd;
8d9dc9f9
AT
402 }
403
8cd9fd4e 404 tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
8d9dc9f9 405 tv.tv_usec = 0;
4c36ddbe 406
554e0a8d
AT
407 errno = 0;
408
409 count = select(fd_count+1,
08f15335 410 io_error_fd != -1?&r_fds:NULL,
4c36ddbe 411 &w_fds,NULL,
8cd9fd4e 412 &tv);
4c36ddbe 413
a57873b7
AT
414 if (count == 0) {
415 check_timeout();
416 }
417
4c36ddbe 418 if (count <= 0) {
554e0a8d
AT
419 if (errno == EBADF) {
420 exit_cleanup(RERR_SOCKETIO);
421 }
8d9dc9f9
AT
422 continue;
423 }
4c36ddbe 424
554e0a8d
AT
425 if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) {
426 read_error_fd();
427 }
428
8d9dc9f9 429 if (FD_ISSET(fd, &w_fds)) {
06ce139f
MP
430 int ret;
431 size_t n = len-total;
f0359dd0 432 ret = write(fd,buf+total,n);
4c36ddbe
AT
433
434 if (ret == -1 && errno == EINTR) {
435 continue;
436 }
437
f0359dd0
AT
438 if (ret == -1 &&
439 (errno == EWOULDBLOCK || errno == EAGAIN)) {
e92ee128 440 msleep(1);
f0359dd0
AT
441 continue;
442 }
443
4c36ddbe 444 if (ret <= 0) {
ce6c7c63
MP
445 rprintf(FERROR,
446 "error writing %d unbuffered bytes"
447 " - exiting: %s\n", len,
448 strerror(errno));
65417579 449 exit_cleanup(RERR_STREAMIO);
4c36ddbe
AT
450 }
451
ef5d23eb
DD
452 /* Sleep after writing to limit I/O bandwidth */
453 if (bwlimit)
454 {
455 tv.tv_sec = 0;
456 tv.tv_usec = ret * 1000 / bwlimit;
457 while (tv.tv_usec > 1000000)
458 {
459 tv.tv_sec++;
460 tv.tv_usec -= 1000000;
461 }
462 select(0, NULL, NULL, NULL, &tv);
463 }
464
4c36ddbe 465 total += ret;
a800434a 466
4c36ddbe
AT
467 if (io_timeout)
468 last_io = time(NULL);
8d9dc9f9 469 }
4c36ddbe 470 }
e44f9a12
AT
471
472 no_flush--;
720b47f2
AT
473}
474
8d9dc9f9 475
d6dead6b
AT
476static char *io_buffer;
477static int io_buffer_count;
478
479void io_start_buffering(int fd)
480{
8d9dc9f9 481 if (io_buffer) return;
679e7657 482 multiplex_out_fd = fd;
ff41a59f 483 io_buffer = (char *)malloc(IO_BUFFER_SIZE);
d6dead6b
AT
484 if (!io_buffer) out_of_memory("writefd");
485 io_buffer_count = 0;
ff41a59f
AT
486}
487
488/* write an message to a multiplexed stream. If this fails then rsync
489 exits */
9dd891bb 490static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
ff41a59f
AT
491{
492 char buffer[4096];
06ce139f 493 size_t n = len;
8d9dc9f9 494
ff41a59f
AT
495 SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
496
6d7b6081
AT
497 if (n > (sizeof(buffer)-4)) {
498 n = sizeof(buffer)-4;
ff41a59f
AT
499 }
500
501 memcpy(&buffer[4], buf, n);
502 writefd_unbuffered(fd, buffer, n+4);
503
504 len -= n;
505 buf += n;
506
6d7b6081
AT
507 if (len) {
508 writefd_unbuffered(fd, buf, len);
509 }
d6dead6b
AT
510}
511
ff41a59f 512
8d9dc9f9 513void io_flush(void)
d6dead6b 514{
679e7657 515 int fd = multiplex_out_fd;
90ba34e2
AT
516
517 err_list_push();
518
e44f9a12 519 if (!io_buffer_count || no_flush) return;
8d9dc9f9
AT
520
521 if (io_multiplexing_out) {
0f3203c3 522 mplex_write(fd, FNONE, io_buffer, io_buffer_count);
8d9dc9f9 523 } else {
4c36ddbe 524 writefd_unbuffered(fd, io_buffer, io_buffer_count);
d6dead6b 525 }
8d9dc9f9
AT
526 io_buffer_count = 0;
527}
528
0ba48136
MP
529
530/* XXX: fd is ignored, which seems a little strange. */
8d9dc9f9
AT
531void io_end_buffering(int fd)
532{
533 io_flush();
534 if (!io_multiplexing_out) {
ff41a59f 535 free(io_buffer);
8d9dc9f9
AT
536 io_buffer = NULL;
537 }
d6dead6b
AT
538}
539
9dd891bb 540static void writefd(int fd,char *buf,size_t len)
d6dead6b 541{
1b7c47cb
AT
542 stats.total_written += len;
543
90ba34e2
AT
544 err_list_push();
545
554e0a8d 546 if (!io_buffer || fd != multiplex_out_fd) {
4c36ddbe
AT
547 writefd_unbuffered(fd, buf, len);
548 return;
549 }
d6dead6b
AT
550
551 while (len) {
552 int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
553 if (n > 0) {
554 memcpy(io_buffer+io_buffer_count, buf, n);
555 buf += n;
556 len -= n;
557 io_buffer_count += n;
558 }
559
8d9dc9f9 560 if (io_buffer_count == IO_BUFFER_SIZE) io_flush();
d6dead6b 561 }
d6dead6b 562}
720b47f2
AT
563
564
b7922338 565void write_int(int f,int32 x)
720b47f2 566{
8d9dc9f9
AT
567 char b[4];
568 SIVAL(b,0,x);
4c36ddbe 569 writefd(f,b,4);
720b47f2
AT
570}
571
7a24c346
MP
572
573/*
574 * Note: int64 may actually be a 32-bit type if ./configure couldn't find any
575 * 64-bit types on this platform.
576 */
71c46176 577void write_longint(int f, int64 x)
3a6a366f
AT
578{
579 extern int remote_version;
580 char b[8];
3a6a366f
AT
581
582 if (remote_version < 16 || x <= 0x7FFFFFFF) {
583 write_int(f, (int)x);
584 return;
585 }
586
8de330a3 587 write_int(f, (int32)0xFFFFFFFF);
3a6a366f
AT
588 SIVAL(b,0,(x&0xFFFFFFFF));
589 SIVAL(b,4,((x>>32)&0xFFFFFFFF));
590
4c36ddbe 591 writefd(f,b,8);
3a6a366f
AT
592}
593
9dd891bb 594void write_buf(int f,char *buf,size_t len)
720b47f2 595{
4c36ddbe 596 writefd(f,buf,len);
720b47f2
AT
597}
598
f0fca04e 599/* write a string to the connection */
6e4fb64e 600static void write_sbuf(int f,char *buf)
f0fca04e
AT
601{
602 write_buf(f, buf, strlen(buf));
603}
604
720b47f2 605
182dca5c
AT
606void write_byte(int f,unsigned char c)
607{
f0fca04e 608 write_buf(f,(char *)&c,1);
182dca5c
AT
609}
610
7a55d06e
MP
611
612
9dd891bb 613int read_line(int f, char *buf, size_t maxlen)
f0fca04e
AT
614{
615 while (maxlen) {
528bfcd7 616 buf[0] = 0;
f0fca04e 617 read_buf(f, buf, 1);
528bfcd7 618 if (buf[0] == 0) return 0;
f0fca04e
AT
619 if (buf[0] == '\n') {
620 buf[0] = 0;
621 break;
622 }
623 if (buf[0] != '\r') {
624 buf++;
625 maxlen--;
626 }
627 }
628 if (maxlen == 0) {
629 *buf = 0;
630 return 0;
631 }
528bfcd7 632
f0fca04e
AT
633 return 1;
634}
635
636
637void io_printf(int fd, const char *format, ...)
638{
639 va_list ap;
640 char buf[1024];
641 int len;
642
643 va_start(ap, format);
8950ac03 644 len = vsnprintf(buf, sizeof(buf), format, ap);
f0fca04e
AT
645 va_end(ap);
646
65417579 647 if (len < 0) exit_cleanup(RERR_STREAMIO);
f0fca04e
AT
648
649 write_sbuf(fd, buf);
650}
8d9dc9f9
AT
651
652
653/* setup for multiplexing an error stream with the data stream */
654void io_start_multiplex_out(int fd)
655{
679e7657
AT
656 multiplex_out_fd = fd;
657 io_flush();
8d9dc9f9
AT
658 io_start_buffering(fd);
659 io_multiplexing_out = 1;
660}
661
662/* setup for multiplexing an error stream with the data stream */
663void io_start_multiplex_in(int fd)
664{
679e7657
AT
665 multiplex_in_fd = fd;
666 io_flush();
8d9dc9f9
AT
667 io_multiplexing_in = 1;
668}
669
554e0a8d 670/* write an message to the multiplexed error stream */
9dd891bb 671int io_multiplex_write(enum logcode code, char *buf, size_t len)
8d9dc9f9
AT
672{
673 if (!io_multiplexing_out) return 0;
674
675 io_flush();
1b7c47cb 676 stats.total_written += (len+4);
ff41a59f 677 mplex_write(multiplex_out_fd, code, buf, len);
8d9dc9f9
AT
678 return 1;
679}
680
554e0a8d
AT
681/* stop output multiplexing */
682void io_multiplexing_close(void)
683{
684 io_multiplexing_out = 0;
685}
686