Honor the new omit_dir_times var.
[rsync/rsync.git] / cleanup.c
CommitLineData
ef1aa910 1/* -*- c-file-style: "linux" -*-
6e86c951 2
ef1aa910 3 Copyright (C) 1996-2000 by Andrew Tridgell
2f03f956 4 Copyright (C) Paul Mackerras 1996
e0fde757 5 Copyright (C) 2002 by Martin Pool
6e86c951 6
2f03f956
AT
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.
6e86c951 11
2f03f956
AT
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.
6e86c951 16
2f03f956
AT
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#include "rsync.h"
23
6e86c951
WD
24extern int io_error;
25extern int keep_partial;
26extern int log_got_error;
d45898df 27extern char *partial_dir;
6e86c951 28
9f639210
DD
29/**
30 * Close all open sockets and files, allowing a (somewhat) graceful
31 * shutdown() of socket connections. This eliminates the abortive
32 * TCP RST sent by a Winsock-based system when the close() occurs.
33 **/
18d6b679 34void close_all(void)
9f639210
DD
35{
36#ifdef SHUTDOWN_ALL_SOCKETS
37 int max_fd;
38 int fd;
39 int ret;
40 struct stat st;
41
42 max_fd = sysconf(_SC_OPEN_MAX) - 1;
43 for (fd = max_fd; fd >= 0; fd--) {
44 ret = fstat(fd,&st);
45 if (fstat(fd,&st) == 0) {
8186ae6b 46 if (is_a_socket(fd))
9f639210 47 ret = shutdown(fd, 2);
9f639210
DD
48 ret = close(fd);
49 }
50 }
51#endif
52}
53
e0fde757
MP
54/**
55 * @file cleanup.c
56 *
57 * Code for handling interrupted transfers. Depending on the @c
58 * --partial option, we may either delete the temporary file, or go
59 * ahead and overwrite the destination. This second behaviour only
60 * occurs if we've sent literal data and therefore hopefully made
61 * progress on the transfer.
62 **/
63
64/**
65 * Set to True once literal data has been sent across the link for the
66 * current file. (????)
67 *
68 * Handling the cleanup when a transfer is interrupted is tricky when
69 * --partial is selected. We need to ensure that the partial file is
70 * kept if any real data has been transferred.
71 **/
8186ae6b 72int cleanup_got_literal = 0;
2f03f956
AT
73
74static char *cleanup_fname;
75static char *cleanup_new_fname;
76static struct file_struct *cleanup_file;
b6609caf 77static int cleanup_fd_r, cleanup_fd_w;
65fc84b3 78static pid_t cleanup_pid = 0;
2f03f956 79
19b27a48 80pid_t cleanup_child_pid = -1;
ef1aa910 81
e0fde757 82/**
b0f451eb 83 * Eventually calls exit(), passing @p code, therefore does not return.
e0fde757
MP
84 *
85 * @param code one of the RERR_* codes from errcode.h.
86 **/
a9766ef1 87void _exit_cleanup(int code, const char *file, int line)
2f03f956 88{
9098bbf3 89 int ocode = code;
b765ec32
DD
90 static int inside_cleanup = 0;
91
aa2c47d8 92 if (inside_cleanup > 10) {
b765ec32
DD
93 /* prevent the occasional infinite recursion */
94 return;
95 }
aa2c47d8 96 inside_cleanup++;
2f03f956
AT
97
98 signal(SIGUSR1, SIG_IGN);
8b35435f 99 signal(SIGUSR2, SIG_IGN);
2f03f956 100
6e86c951
WD
101 if (verbose > 3) {
102 rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
9098bbf3 103 code, file, line);
6e86c951 104 }
9098bbf3 105
19b27a48
AT
106 if (cleanup_child_pid != -1) {
107 int status;
108 if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
109 status = WEXITSTATUS(status);
8186ae6b
WD
110 if (status > code)
111 code = status;
19b27a48
AT
112 }
113 }
114
a7260c40
WD
115 if (cleanup_got_literal && cleanup_fname && keep_partial
116 && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
2f03f956
AT
117 char *fname = cleanup_fname;
118 cleanup_fname = NULL;
b6609caf
WD
119 if (cleanup_fd_r != -1)
120 close(cleanup_fd_r);
09e2bbce
WD
121 if (cleanup_fd_w != -1) {
122 flush_write_file(cleanup_fd_w);
b6609caf 123 close(cleanup_fd_w);
09e2bbce 124 }
d45898df
WD
125 finish_transfer(cleanup_new_fname, fname, cleanup_file, 0,
126 !partial_dir);
2f03f956 127 }
ef732c3b 128 io_flush(FULL_FLUSH);
2f03f956
AT
129 if (cleanup_fname)
130 do_unlink(cleanup_fname);
8186ae6b 131 if (code)
2f03f956 132 kill_all(SIGUSR1);
65fc84b3 133 if (cleanup_pid && cleanup_pid == getpid()) {
27d3cdbc 134 char *pidf = lp_pid_file();
8186ae6b 135 if (pidf && *pidf)
27d3cdbc 136 unlink(lp_pid_file());
27d3cdbc 137 }
9b73d1c0 138
6e35c72f
WD
139 if (code == 0) {
140 if ((io_error & ~IOERR_VANISHED) || log_got_error)
141 code = RERR_PARTIAL;
142 else if (io_error)
143 code = RERR_VANISHED;
ff81e809
AT
144 }
145
8186ae6b
WD
146 if (code)
147 log_exit(code, file, line);
19b27a48 148
6e86c951
WD
149 if (verbose > 2) {
150 rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
9098bbf3 151 ocode, file, line, code);
6e86c951 152 }
9098bbf3 153
9f639210 154 close_all();
2f03f956
AT
155 exit(code);
156}
157
158void cleanup_disable(void)
159{
160 cleanup_fname = NULL;
161 cleanup_got_literal = 0;
162}
163
164
c6b81a98 165void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
b6609caf 166 int fd_r, int fd_w)
2f03f956
AT
167{
168 cleanup_fname = fnametmp;
169 cleanup_new_fname = fname;
170 cleanup_file = file;
b6609caf
WD
171 cleanup_fd_r = fd_r;
172 cleanup_fd_w = fd_w;
2f03f956 173}
8638dd48 174
65fc84b3 175void cleanup_set_pid(pid_t pid)
8638dd48
DD
176{
177 cleanup_pid = pid;
178}