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