|
Lines 666-679
Link Here
|
| 666 |
status = get_status(conn->fd_in, id); |
666 |
status = get_status(conn->fd_in, id); |
| 667 |
if (status != SSH2_FX_OK) |
667 |
if (status != SSH2_FX_OK) |
| 668 |
error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, |
668 |
error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath, |
| 669 |
newpath, fx2txt(status)); |
669 |
newpath, fx2txt(status)); |
| 670 |
return(status); |
670 |
return(status); |
| 671 |
} |
671 |
} |
| 672 |
char * |
672 |
char * |
| 673 |
do_readlink(struct sftp_conn *conn, char *path) |
673 |
do_readlink(struct sftp_conn *conn, char *path, Attrib *attrib) |
| 674 |
{ |
674 |
{ |
| 675 |
Buffer msg; |
675 |
Buffer msg; |
| 676 |
u_int type, expected_id, count, id; |
676 |
u_int type, expected_id, count, id; |
|
Lines 712-717
Link Here
|
| 712 |
debug3("SSH_FXP_READLINK %s -> %s", path, filename); |
712 |
debug3("SSH_FXP_READLINK %s -> %s", path, filename); |
|
|
713 |
if (attrib != NULL) |
| 714 |
*attrib = *a; |
| 715 |
|
| 713 |
xfree(longname); |
716 |
xfree(longname); |
| 714 |
buffer_free(&msg); |
717 |
buffer_free(&msg); |
|
Lines 719-724
Link Here
|
| 719 |
return(filename); |
722 |
return(filename); |
| 720 |
} |
723 |
} |
|
|
724 |
int |
| 725 |
do_getlink(struct sftp_conn *conn, char *path) |
| 726 |
{ |
| 727 |
char *dest; |
| 728 |
u_int status = 0; |
| 729 |
int ret; |
| 730 |
struct stat statb; |
| 731 |
char *filename; |
| 732 |
Attrib *a; |
| 733 |
Attrib attrib; |
| 734 |
|
| 735 |
a = do_lstat(conn, path, 0); |
| 736 |
if (a == NULL || !S_ISLNK(a->perm)) { |
| 737 |
if (a != NULL) |
| 738 |
error("%s is not a symlink", path); |
| 739 |
return(-1); |
| 740 |
} |
| 741 |
|
| 742 |
dest = do_readlink(conn, path, &attrib); |
| 743 |
if (dest == NULL) |
| 744 |
return(-1); |
| 745 |
filename = strrchr(path, '/'); |
| 746 |
if (filename == NULL) |
| 747 |
filename = path; |
| 748 |
else |
| 749 |
filename += 1; |
| 750 |
if (lstat(filename, &statb) == 0) { |
| 751 |
error("Name \"%s\" already exists", filename); |
| 752 |
return(-1); |
| 753 |
} |
| 754 |
else { |
| 755 |
ret = symlink(dest, filename); |
| 756 |
status = (ret == -1) ? errno : 0; |
| 757 |
if (status != 0) |
| 758 |
error("Couldn't create symlink \"%s\": %s", filename, |
| 759 |
strerror(status)); |
| 760 |
if (getuid() == 0 || geteuid() == 0) { |
| 761 |
ret = lchown(filename, attrib.uid, attrib.gid); |
| 762 |
status = (ret == -1) ? errno : 0; |
| 763 |
if (status != 0) |
| 764 |
error("Couldn't set ownership on symlink \"%s\": |
| 721 |
%s", filename, |
765 |
%s", filename, |
|
|
766 |
strerror(status)); |
| 767 |
} |
| 768 |
} |
| 769 |
return(status); |
| 770 |
} |
| 771 |
|
| 722 |
static void |
772 |
static void |
| 723 |
send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, |
773 |
send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, |
| 724 |
char *handle, u_int handle_len) |
774 |
char *handle, u_int handle_len) |