Die if we sent --max-delete=0 to a receiving side that is too old.
[rsync/rsync.git] / compat.c
1 /*
2  * Compatibility routines for older rsync protocol versions.
3  *
4  * Copyright (C) Andrew Tridgell 1996
5  * Copyright (C) Paul Mackerras 1996
6  * Copyright (C) 2004, 2005, 2006 Wayne Davison
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22
23 #include "rsync.h"
24
25 int remote_protocol = 0;
26
27 extern int verbose;
28 extern int am_server;
29 extern int am_sender;
30 extern int inplace;
31 extern int fuzzy_basis;
32 extern int read_batch;
33 extern int max_delete;
34 extern int checksum_seed;
35 extern int basis_dir_cnt;
36 extern int prune_empty_dirs;
37 extern int protocol_version;
38 extern char *dest_option;
39
40 void setup_protocol(int f_out,int f_in)
41 {
42         if (remote_protocol == 0) {
43                 if (!read_batch)
44                         write_int(f_out, protocol_version);
45                 remote_protocol = read_int(f_in);
46                 if (protocol_version > remote_protocol)
47                         protocol_version = remote_protocol;
48         }
49         if (read_batch && remote_protocol > protocol_version) {
50                 rprintf(FERROR, "The protocol version in the batch file is too new (%d > %d).\n",
51                         remote_protocol, protocol_version);
52                 exit_cleanup(RERR_PROTOCOL);
53         }
54
55         if (verbose > 3) {
56                 rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
57                         am_server? "Server" : "Client", remote_protocol, protocol_version);
58         }
59         if (remote_protocol < MIN_PROTOCOL_VERSION
60          || remote_protocol > MAX_PROTOCOL_VERSION) {
61                 rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
62                 rprintf(FERROR,"(see the rsync man page for an explanation)\n");
63                 exit_cleanup(RERR_PROTOCOL);
64         }
65         if (remote_protocol < OLD_PROTOCOL_VERSION) {
66                 rprintf(FINFO,"%s is very old version of rsync, upgrade recommended.\n",
67                         am_server? "Client" : "Server");
68         }
69         if (protocol_version < MIN_PROTOCOL_VERSION) {
70                 rprintf(FERROR, "--protocol must be at least %d on the %s.\n",
71                         MIN_PROTOCOL_VERSION, am_server? "Server" : "Client");
72                 exit_cleanup(RERR_PROTOCOL);
73         }
74         if (protocol_version > PROTOCOL_VERSION) {
75                 rprintf(FERROR, "--protocol must be no more than %d on the %s.\n",
76                         PROTOCOL_VERSION, am_server? "Server" : "Client");
77                 exit_cleanup(RERR_PROTOCOL);
78         }
79
80         if (protocol_version < 30) {
81                 if (max_delete == 0 && am_sender) {
82                         rprintf(FERROR,
83                             "--max-delete=0 requires protocol 30 or higher"
84                             " (negotiated %d).\n",
85                             protocol_version);
86                         exit_cleanup(RERR_PROTOCOL);
87                 }
88         }
89
90         if (protocol_version < 29) {
91                 if (fuzzy_basis) {
92                         rprintf(FERROR,
93                             "--fuzzy requires protocol 29 or higher"
94                             " (negotiated %d).\n",
95                             protocol_version);
96                         exit_cleanup(RERR_PROTOCOL);
97                 }
98
99                 if (basis_dir_cnt && inplace) {
100                         rprintf(FERROR,
101                             "%s with --inplace requires protocol 29 or higher"
102                             " (negotiated %d).\n",
103                             dest_option, protocol_version);
104                         exit_cleanup(RERR_PROTOCOL);
105                 }
106
107                 if (basis_dir_cnt > 1) {
108                         rprintf(FERROR,
109                             "Using more than one %s option requires protocol"
110                             " 29 or higher (negotiated %d).\n",
111                             dest_option, protocol_version);
112                         exit_cleanup(RERR_PROTOCOL);
113                 }
114
115                 if (prune_empty_dirs) {
116                         rprintf(FERROR,
117                             "--prune-empty-dirs requires protocol 29 or higher"
118                             " (negotiated %d).\n",
119                             protocol_version);
120                         exit_cleanup(RERR_PROTOCOL);
121                 }
122         }
123
124         if (am_server) {
125                 if (!checksum_seed)
126                         checksum_seed = time(NULL);
127                 write_int(f_out, checksum_seed);
128         } else {
129                 checksum_seed = read_int(f_in);
130         }
131 }