rsync.c was getting a bit unwieldy so I split the code into 3 modules,
[rsync/rsync.git] / receiver.c
1 /* 
2    Copyright (C) Andrew Tridgell 1996
3    Copyright (C) Paul Mackerras 1996
4    
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14    
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "rsync.h"
21
22 extern int verbose;
23 extern int recurse;
24 extern int delete_mode;
25 extern int remote_version;
26 extern int csum_length;
27 extern struct stats stats;
28 extern int dry_run;
29 extern int am_server;
30 extern int relative_paths;
31 extern int preserve_hard_links;
32 extern int cvs_exclude;
33 extern int io_error;
34 extern char *tmpdir;
35
36
37 static struct delete_list {
38         dev_t dev;
39         INO_T inode;
40 } *delete_list;
41 static int dlist_len, dlist_alloc_len;
42
43
44 /* yuck! This function wouldn't have been necessary if I had the sorting
45    algorithm right. Unfortunately fixing the sorting algorithm would introduce
46    a backward incompatibility as file list indexes are sent over the link.
47 */
48 static int delete_already_done(struct file_list *flist,int j)
49 {
50         int i;
51         STRUCT_STAT st;
52
53         if (link_stat(f_name(flist->files[j]), &st)) return 1;
54
55         for (i=0;i<dlist_len;i++) {
56                 if (st.st_ino == delete_list[i].inode &&
57                     st.st_dev == delete_list[i].dev)
58                         return 1;
59         }
60
61         return 0;
62 }
63
64 static void add_delete_entry(struct file_struct *file)
65 {
66         if (dlist_len == dlist_alloc_len) {
67                 dlist_alloc_len += 1024;
68                 delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
69                 if (!delete_list) out_of_memory("add_delete_entry");
70         }
71
72         delete_list[dlist_len].dev = file->dev;
73         delete_list[dlist_len].inode = file->inode;
74         dlist_len++;
75
76         if (verbose > 3)
77                 rprintf(FINFO,"added %s to delete list\n", f_name(file));
78 }
79
80 static void delete_one(struct file_struct *f)
81 {
82         if (!S_ISDIR(f->mode)) {
83                 if (do_unlink(f_name(f)) != 0) {
84                         rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
85                 } else if (verbose) {
86                         rprintf(FINFO,"deleting %s\n",f_name(f));
87                 }
88         } else {    
89                 if (do_rmdir(f_name(f)) != 0) {
90                         if (errno != ENOTEMPTY && errno != EEXIST)
91                                 rprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
92                 } else if (verbose) {
93                         rprintf(FINFO,"deleting directory %s\n",f_name(f));      
94                 }
95         }
96 }
97
98
99
100
101 /* this deletes any files on the receiving side that are not present
102    on the sending side. For version 1.6.4 I have changed the behaviour
103    to match more closely what most people seem to expect of this option */
104 static void delete_files(struct file_list *flist)
105 {
106         struct file_list *local_file_list;
107         int i, j;
108         char *name;
109
110         if (cvs_exclude)
111                 add_cvs_excludes();
112
113         if (io_error) {
114                 rprintf(FINFO,"IO error encountered - skipping file deletion\n");
115                 return;
116         }
117
118         for (j=0;j<flist->count;j++) {
119                 if (!S_ISDIR(flist->files[j]->mode) || 
120                     !(flist->files[j]->flags & FLAG_DELETE)) continue;
121
122                 if (remote_version < 19 &&
123                     delete_already_done(flist, j)) continue;
124
125                 name = strdup(f_name(flist->files[j]));
126
127                 if (!(local_file_list = send_file_list(-1,1,&name))) {
128                         free(name);
129                         continue;
130                 }
131
132                 if (verbose > 1)
133                         rprintf(FINFO,"deleting in %s\n", name);
134
135                 for (i=local_file_list->count-1;i>=0;i--) {
136                         if (!local_file_list->files[i]->basename) continue;
137                         if (remote_version < 19 &&
138                             S_ISDIR(local_file_list->files[i]->mode))
139                                 add_delete_entry(local_file_list->files[i]);
140                         if (-1 == flist_find(flist,local_file_list->files[i])) {
141                                 delete_one(local_file_list->files[i]);
142                         }    
143                 }
144                 flist_free(local_file_list);
145                 free(name);
146         }
147 }
148
149
150 static int get_tmpname(char *fnametmp, char *fname)
151 {
152         char *f;
153
154         /* open tmp file */
155         if (tmpdir) {
156                 f = strrchr(fname,'/');
157                 if (f == NULL) 
158                         f = fname;
159                 else 
160                         f++;
161                 if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
162                         rprintf(FERROR,"filename too long\n");
163                         return 0;
164                 }
165                 slprintf(fnametmp,MAXPATHLEN-1, "%s/.%s.XXXXXX",tmpdir,f);
166                 return 1;
167         } 
168
169         f = strrchr(fname,'/');
170
171         if (strlen(fname)+9 > MAXPATHLEN) {
172                 rprintf(FERROR,"filename too long\n");
173                 return 0;
174         }
175
176         if (f) {
177                 *f = 0;
178                 slprintf(fnametmp,MAXPATHLEN-1,"%s/.%s.XXXXXX",
179                          fname,f+1);
180                 *f = '/';
181         } else {
182                 slprintf(fnametmp,MAXPATHLEN-1,".%s.XXXXXX",fname);
183         }
184
185         return 1;
186 }
187
188
189 static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
190                         OFF_T total_size)
191 {
192         int i,n,remainder,len,count;
193         OFF_T offset = 0;
194         OFF_T offset2;
195         char *data;
196         static char file_sum1[MD4_SUM_LENGTH];
197         static char file_sum2[MD4_SUM_LENGTH];
198         char *map=NULL;
199         
200         count = read_int(f_in);
201         n = read_int(f_in);
202         remainder = read_int(f_in);
203         
204         sum_init();
205         
206         for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
207
208                 show_progress(offset, total_size);
209
210                 if (i > 0) {
211                         extern int cleanup_got_literal;
212
213                         if (verbose > 3) {
214                                 rprintf(FINFO,"data recv %d at %d\n",
215                                         i,(int)offset);
216                         }
217
218                         stats.literal_data += i;
219                         cleanup_got_literal = 1;
220       
221                         sum_update(data,i);
222
223                         if (fd != -1 && write_file(fd,data,i) != i) {
224                                 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
225                                 exit_cleanup(1);
226                         }
227                         offset += i;
228                         continue;
229                 } 
230
231                 i = -(i+1);
232                 offset2 = i*n;
233                 len = n;
234                 if (i == count-1 && remainder != 0)
235                         len = remainder;
236                 
237                 stats.matched_data += len;
238                 
239                 if (verbose > 3)
240                         rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
241                                 i,len,(int)offset2,(int)offset);
242                 
243                 map = map_ptr(buf,offset2,len);
244                 
245                 see_token(map, len);
246                 sum_update(map,len);
247                 
248                 if (fd != -1 && write_file(fd,map,len) != len) {
249                         rprintf(FERROR,"write failed on %s : %s\n",
250                                 fname,strerror(errno));
251                         exit_cleanup(1);
252                 }
253                 offset += len;
254         }
255
256         end_progress();
257
258         if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
259                 rprintf(FERROR,"write failed on %s : %s\n",
260                         fname,strerror(errno));
261                 exit_cleanup(1);
262         }
263
264         sum_end(file_sum1);
265
266         if (remote_version >= 14) {
267                 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
268                 if (verbose > 2) {
269                         rprintf(FINFO,"got file_sum\n");
270                 }
271                 if (fd != -1 && 
272                     memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
273                         return 0;
274                 }
275         }
276         return 1;
277 }
278
279
280
281 int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
282 {  
283         int fd1,fd2;
284         STRUCT_STAT st;
285         char *fname;
286         char fnametmp[MAXPATHLEN];
287         struct map_struct *buf;
288         int i;
289         struct file_struct *file;
290         int phase=0;
291         int recv_ok;
292         
293         if (verbose > 2) {
294                 rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
295         }
296
297         if (recurse && delete_mode && !local_name && flist->count>0) {
298                 delete_files(flist);
299         }
300
301         while (1) {      
302                 cleanup_disable();
303
304                 i = read_int(f_in);
305                 if (i == -1) {
306                         if (phase==0 && remote_version >= 13) {
307                                 phase++;
308                                 csum_length = SUM_LENGTH;
309                                 if (verbose > 2)
310                                         rprintf(FINFO,"recv_files phase=%d\n",phase);
311                                 write_int(f_gen,-1);
312                                 continue;
313                         }
314                         break;
315                 }
316
317                 if (i < 0 || i >= flist->count) {
318                         rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n", 
319                                 i, flist->count);
320                         exit_cleanup(1);
321                 }
322
323                 file = flist->files[i];
324                 fname = f_name(file);
325
326                 stats.num_transferred_files++;
327                 stats.total_transferred_size += file->length;
328
329                 if (local_name)
330                         fname = local_name;
331
332                 if (dry_run) {
333                         if (!am_server && verbose)
334                                 rprintf(FINFO,"%s\n",fname);
335                         continue;
336                 }
337
338                 if (verbose > 2)
339                         rprintf(FINFO,"recv_files(%s)\n",fname);
340
341                 /* open the file */  
342                 fd1 = open(fname,O_RDONLY);
343
344                 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
345                         rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
346                         receive_data(f_in,NULL,-1,NULL,file->length);
347                         close(fd1);
348                         continue;
349                 }
350
351                 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
352                         rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
353                         receive_data(f_in,NULL,-1,NULL,file->length);
354                         close(fd1);
355                         continue;
356                 }
357
358                 if (fd1 != -1 && st.st_size > 0) {
359                         buf = map_file(fd1,st.st_size);
360                         if (verbose > 2)
361                                 rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
362                 } else {
363                         buf = NULL;
364                 }
365
366                 if (!get_tmpname(fnametmp,fname)) {
367                         if (buf) unmap_file(buf);
368                         if (fd1 != -1) close(fd1);
369                         continue;
370                 }
371
372                 if (NULL == do_mktemp(fnametmp)) {
373                         rprintf(FERROR,"mktemp %s failed\n",fnametmp);
374                         receive_data(f_in,buf,-1,NULL,file->length);
375                         if (buf) unmap_file(buf);
376                         if (fd1 != -1) close(fd1);
377                         continue;
378                 }
379
380                 /* we initially set the perms without the
381                    setuid/setgid bits to ensure that there is no race
382                    condition. They are then correctly updated after
383                    the lchown. Thanks to snabb@epipe.fi for pointing
384                    this out */
385                 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
386                               file->mode & ACCESSPERMS);
387
388                 if (fd2 == -1 && relative_paths && errno == ENOENT && 
389                     create_directory_path(fnametmp) == 0) {
390                         fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
391                                       file->mode & ACCESSPERMS);
392                 }
393                 if (fd2 == -1) {
394                         rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
395                         receive_data(f_in,buf,-1,NULL,file->length);
396                         if (buf) unmap_file(buf);
397                         if (fd1 != -1) close(fd1);
398                         continue;
399                 }
400       
401                 cleanup_set(fnametmp, fname, file);
402
403                 if (!am_server && verbose)
404                         rprintf(FINFO,"%s\n",fname);
405                 
406                 /* recv file data */
407                 recv_ok = receive_data(f_in,buf,fd2,fname,file->length);
408                 
409                 if (buf) unmap_file(buf);
410                 if (fd1 != -1) {
411                         close(fd1);
412                 }
413                 close(fd2);
414                 
415                 if (verbose > 2)
416                         rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
417
418                 finish_transfer(fname, fnametmp, file);
419                 
420                 cleanup_disable();
421                 
422                 if (!recv_ok) {
423                         if (csum_length == SUM_LENGTH) {
424                                 rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
425                                         fname);
426                         } else {
427                                 if (verbose > 1)
428                                         rprintf(FINFO,"redoing %s(%d)\n",fname,i);
429                                 write_int(f_gen,i);
430                         }
431                 }
432         }
433
434         if (preserve_hard_links)
435                 do_hard_links(flist);
436
437         /* now we need to fix any directory permissions that were 
438            modified during the transfer */
439         for (i = 0; i < flist->count; i++) {
440                 file = flist->files[i];
441                 if (!file->basename || !S_ISDIR(file->mode)) continue;
442                 recv_generator(f_name(file),flist,i,-1);
443         }
444
445         if (verbose > 2)
446                 rprintf(FINFO,"recv_files finished\n");
447         
448         return 0;
449 }
450