Changeset View
Changeset View
Standalone View
Standalone View
receiver.c
Show All 10 Lines | |||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
*/ | */ | ||||
#include <sys/capsicum.h> | |||||
#include <sys/mman.h> | #include <sys/mman.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <assert.h> | #include <assert.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <inttypes.h> | #include <inttypes.h> | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | rsync_receiver(struct sess *sess, int fdin, int fdout, const char *root) | ||||
char *tofree; | char *tofree; | ||||
int rc = 0, dfd = -1, phase = 0, c; | int rc = 0, dfd = -1, phase = 0, c; | ||||
int32_t ioerror; | int32_t ioerror; | ||||
struct pollfd pfd[PFD__MAX]; | struct pollfd pfd[PFD__MAX]; | ||||
struct download *dl = NULL; | struct download *dl = NULL; | ||||
struct upload *ul = NULL; | struct upload *ul = NULL; | ||||
mode_t oumask; | mode_t oumask; | ||||
if (pledge("stdio unix rpath wpath cpath dpath fattr chown getpw unveil", NULL) == -1) { | /* | ||||
ERR(sess, "pledge"); | * Create the path for our destination directory, if we're not | ||||
* in dry-run mode (which would otherwise crash w/the pledge). | |||||
* This uses our current umask: we might set the permissions on | |||||
* this directory in post_dir(). | |||||
*/ | |||||
if (!sess->opts->dry_run) { | |||||
if ((tofree = strdup(root)) == NULL) { | |||||
ERR(sess, "strdup"); | |||||
goto out; | goto out; | ||||
} else if (mkpath(sess, tofree) < 0) { | |||||
ERRX1(sess, "%s: mkpath2", root); | |||||
free(tofree); | |||||
goto out; | |||||
} | } | ||||
free(tofree); | |||||
} | |||||
/* | |||||
* Disable umask() so we can set permissions fully. | |||||
* Then open the directory iff we're not in dry_run. | |||||
*/ | |||||
oumask = umask(0); | |||||
if (!sess->opts->dry_run) { | |||||
dfd = open(root, O_RDONLY | O_DIRECTORY, 0); | |||||
if (dfd == -1) { | |||||
ERR(sess, "%s: open", root); | |||||
goto out; | |||||
} | |||||
} | |||||
if (cap_enter() < 0 && errno != ENOSYS) { | |||||
ERRX(sess, "cap_enter"); | |||||
goto out; | |||||
} | |||||
/* Client sends zero-length exclusions. */ | /* Client sends zero-length exclusions. */ | ||||
if (!sess->opts->server && | if (!sess->opts->server && | ||||
!io_write_int(sess, fdout, 0)) { | !io_write_int(sess, fdout, 0)) { | ||||
ERRX1(sess, "io_write_int"); | ERRX1(sess, "io_write_int"); | ||||
goto out; | goto out; | ||||
} | } | ||||
Show All 32 Lines | if (flsz == 0 && !sess->opts->server) { | ||||
rc = 1; | rc = 1; | ||||
goto out; | goto out; | ||||
} else if (!sess->opts->server) | } else if (!sess->opts->server) | ||||
LOG1(sess, "Transfer starting: %zu files", flsz); | LOG1(sess, "Transfer starting: %zu files", flsz); | ||||
LOG2(sess, "%s: receiver destination", root); | LOG2(sess, "%s: receiver destination", root); | ||||
/* | /* | ||||
* Create the path for our destination directory, if we're not | |||||
* in dry-run mode (which would otherwise crash w/the pledge). | |||||
* This uses our current umask: we might set the permissions on | |||||
* this directory in post_dir(). | |||||
*/ | |||||
if (!sess->opts->dry_run) { | |||||
if ((tofree = strdup(root)) == NULL) { | |||||
ERR(sess, "strdup"); | |||||
goto out; | |||||
} else if (mkpath(sess, tofree) < 0) { | |||||
ERRX1(sess, "%s: mkpath", root); | |||||
free(tofree); | |||||
goto out; | |||||
} | |||||
free(tofree); | |||||
} | |||||
/* | |||||
* Disable umask() so we can set permissions fully. | |||||
* Then open the directory iff we're not in dry_run. | |||||
*/ | |||||
oumask = umask(0); | |||||
if (!sess->opts->dry_run) { | |||||
dfd = open(root, O_RDONLY | O_DIRECTORY, 0); | |||||
if (dfd == -1) { | |||||
ERR(sess, "%s: open", root); | |||||
goto out; | |||||
} | |||||
} | |||||
/* | |||||
* Begin by conditionally getting all files we have currently | * Begin by conditionally getting all files we have currently | ||||
* available in our destination. | * available in our destination. | ||||
*/ | */ | ||||
if (sess->opts->del && | if (sess->opts->del && | ||||
sess->opts->recursive && | sess->opts->recursive && | ||||
!flist_gen_dels(sess, root, &dfl, &dflsz, fl, flsz)) { | !flist_gen_dels(sess, root, &dfl, &dflsz, fl, flsz)) { | ||||
ERRX1(sess, "flist_gen_local"); | ERRX1(sess, "flist_gen_local"); | ||||
goto out; | |||||
} | |||||
/* | |||||
* Make our entire view of the file-system be limited to what's | |||||
* in the root directory. | |||||
* This prevents us from accidentally (or "under the influence") | |||||
* writing into other parts of the file-system. | |||||
*/ | |||||
if (unveil(root, "rwc") == -1) { | |||||
ERR(sess, "%s: unveil", root); | |||||
goto out; | |||||
} else if (unveil(NULL, NULL) == -1) { | |||||
ERR(sess, "%s: unveil", root); | |||||
goto out; | goto out; | ||||
} | } | ||||
/* If we have a local set, go for the deletion. */ | /* If we have a local set, go for the deletion. */ | ||||
if (!flist_del(sess, dfd, dfl, dflsz)) { | if (!flist_del(sess, dfd, dfl, dflsz)) { | ||||
ERRX1(sess, "flist_del"); | ERRX1(sess, "flist_del"); | ||||
goto out; | goto out; | ||||
▲ Show 20 Lines • Show All 163 Lines • Show Last 20 Lines |