version 1.3, 2019/02/10 23:56:19 |
version 1.4, 2019/02/11 19:18:36 |
|
|
size_t i; |
size_t i; |
const char *cp; |
const char *cp; |
|
|
if ( ! sess->opts->recursive) |
if (!sess->opts->recursive) |
return; |
return; |
|
|
if (flsz && strcmp(fl[0].wpath, ".")) { |
if (flsz && strcmp(fl[0].wpath, ".")) { |
for (i = 0; i < flsz; i++) { |
for (i = 0; i < flsz; i++) { |
if ( ! S_ISDIR(fl[i].st.mode)) |
if (!S_ISDIR(fl[i].st.mode)) |
continue; |
continue; |
cp = strchr(fl[i].wpath, '/'); |
cp = strchr(fl[i].wpath, '/'); |
if (NULL != cp && '\0' != cp[1]) |
if (NULL != cp && '\0' != cp[1]) |
|
|
|
|
if (sess->mplex_reads && |
if (sess->mplex_reads && |
io_read_check(sess, fdin) && |
io_read_check(sess, fdin) && |
! io_read_flush(sess, fdin)) { |
!io_read_flush(sess, fdin)) { |
ERRX1(sess, "io_read_flush"); |
ERRX1(sess, "io_read_flush"); |
return 0; |
return 0; |
} |
} |
|
|
/* Now write to the wire. */ |
/* Now write to the wire. */ |
/* FIXME: buffer this. */ |
/* FIXME: buffer this. */ |
|
|
if ( ! io_write_byte(sess, fdout, flag)) { |
if (!io_write_byte(sess, fdout, flag)) { |
ERRX1(sess, "io_write_byte"); |
ERRX1(sess, "io_write_byte"); |
return 0; |
return 0; |
} else if ( ! io_write_int(sess, fdout, fnlen)) { |
} else if (!io_write_int(sess, fdout, fnlen)) { |
ERRX1(sess, "io_write_int"); |
ERRX1(sess, "io_write_int"); |
return 0; |
return 0; |
} else if ( ! io_write_buf(sess, fdout, fn, fnlen)) { |
} else if (!io_write_buf(sess, fdout, fn, fnlen)) { |
ERRX1(sess, "io_write_buf"); |
ERRX1(sess, "io_write_buf"); |
return 0; |
return 0; |
} else if ( ! io_write_long(sess, fdout, f->st.size)) { |
} else if (!io_write_long(sess, fdout, f->st.size)) { |
ERRX1(sess, "io_write_long"); |
ERRX1(sess, "io_write_long"); |
return 0; |
return 0; |
} else if ( ! io_write_int(sess, fdout, f->st.mtime)) { |
} else if (!io_write_int(sess, fdout, f->st.mtime)) { |
ERRX1(sess, "io_write_int"); |
ERRX1(sess, "io_write_int"); |
return 0; |
return 0; |
} else if ( ! io_write_int(sess, fdout, f->st.mode)) { |
} else if (!io_write_int(sess, fdout, f->st.mode)) { |
ERRX1(sess, "io_write_int"); |
ERRX1(sess, "io_write_int"); |
return 0; |
return 0; |
} |
} |
|
|
sess->opts->preserve_links) { |
sess->opts->preserve_links) { |
fn = f->link; |
fn = f->link; |
fnlen = strlen(f->link); |
fnlen = strlen(f->link); |
if ( ! io_write_int(sess, fdout, fnlen)) { |
if (!io_write_int(sess, fdout, fnlen)) { |
ERRX1(sess, "io_write_int"); |
ERRX1(sess, "io_write_int"); |
return 0; |
return 0; |
} |
} |
if ( ! io_write_buf(sess, fdout, fn, fnlen)) { |
if (!io_write_buf(sess, fdout, fn, fnlen)) { |
ERRX1(sess, "io_write_int"); |
ERRX1(sess, "io_write_int"); |
return 0; |
return 0; |
} |
} |
|
|
sess->total_size += f->st.size; |
sess->total_size += f->st.size; |
} |
} |
|
|
if ( ! io_write_byte(sess, fdout, 0)) { |
if (!io_write_byte(sess, fdout, 0)) { |
ERRX1(sess, "io_write_byte"); |
ERRX1(sess, "io_write_byte"); |
return 0; |
return 0; |
} |
} |
|
|
*/ |
*/ |
|
|
if (FLIST_NAME_SAME & flags) { |
if (FLIST_NAME_SAME & flags) { |
if ( ! io_read_byte(sess, fd, &bval)) { |
if (!io_read_byte(sess, fd, &bval)) { |
ERRX1(sess, "io_read_byte"); |
ERRX1(sess, "io_read_byte"); |
return 0; |
return 0; |
} |
} |
|
|
/* Get the (possibly-remaining) filename length. */ |
/* Get the (possibly-remaining) filename length. */ |
|
|
if (FLIST_NAME_LONG & flags) { |
if (FLIST_NAME_LONG & flags) { |
if ( ! io_read_size(sess, fd, &pathlen)) { |
if (!io_read_size(sess, fd, &pathlen)) { |
ERRX1(sess, "io_read_size"); |
ERRX1(sess, "io_read_size"); |
return 0; |
return 0; |
} |
} |
} else { |
} else { |
if ( ! io_read_byte(sess, fd, &bval)) { |
if (!io_read_byte(sess, fd, &bval)) { |
ERRX1(sess, "io_read_byte"); |
ERRX1(sess, "io_read_byte"); |
return 0; |
return 0; |
} |
} |
|
|
if (FLIST_NAME_SAME & flags) |
if (FLIST_NAME_SAME & flags) |
memcpy(f->path, last, partial); |
memcpy(f->path, last, partial); |
|
|
if ( ! io_read_buf(sess, fd, f->path + partial, pathlen)) { |
if (!io_read_buf(sess, fd, f->path + partial, pathlen)) { |
ERRX1(sess, "io_read_buf"); |
ERRX1(sess, "io_read_buf"); |
return 0; |
return 0; |
} |
} |
|
|
last[0] = '\0'; |
last[0] = '\0'; |
|
|
for (;;) { |
for (;;) { |
if ( ! io_read_byte(sess, fd, &flag)) { |
if (!io_read_byte(sess, fd, &flag)) { |
ERRX1(sess, "io_read_byte"); |
ERRX1(sess, "io_read_byte"); |
goto out; |
goto out; |
} else if (0 == flag) |
} else if (0 == flag) |
break; |
break; |
|
|
if ( ! flist_realloc(sess, &fl, &flsz, &flmax)) { |
if (!flist_realloc(sess, &fl, &flsz, &flmax)) { |
ERRX1(sess, "flist_realloc"); |
ERRX1(sess, "flist_realloc"); |
goto out; |
goto out; |
} |
} |
|
|
|
|
/* Filename first. */ |
/* Filename first. */ |
|
|
if ( ! flist_recv_name(sess, fd, ff, flag, last)) { |
if (!flist_recv_name(sess, fd, ff, flag, last)) { |
ERRX1(sess, "flist_recv_name"); |
ERRX1(sess, "flist_recv_name"); |
goto out; |
goto out; |
} |
} |
|
|
/* Read the file size. */ |
/* Read the file size. */ |
|
|
if ( ! io_read_ulong(sess, fd, &lval)) { |
if (!io_read_ulong(sess, fd, &lval)) { |
ERRX1(sess, "io_read_ulong"); |
ERRX1(sess, "io_read_ulong"); |
goto out; |
goto out; |
} |
} |
|
|
|
|
/* Read the modification time. */ |
/* Read the modification time. */ |
|
|
if ( ! (FLIST_TIME_SAME & flag)) { |
if (!(FLIST_TIME_SAME & flag)) { |
if ( ! io_read_int(sess, fd, &ival)) { |
if (!io_read_int(sess, fd, &ival)) { |
ERRX1(sess, "io_read_int"); |
ERRX1(sess, "io_read_int"); |
goto out; |
goto out; |
} |
} |
|
|
|
|
/* Read the file mode. */ |
/* Read the file mode. */ |
|
|
if ( ! (FLIST_MODE_SAME & flag)) { |
if (!(FLIST_MODE_SAME & flag)) { |
if ( ! io_read_int(sess, fd, &ival)) { |
if (!io_read_int(sess, fd, &ival)) { |
ERRX1(sess, "io_read_int"); |
ERRX1(sess, "io_read_int"); |
goto out; |
goto out; |
} |
} |
|
|
|
|
if (S_ISLNK(ff->st.mode) && |
if (S_ISLNK(ff->st.mode) && |
sess->opts->preserve_links) { |
sess->opts->preserve_links) { |
if ( ! io_read_size(sess, fd, &lsz)) { |
if (!io_read_size(sess, fd, &lsz)) { |
ERRX1(sess, "io_read_size"); |
ERRX1(sess, "io_read_size"); |
goto out; |
goto out; |
} else if (0 == lsz) { |
} else if (0 == lsz) { |
|
|
ERR(sess, "calloc"); |
ERR(sess, "calloc"); |
goto out; |
goto out; |
} |
} |
if ( ! io_read_buf(sess, fd, ff->link, lsz)) { |
if (!io_read_buf(sess, fd, ff->link, lsz)) { |
ERRX1(sess, "io_read_buf"); |
ERRX1(sess, "io_read_buf"); |
goto out; |
goto out; |
} |
} |
|
|
ERR(sess, "%s: lstat", root); |
ERR(sess, "%s: lstat", root); |
return 0; |
return 0; |
} else if (S_ISREG(st.st_mode)) { |
} else if (S_ISREG(st.st_mode)) { |
if ( ! flist_realloc(sess, fl, sz, max)) { |
if (!flist_realloc(sess, fl, sz, max)) { |
ERRX1(sess, "flist_realloc"); |
ERRX1(sess, "flist_realloc"); |
return 0; |
return 0; |
} |
} |
f = &(*fl)[(*sz) - 1]; |
f = &(*fl)[(*sz) - 1]; |
assert(NULL != f); |
assert(NULL != f); |
|
|
if ( ! flist_append(sess, f, &st, root)) { |
if (!flist_append(sess, f, &st, root)) { |
ERRX1(sess, "flist_append"); |
ERRX1(sess, "flist_append"); |
return 0; |
return 0; |
} else if (-1 == unveil(root, "r")) { |
} else if (-1 == unveil(root, "r")) { |
|
|
} |
} |
return 1; |
return 1; |
} else if (S_ISLNK(st.st_mode)) { |
} else if (S_ISLNK(st.st_mode)) { |
if ( ! sess->opts->preserve_links) { |
if (!sess->opts->preserve_links) { |
WARNX(sess, "%s: skipping symlink", root); |
WARNX(sess, "%s: skipping symlink", root); |
return 1; |
return 1; |
} else if ( ! flist_realloc(sess, fl, sz, max)) { |
} else if (!flist_realloc(sess, fl, sz, max)) { |
ERRX1(sess, "flist_realloc"); |
ERRX1(sess, "flist_realloc"); |
return 0; |
return 0; |
} |
} |
f = &(*fl)[(*sz) - 1]; |
f = &(*fl)[(*sz) - 1]; |
assert(NULL != f); |
assert(NULL != f); |
|
|
if ( ! flist_append(sess, f, &st, root)) { |
if (!flist_append(sess, f, &st, root)) { |
ERRX1(sess, "flist_append"); |
ERRX1(sess, "flist_append"); |
return 0; |
return 0; |
} else if (-1 == unveil(root, "r")) { |
} else if (-1 == unveil(root, "r")) { |
|
|
return 0; |
return 0; |
} |
} |
return 1; |
return 1; |
} else if ( ! S_ISDIR(st.st_mode)) { |
} else if (!S_ISDIR(st.st_mode)) { |
WARNX(sess, "%s: skipping special", root); |
WARNX(sess, "%s: skipping special", root); |
return 1; |
return 1; |
} |
} |
|
|
|
|
errno = 0; |
errno = 0; |
while (NULL != (ent = fts_read(fts))) { |
while (NULL != (ent = fts_read(fts))) { |
if ( ! flist_fts_check(sess, ent)) { |
if (!flist_fts_check(sess, ent)) { |
errno = 0; |
errno = 0; |
continue; |
continue; |
} |
} |
|
|
|
|
assert(NULL != ent->fts_statp); |
assert(NULL != ent->fts_statp); |
if (S_ISLNK(ent->fts_statp->st_mode) && |
if (S_ISLNK(ent->fts_statp->st_mode) && |
! sess->opts->preserve_links) { |
!sess->opts->preserve_links) { |
WARNX(sess, "%s: skipping " |
WARNX(sess, "%s: skipping " |
"symlink", ent->fts_path); |
"symlink", ent->fts_path); |
continue; |
continue; |
|
|
|
|
/* Allocate a new file entry. */ |
/* Allocate a new file entry. */ |
|
|
if ( ! flist_realloc(sess, fl, sz, max)) { |
if (!flist_realloc(sess, fl, sz, max)) { |
ERRX1(sess, "flist_realloc"); |
ERRX1(sess, "flist_realloc"); |
goto out; |
goto out; |
} |
} |
|
|
size_t i, max = 0; |
size_t i, max = 0; |
|
|
for (i = 0; i < argc; i++) |
for (i = 0; i < argc; i++) |
if ( ! flist_gen_dirent(sess, argv[i], flp, sz, &max)) |
if (!flist_gen_dirent(sess, argv[i], flp, sz, &max)) |
break; |
break; |
|
|
if (i == argc) { |
if (i == argc) { |
|
|
WARNX(sess, "%s: skipping directory", argv[i]); |
WARNX(sess, "%s: skipping directory", argv[i]); |
continue; |
continue; |
} else if (S_ISLNK(st.st_mode)) { |
} else if (S_ISLNK(st.st_mode)) { |
if ( ! sess->opts->preserve_links) { |
if (!sess->opts->preserve_links) { |
WARNX(sess, "%s: skipping " |
WARNX(sess, "%s: skipping " |
"symlink", argv[i]); |
"symlink", argv[i]); |
continue; |
continue; |
} |
} |
} else if ( ! S_ISREG(st.st_mode)) { |
} else if (!S_ISREG(st.st_mode)) { |
WARNX(sess, "%s: skipping special", argv[i]); |
WARNX(sess, "%s: skipping special", argv[i]); |
continue; |
continue; |
} |
} |
|
|
if (-1 == unveil(argv[i], "r")) { |
if (-1 == unveil(argv[i], "r")) { |
ERR(sess, "%s: unveil", argv[i]); |
ERR(sess, "%s: unveil", argv[i]); |
goto out; |
goto out; |
} else if ( ! flist_append(sess, f, &st, argv[i])) { |
} else if (!flist_append(sess, f, &st, argv[i])) { |
ERRX1(sess, "flist_append"); |
ERRX1(sess, "flist_append"); |
goto out; |
goto out; |
} |
} |
|
|
if (-1 == unveil(NULL, NULL)) { |
if (-1 == unveil(NULL, NULL)) { |
ERR(sess, "unveil"); |
ERR(sess, "unveil"); |
return 0; |
return 0; |
} else if ( ! rc) |
} else if (!rc) |
return 0; |
return 0; |
|
|
qsort(*flp, *sz, sizeof(struct flist), flist_cmp); |
qsort(*flp, *sz, sizeof(struct flist), flist_cmp); |
|
|
|
|
/* Only run this code when we're recursive. */ |
/* Only run this code when we're recursive. */ |
|
|
if ( ! sess->opts->recursive) |
if (!sess->opts->recursive) |
return 1; |
return 1; |
|
|
/* |
/* |
|
|
cargv[1] = NULL; |
cargv[1] = NULL; |
} else { |
} else { |
for (i = j = 0; i < wflsz; i++) { |
for (i = j = 0; i < wflsz; i++) { |
if ( ! (FLSTAT_TOP_DIR & wfl[i].st.flags)) |
if (!(FLSTAT_TOP_DIR & wfl[i].st.flags)) |
continue; |
continue; |
assert(S_ISDIR(wfl[i].st.mode)); |
assert(S_ISDIR(wfl[i].st.mode)); |
assert(strcmp(wfl[i].wpath, ".")); |
assert(strcmp(wfl[i].wpath, ".")); |
|
|
* we want to delete. |
* we want to delete. |
*/ |
*/ |
|
|
if ( ! hcreate(wflsz)) { |
if (!hcreate(wflsz)) { |
ERR(sess, "hcreate"); |
ERR(sess, "hcreate"); |
goto out; |
goto out; |
} |
} |
|
|
while (NULL != (ent = fts_read(fts))) { |
while (NULL != (ent = fts_read(fts))) { |
if (FTS_NS == ent->fts_info) |
if (FTS_NS == ent->fts_info) |
continue; |
continue; |
if ( ! flist_fts_check(sess, ent)) { |
if (!flist_fts_check(sess, ent)) { |
errno = 0; |
errno = 0; |
continue; |
continue; |
} else if (stripdir >= ent->fts_pathlen) |
} else if (stripdir >= ent->fts_pathlen) |
|
|
|
|
/* Not found: we'll delete it. */ |
/* Not found: we'll delete it. */ |
|
|
if ( ! flist_realloc(sess, fl, sz, &max)) { |
if (!flist_realloc(sess, fl, sz, &max)) { |
ERRX1(sess, "flist_realloc"); |
ERRX1(sess, "flist_realloc"); |
goto out; |
goto out; |
} |
} |