|
From: Csaba H. <csa...@cr...> - 2006-01-08 23:00:07
|
On 2006-01-08, Paul Jarc <pr...@po...> wrote:
> Csaba Henk <csa...@cr...> wrote:
>> sshfs doesn't necessarily get a mountpoint argument on FreeBSD. If that
>> happens and the symlink workaround is asked for, then realpath gets
>> NULL, and we end up with a segfault.
>
> Ok, this version should fix that. It also makes a small aesthetic
> improvement: previously, if the mount point were given with a trailing
> slash, you'd get two slashes in symlink targets.
Thanks, nice. Anyway, as far as I'm concerned, I'd vote for erring loud...
so here's a version which just does that (what do you think?).
For better readability, patch of patch:
--- sshfs-symlink2.1.diff Sun Jan 8 23:50:06 2006
+++ sshfs-symlink3.1.diff Sun Jan 8 23:45:31 2006
@@ -62,11 +62,15 @@
" -o idmap=TYPE user/group ID mapping, possible types are:\n"
" none no translation of the ID space (default)\n"
" user only translate UID of connecting user\n"
-@@ -2066,6 +2082,24 @@
+@@ -2066,6 +2082,28 @@
if (sshfs.max_read > 65536)
sshfs.max_read = 65536;
-+ if (!sshfs.symlink_workaround || outargs.argv[1]==NULL)
++ if (sshfs.symlink_workaround && outargs.argv[1] == NULL) {
++ fprintf(stderr, "symlink workaround failed: no mountpoint given\n");
++ exit(1);
++ }
++ if (!sshfs.symlink_workaround)
+ sshfs.symlink_prefix_len=0;
+ else if (realpath(outargs.argv[1], sshfs.symlink_prefix)!=NULL)
+ sshfs.symlink_prefix_len=strlen(sshfs.symlink_prefix);
For better usability, I put the whole amended patch to the end of this
post.
Regards,
Csaba
Index: sshfs.c
===================================================================
RCS file: /cvsroot/fuse/sshfs/sshfs.c,v
retrieving revision 1.52
diff -u -r1.52 sshfs.c
--- sshfs.c 16 Dec 2005 11:15:26 -0000 1.52
+++ sshfs.c 8 Jan 2006 22:11:46 -0000
@@ -147,6 +147,7 @@
char *sftp_server;
struct fuse_args ssh_args;
int rename_workaround;
+ int symlink_workaround;
int detect_uid;
unsigned max_read;
unsigned ssh_ver;
@@ -168,6 +169,8 @@
unsigned local_uid;
int remote_uid_detected;
unsigned blksize;
+ size_t symlink_prefix_len;
+ char symlink_prefix[PATH_MAX+1];
};
static struct sshfs sshfs;
@@ -233,8 +236,11 @@
SSHFS_OPT("ssh_protocol=%u", ssh_ver, 0),
SSHFS_OPT("-1", ssh_ver, 1),
SSHFS_OPT("workaround=none", rename_workaround, 0),
+ SSHFS_OPT("workaround=none", symlink_workaround, 0),
SSHFS_OPT("workaround=rename", rename_workaround, 1),
+ SSHFS_OPT("workaround=symlink", symlink_workaround, 1),
SSHFS_OPT("workaround=all", rename_workaround, 1),
+ SSHFS_OPT("workaround=all", symlink_workaround, 1),
SSHFS_OPT("idmap=none", detect_uid, 0),
SSHFS_OPT("idmap=user", detect_uid, 1),
SSHFS_OPT("sshfs_sync", sync_write, 1),
@@ -1157,8 +1163,17 @@
err = -EIO;
if(buf_get_uint32(&name, &count) != -1 && count == 1 &&
buf_get_string(&name, &link) != -1) {
- strncpy(linkbuf, link, size-1);
- linkbuf[size-1] = '\0';
+ if (size>0) {
+ if (link[0]=='/') {
+ size_t len=sshfs.symlink_prefix_len;
+ if (len>size-1) len=size-1;
+ memcpy(linkbuf, sshfs.symlink_prefix, len);
+ linkbuf+=len;
+ size-=len;
+ }
+ strncpy(linkbuf, link, size-1);
+ linkbuf[size-1] = '\0';
+ }
free(link);
err = 0;
}
@@ -1913,6 +1928,7 @@
" none no workarounds enabled (default)\n"
" all all workarounds enabled\n"
" rename work around problem renaming to existing file\n"
+" symlink prepend mountpoint to absolute symlink targets\n"
" -o idmap=TYPE user/group ID mapping, possible types are:\n"
" none no translation of the ID space (default)\n"
" user only translate UID of connecting user\n"
@@ -2066,6 +2082,28 @@
if (sshfs.max_read > 65536)
sshfs.max_read = 65536;
+ if (sshfs.symlink_workaround && outargs.argv[1] == NULL) {
+ fprintf(stderr, "symlink workaround failed: no mountpoint given\n");
+ exit(1);
+ }
+ if (!sshfs.symlink_workaround)
+ sshfs.symlink_prefix_len=0;
+ else if (realpath(outargs.argv[1], sshfs.symlink_prefix)!=NULL)
+ sshfs.symlink_prefix_len=strlen(sshfs.symlink_prefix);
+ else {
+ sshfs.symlink_prefix_len=strlen(outargs.argv[1]);
+ if (outargs.argv[1][sshfs.symlink_prefix_len-1]=='/')
+ --sshfs.symlink_prefix_len;
+ if (outargs.argv[1][0]=='/' &&
+ sshfs.symlink_prefix_len<=sizeof sshfs.symlink_prefix) {
+ memcpy(sshfs.symlink_prefix, outargs.argv[1],
+ sshfs.symlink_prefix_len);
+ } else {
+ perror("unable to normalize mount path");
+ exit(1);
+ }
+ }
+
tmp = g_strdup_printf("-omax_read=%u", sshfs.max_read);
fuse_opt_add_arg(&outargs, tmp);
g_free(tmp);
|