2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
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.
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.
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.
22 extern int csum_length;
26 extern int always_checksum;
27 extern time_t starttime;
29 extern int remote_version;
31 extern char *backup_suffix;
34 extern int whole_file;
35 extern int block_size;
36 extern int update_only;
37 extern int make_backups;
38 extern int preserve_links;
39 extern int preserve_hard_links;
40 extern int preserve_perms;
41 extern int preserve_devices;
42 extern int preserve_uid;
43 extern int preserve_gid;
44 extern int preserve_times;
46 extern int ignore_times;
48 extern int delete_mode;
49 extern int cvs_exclude;
51 extern int relative_paths;
52 extern int io_timeout;
58 static void free_sums(struct sum_struct *s)
60 if (s->sums) free(s->sums);
66 * delete a file or directory. If force_delet is set then delete
69 static int delete_file(char *fname)
74 extern int force_delete;
79 if (do_unlink(fname) == 0 || errno == ENOENT) return 0;
82 ret = do_lstat(fname, &st);
84 ret = do_stat(fname, &st);
87 rprintf(FERROR,"stat(%s) : %s\n", fname, strerror(errno));
91 if (!S_ISDIR(st.st_mode)) {
92 rprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno));
96 if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
97 if (!force_delete || !recurse ||
98 (errno != ENOTEMPTY && errno != EEXIST)) {
99 rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
103 /* now we do a recsursive delete on the directory ... */
106 rprintf(FERROR,"opendir(%s): %s\n",
107 fname,strerror(errno));
111 for (di=readdir(d); di; di=readdir(d)) {
112 char *dname = d_name(di);
113 if (strcmp(dname,".")==0 ||
114 strcmp(dname,"..")==0)
116 slprintf(buf, sizeof(buf)-1, "%s/%s", fname, dname);
118 rprintf(FINFO,"deleting %s\n", buf);
119 if (delete_file(buf) != 0) {
127 if (do_rmdir(fname) != 0) {
128 rprintf(FERROR,"rmdir(%s) : %s\n", fname, strerror(errno));
136 send a sums struct down a fd
138 static void send_sums(struct sum_struct *s,int f_out)
142 /* tell the other guy how many we are going to be doing and how many
143 bytes there are in the last chunk */
144 write_int(f_out,s?s->count:0);
145 write_int(f_out,s?s->n:block_size);
146 write_int(f_out,s?s->remainder:0);
148 for (i=0;i<s->count;i++) {
149 write_int(f_out,s->sums[i].sum1);
150 write_buf(f_out,s->sums[i].sum2,csum_length);
156 generate a stream of signatures/checksums that describe a buffer
158 generate approximately one checksum every n bytes
160 static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
163 struct sum_struct *s;
166 int remainder = (len%block_len);
169 count = (len+(block_len-1))/block_len;
171 s = (struct sum_struct *)malloc(sizeof(*s));
172 if (!s) out_of_memory("generate_sums");
175 s->remainder = remainder;
185 rprintf(FINFO,"count=%d rem=%d n=%d flength=%d\n",
186 s->count,s->remainder,s->n,(int)s->flength);
188 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
189 if (!s->sums) out_of_memory("generate_sums");
191 for (i=0;i<count;i++) {
193 char *map = map_ptr(buf,offset,n1);
195 s->sums[i].sum1 = get_checksum1(map,n1);
196 get_checksum2(map,n1,s->sums[i].sum2);
198 s->sums[i].offset = offset;
203 rprintf(FINFO,"chunk[%d] offset=%d len=%d sum1=%08x\n",
204 i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
215 receive the checksums for a buffer
217 static struct sum_struct *receive_sums(int f)
219 struct sum_struct *s;
223 s = (struct sum_struct *)malloc(sizeof(*s));
224 if (!s) out_of_memory("receive_sums");
226 s->count = read_int(f);
228 s->remainder = read_int(f);
232 rprintf(FINFO,"count=%d n=%d rem=%d\n",
233 s->count,s->n,s->remainder);
238 s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
239 if (!s->sums) out_of_memory("receive_sums");
241 for (i=0;i<s->count;i++) {
242 s->sums[i].sum1 = read_int(f);
243 read_buf(f,s->sums[i].sum2,csum_length);
245 s->sums[i].offset = offset;
248 if (i == s->count-1 && s->remainder != 0) {
249 s->sums[i].len = s->remainder;
251 s->sums[i].len = s->n;
253 offset += s->sums[i].len;
256 rprintf(FINFO,"chunk[%d] len=%d offset=%d sum1=%08x\n",
257 i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
266 static int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
271 extern int am_daemon;
273 if (dry_run) return 0;
276 if (link_stat(fname,&st2) != 0) {
277 rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
283 if (preserve_times && !S_ISLNK(st->st_mode) &&
284 st->st_mtime != file->modtime) {
286 if (set_modtime(fname,file->modtime) != 0) {
287 rprintf(FERROR,"failed to set times on %s : %s\n",
288 fname,strerror(errno));
294 if (preserve_perms && !S_ISLNK(st->st_mode) &&
295 st->st_mode != file->mode) {
297 if (do_chmod(fname,file->mode) != 0) {
298 rprintf(FERROR,"failed to set permissions on %s : %s\n",
299 fname,strerror(errno));
305 if ((am_root || !am_daemon) &&
306 ((am_root && preserve_uid && st->st_uid != file->uid) ||
307 (preserve_gid && st->st_gid != file->gid))) {
309 (am_root&&preserve_uid)?file->uid:-1,
310 preserve_gid?file->gid:-1) != 0) {
311 if (preserve_uid && st->st_uid != file->uid)
313 if (verbose>1 || preserve_uid)
314 rprintf(FERROR,"chown %s : %s\n",
315 fname,strerror(errno));
321 if (verbose > 1 && report) {
323 rprintf(FINFO,"%s\n",fname);
325 rprintf(FINFO,"%s is uptodate\n",fname);
331 /* choose whether to skip a particular file */
332 static int skip_file(char *fname,
333 struct file_struct *file, STRUCT_STAT *st)
335 if (st->st_size != file->length) {
339 /* if always checksum is set then we use the checksum instead
340 of the file time to determine whether to sync */
341 if (always_checksum && S_ISREG(st->st_mode)) {
342 char sum[MD4_SUM_LENGTH];
343 file_checksum(fname,sum,st->st_size);
344 return (memcmp(sum,file->sum,csum_length) == 0);
351 return (st->st_mtime == file->modtime);
355 /* use a larger block size for really big files */
356 int adapt_block_size(struct file_struct *file, int bsize)
358 int ret = file->length / (10000); /* rough heuristic */
359 ret = ret & ~15; /* multiple of 16 */
360 if (ret < bsize) ret = bsize;
361 if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
365 void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
369 struct map_struct *buf;
370 struct sum_struct *s;
372 struct file_struct *file = flist->files[i];
375 rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
377 statret = link_stat(fname,&st);
379 if (S_ISDIR(file->mode)) {
381 if (statret == 0 && !S_ISDIR(st.st_mode)) {
382 if (do_unlink(fname) != 0) {
383 rprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
388 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
389 if (!(relative_paths && errno==ENOENT &&
390 create_directory_path(fname)==0 &&
391 do_mkdir(fname,file->mode)==0)) {
392 rprintf(FERROR,"mkdir %s : %s (2)\n",
393 fname,strerror(errno));
396 if (set_perms(fname,file,NULL,0) && verbose)
397 rprintf(FINFO,"%s/\n",fname);
401 if (preserve_links && S_ISLNK(file->mode)) {
403 char lnk[MAXPATHLEN];
406 l = readlink(fname,lnk,MAXPATHLEN-1);
409 if (strcmp(lnk,file->link) == 0) {
410 set_perms(fname,file,&st,1);
416 if (do_symlink(file->link,fname) != 0) {
417 rprintf(FERROR,"link %s -> %s : %s\n",
418 fname,file->link,strerror(errno));
420 set_perms(fname,file,NULL,0);
422 rprintf(FINFO,"%s -> %s\n",
430 if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
432 st.st_mode != file->mode ||
433 st.st_rdev != file->rdev) {
436 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
437 fname,(int)file->mode,(int)file->rdev);
438 if (do_mknod(fname,file->mode,file->rdev) != 0) {
439 rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
441 set_perms(fname,file,NULL,0);
443 rprintf(FINFO,"%s\n",fname);
446 set_perms(fname,file,&st,1);
452 if (preserve_hard_links && check_hard_link(file)) {
454 rprintf(FINFO,"%s is a hard link\n",f_name(file));
458 if (!S_ISREG(file->mode)) {
459 rprintf(FINFO,"skipping non-regular file %s\n",fname);
464 if (errno == ENOENT) {
466 if (!dry_run) send_sums(NULL,f_out);
469 rprintf(FERROR,"recv_generator failed to open %s\n",fname);
474 if (!S_ISREG(st.st_mode)) {
475 if (delete_file(fname) != 0) {
479 /* now pretend the file didn't exist */
481 if (!dry_run) send_sums(NULL,f_out);
485 if (update_only && st.st_mtime > file->modtime) {
487 rprintf(FINFO,"%s is newer\n",fname);
491 if (skip_file(fname, file, &st)) {
492 set_perms(fname,file,&st,1);
503 send_sums(NULL,f_out);
508 fd = open(fname,O_RDONLY);
511 rprintf(FERROR,"failed to open %s : %s\n",fname,strerror(errno));
512 rprintf(FERROR,"skipping %s\n",fname);
516 if (st.st_size > 0) {
517 buf = map_file(fd,st.st_size);
523 rprintf(FINFO,"gen mapped %s of size %d\n",fname,(int)st.st_size);
525 s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
528 rprintf(FINFO,"sending sums for %d\n",i);
534 if (buf) unmap_file(buf);
541 static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname)
543 int i,n,remainder,len,count;
547 static char file_sum1[MD4_SUM_LENGTH];
548 static char file_sum2[MD4_SUM_LENGTH];
551 count = read_int(f_in);
553 remainder = read_int(f_in);
557 for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
560 rprintf(FINFO,"data recv %d at %d\n",i,(int)offset);
564 if (fd != -1 && write_file(fd,data,i) != i) {
565 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
573 if (i == count-1 && remainder != 0)
577 rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
578 i,len,(int)offset2,(int)offset);
580 map = map_ptr(buf,offset2,len);
585 if (fd != -1 && write_file(fd,map,len) != len) {
586 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
593 if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
594 rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
600 if (remote_version >= 14) {
601 read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
603 rprintf(FINFO,"got file_sum\n");
604 if (fd != -1 && memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0)
611 static void delete_one(struct file_struct *f)
613 if (!S_ISDIR(f->mode)) {
614 if (do_unlink(f_name(f)) != 0) {
615 rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
616 } else if (verbose) {
617 rprintf(FINFO,"deleting %s\n",f_name(f));
620 if (do_rmdir(f_name(f)) != 0) {
621 if (errno != ENOTEMPTY && errno != EEXIST)
622 rprintf(FERROR,"rmdir %s : %s\n",f_name(f),strerror(errno));
623 } else if (verbose) {
624 rprintf(FINFO,"deleting directory %s\n",f_name(f));
631 static struct delete_list {
635 static int dlist_len, dlist_alloc_len;
637 static void add_delete_entry(struct file_struct *file)
639 if (dlist_len == dlist_alloc_len) {
640 dlist_alloc_len += 1024;
641 delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
642 if (!delete_list) out_of_memory("add_delete_entry");
645 delete_list[dlist_len].dev = file->dev;
646 delete_list[dlist_len].inode = file->inode;
650 rprintf(FINFO,"added %s to delete list\n", f_name(file));
653 /* yuck! This function wouldn't have been necessary if I had the sorting
654 algorithm right. Unfortunately fixing the sorting algorithm would introduce
655 a backward incompatibility as file list indexes are sent over the link.
657 static int delete_already_done(struct file_list *flist,int j)
662 if (link_stat(f_name(flist->files[j]), &st)) return 1;
664 for (i=0;i<dlist_len;i++) {
665 if (st.st_ino == delete_list[i].inode &&
666 st.st_dev == delete_list[i].dev)
674 /* this deletes any files on the receiving side that are not present
675 on the sending side. For version 1.6.4 I have changed the behaviour
676 to match more closely what most people seem to expect of this option */
677 static void delete_files(struct file_list *flist)
679 struct file_list *local_file_list;
687 rprintf(FINFO,"IO error encountered - skipping file deletion\n");
691 for (j=0;j<flist->count;j++) {
692 if (!S_ISDIR(flist->files[j]->mode) ||
693 !(flist->files[j]->flags & FLAG_DELETE)) continue;
695 if (remote_version < 19 &&
696 delete_already_done(flist, j)) continue;
698 name = strdup(f_name(flist->files[j]));
700 if (!(local_file_list = send_file_list(-1,1,&name))) {
706 rprintf(FINFO,"deleting in %s\n", name);
708 for (i=local_file_list->count-1;i>=0;i--) {
709 if (!local_file_list->files[i]->basename) continue;
710 if (remote_version < 19 &&
711 S_ISDIR(local_file_list->files[i]->mode))
712 add_delete_entry(local_file_list->files[i]);
713 if (-1 == flist_find(flist,local_file_list->files[i])) {
714 delete_one(local_file_list->files[i]);
717 flist_free(local_file_list);
722 static char *cleanup_fname;
724 void exit_cleanup(int code)
728 do_unlink(cleanup_fname);
729 signal(SIGUSR1, SIG_IGN);
742 int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
747 char fnametmp[MAXPATHLEN];
748 struct map_struct *buf;
750 struct file_struct *file;
755 rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
758 if (recurse && delete_mode && !local_name && flist->count>0) {
766 if (phase==0 && remote_version >= 13) {
768 csum_length = SUM_LENGTH;
770 rprintf(FINFO,"recv_files phase=%d\n",phase);
777 file = flist->files[i];
778 fname = f_name(file);
784 if (!am_server && verbose)
785 printf("%s\n",fname);
790 rprintf(FINFO,"recv_files(%s)\n",fname);
793 fd1 = open(fname,O_RDONLY);
795 if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
796 rprintf(FERROR,"fstat %s : %s\n",fname,strerror(errno));
797 receive_data(f_in,NULL,-1,NULL);
802 if (fd1 != -1 && !S_ISREG(st.st_mode)) {
803 rprintf(FERROR,"%s : not a regular file (recv_files)\n",fname);
804 receive_data(f_in,NULL,-1,NULL);
809 if (fd1 != -1 && st.st_size > 0) {
810 buf = map_file(fd1,st.st_size);
812 rprintf(FINFO,"recv mapped %s of size %d\n",fname,(int)st.st_size);
820 f = strrchr(fname,'/');
825 if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
826 rprintf(FERROR,"filename too long\n");
827 if (buf) unmap_file(buf);
831 slprintf(fnametmp,sizeof(fnametmp)-1, "%s/.%s.XXXXXX",tmpdir,f);
833 char *f = strrchr(fname,'/');
835 if (strlen(fname)+9 > MAXPATHLEN) {
836 rprintf(FERROR,"filename too long\n");
837 if (buf) unmap_file(buf);
844 slprintf(fnametmp,sizeof(fnametmp)-1,"%s/.%s.XXXXXX",fname,f+1);
847 slprintf(fnametmp,sizeof(fnametmp)-1,".%s.XXXXXX",fname);
850 if (NULL == do_mktemp(fnametmp)) {
851 rprintf(FERROR,"mktemp %s failed\n",fnametmp);
852 receive_data(f_in,buf,-1,NULL);
853 if (buf) unmap_file(buf);
857 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
858 if (fd2 == -1 && relative_paths && errno == ENOENT &&
859 create_directory_path(fnametmp) == 0) {
860 fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,file->mode);
863 rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
864 receive_data(f_in,buf,-1,NULL);
865 if (buf) unmap_file(buf);
870 cleanup_fname = fnametmp;
872 if (!am_server && verbose)
873 printf("%s\n",fname);
876 recv_ok = receive_data(f_in,buf,fd2,fname);
878 if (buf) unmap_file(buf);
885 rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
888 char fnamebak[MAXPATHLEN];
889 if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
890 rprintf(FERROR,"backup filename too long\n");
893 slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
894 if (do_rename(fname,fnamebak) != 0 && errno != ENOENT) {
895 rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
900 /* move tmp file over real file */
901 if (do_rename(fnametmp,fname) != 0) {
902 if (errno == EXDEV) {
903 /* rename failed on cross-filesystem link.
904 Copy the file instead. */
905 if (copy_file(fnametmp,fname, file->mode)) {
906 rprintf(FERROR,"copy %s -> %s : %s\n",
907 fnametmp,fname,strerror(errno));
909 set_perms(fname,file,NULL,0);
913 rprintf(FERROR,"rename %s -> %s : %s\n",
914 fnametmp,fname,strerror(errno));
918 set_perms(fname,file,NULL,0);
921 cleanup_fname = NULL;
925 if (csum_length == SUM_LENGTH) {
926 rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
930 rprintf(FINFO,"redoing %s(%d)\n",fname,i);
936 if (preserve_hard_links)
937 do_hard_links(flist);
939 /* now we need to fix any directory permissions that were
940 modified during the transfer */
941 for (i = 0; i < flist->count; i++) {
942 file = flist->files[i];
943 if (!file->basename || !S_ISDIR(file->mode)) continue;
944 recv_generator(f_name(file),flist,i,-1);
948 rprintf(FINFO,"recv_files finished\n");
955 void send_files(struct file_list *flist,int f_out,int f_in)
958 struct sum_struct *s;
959 struct map_struct *buf;
961 char fname[MAXPATHLEN];
963 struct file_struct *file;
968 rprintf(FINFO,"send_files starting\n");
970 setup_readbuffer(f_in);
975 if (phase==0 && remote_version >= 13) {
977 csum_length = SUM_LENGTH;
980 rprintf(FINFO,"send_files phase=%d\n",phase);
986 file = flist->files[i];
990 strlcpy(fname,file->basedir,MAXPATHLEN-1);
991 if (strlen(fname) == MAXPATHLEN-1) {
993 rprintf(FERROR, "send_files failed on long-named directory %s\n",
997 strlcat(fname,"/",MAXPATHLEN-1);
998 offset = strlen(file->basedir)+1;
1000 strlcat(fname,f_name(file),MAXPATHLEN-strlen(fname));
1003 rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
1006 if (!am_server && verbose)
1007 printf("%s\n",fname);
1012 s = receive_sums(f_in);
1015 rprintf(FERROR,"receive_sums failed\n");
1019 fd = open(fname,O_RDONLY);
1022 rprintf(FERROR,"send_files failed to open %s: %s\n",
1023 fname,strerror(errno));
1028 /* map the local file */
1029 if (do_fstat(fd,&st) != 0) {
1031 rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
1037 if (st.st_size > 0) {
1038 buf = map_file(fd,st.st_size);
1044 rprintf(FINFO,"send_files mapped %s of size %d\n",
1045 fname,(int)st.st_size);
1049 write_int(f_out,s->count);
1050 write_int(f_out,s->n);
1051 write_int(f_out,s->remainder);
1054 rprintf(FINFO,"calling match_sums %s\n",fname);
1056 if (!am_server && verbose)
1057 printf("%s\n",fname+offset);
1059 match_sums(f_out,s,buf,st.st_size);
1061 if (buf) unmap_file(buf);
1067 rprintf(FINFO,"sender finished %s\n",fname);
1071 rprintf(FINFO,"send files finished\n");
1075 write_int(f_out,-1);
1080 void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
1086 rprintf(FINFO,"generator starting pid=%d count=%d\n",
1087 (int)getpid(),flist->count);
1089 for (i = 0; i < flist->count; i++) {
1090 struct file_struct *file = flist->files[i];
1091 mode_t saved_mode = file->mode;
1092 if (!file->basename) continue;
1094 /* we need to ensure that any directories we create have writeable
1095 permissions initially so that we can create the files within
1096 them. This is then fixed after the files are transferred */
1097 if (!am_root && S_ISDIR(file->mode)) {
1098 file->mode |= S_IWUSR; /* user write */
1101 recv_generator(local_name?local_name:f_name(file),
1104 file->mode = saved_mode;
1108 csum_length = SUM_LENGTH;
1112 rprintf(FINFO,"generate_files phase=%d\n",phase);
1116 /* we expect to just sit around now, so don't exit on a timeout. If we
1117 really get a timeout then the other process should exit */
1120 if (remote_version >= 13) {
1121 /* in newer versions of the protocol the files can cycle through
1122 the system more than once to catch initial checksum errors */
1123 for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
1124 struct file_struct *file = flist->files[i];
1125 recv_generator(local_name?local_name:f_name(file),
1131 rprintf(FINFO,"generate_files phase=%d\n",phase);
1138 rprintf(FINFO,"generator wrote %ld\n",(long)write_total());