diff options
Diffstat (limited to 'sshfs.c')
-rw-r--r-- | sshfs.c | 170 |
1 files changed, 37 insertions, 133 deletions
@@ -132,8 +132,6 @@ #define SFTP_SERVER_PATH "/usr/lib/sftp-server" -#define SSHNODELAY_SO "sshnodelay.so" - /* Asynchronous readdir parameters */ #define READDIR_START 2 #define READDIR_MAX 32 @@ -216,8 +214,6 @@ struct sshfs { struct fuse_args ssh_args; char *workarounds; int rename_workaround; - int nodelay_workaround; - int nodelaysrv_workaround; int truncate_workaround; int buflimit_workaround; int fstat_workaround; @@ -297,6 +293,7 @@ static const char *ssh_opts[] = { "AddressFamily", "BatchMode", "BindAddress", + "CertificateFile", "ChallengeResponseAuthentication", "CheckHostIP", "Cipher", @@ -307,28 +304,40 @@ static const char *ssh_opts[] = { "ConnectTimeout", "ControlMaster", "ControlPath", + "ControlPersist", + "FingerprintHash", "GlobalKnownHostsFile", "GSSAPIAuthentication", "GSSAPIDelegateCredentials", "HostbasedAuthentication", + "HostbasedKeyTypes", "HostKeyAlgorithms", "HostKeyAlias", "HostName", "IdentitiesOnly", "IdentityFile", + "IdentityAgent", + "IPQoS", "KbdInteractiveAuthentication", "KbdInteractiveDevices", + "KexAlgorithms", "LocalCommand", "LogLevel", "MACs", "NoHostAuthenticationForLocalhost", "NumberOfPasswordPrompts", "PasswordAuthentication", + "PermitLocalCommand", + "PKCS11Provider", "Port", "PreferredAuthentications", "ProxyCommand", + "ProxyJump", + "ProxyUseFdpass", + "PubkeyAcceptedKeyTypes" "PubkeyAuthentication", "RekeyLimit", + "RevokedHostKeys", "RhostsRSAAuthentication", "RSAAuthentication", "ServerAliveCountMax", @@ -336,9 +345,11 @@ static const char *ssh_opts[] = { "SmartcardDevice", "StrictHostKeyChecking", "TCPKeepAlive", + "UpdateHostKeys", "UsePrivilegedPort", "UserKnownHostsFile", "VerifyHostKeyDNS", + "VisualHostKey", NULL, }; @@ -408,23 +419,11 @@ static struct fuse_opt sshfs_opts[] = { static struct fuse_opt workaround_opts[] = { SSHFS_OPT("none", rename_workaround, 0), - SSHFS_OPT("none", nodelay_workaround, 0), - SSHFS_OPT("none", nodelaysrv_workaround, 0), SSHFS_OPT("none", truncate_workaround, 0), SSHFS_OPT("none", buflimit_workaround, 0), SSHFS_OPT("none", fstat_workaround, 0), - SSHFS_OPT("all", rename_workaround, 1), - SSHFS_OPT("all", nodelay_workaround, 1), - SSHFS_OPT("all", nodelaysrv_workaround, 1), - SSHFS_OPT("all", truncate_workaround, 1), - SSHFS_OPT("all", buflimit_workaround, 1), - SSHFS_OPT("all", fstat_workaround, 1), SSHFS_OPT("rename", rename_workaround, 1), SSHFS_OPT("norename", rename_workaround, 0), - SSHFS_OPT("nodelay", nodelay_workaround, 1), - SSHFS_OPT("nonodelay", nodelay_workaround, 0), - SSHFS_OPT("nodelaysrv", nodelaysrv_workaround, 1), - SSHFS_OPT("nonodelaysrv", nodelaysrv_workaround, 0), SSHFS_OPT("truncate", truncate_workaround, 1), SSHFS_OPT("notruncate", truncate_workaround, 0), SSHFS_OPT("buflimit", buflimit_workaround, 1), @@ -877,85 +876,6 @@ static void ssh_add_arg(const char *arg) _exit(1); } -#ifdef SSH_NODELAY_WORKAROUND -static int do_ssh_nodelay_workaround(void) -{ -#ifdef __APPLE__ - char *oldpreload = getenv("DYLD_INSERT_LIBRARIES"); -#else - char *oldpreload = getenv("LD_PRELOAD"); -#endif - char *newpreload; - char sopath[PATH_MAX]; - int res; - -#ifdef __APPLE__ - char *sshfs_program_path_base = NULL; - if (!sshfs_program_path[0]) { - goto nobundle; - } - sshfs_program_path_base = dirname(sshfs_program_path); - if (!sshfs_program_path_base) { - goto nobundle; - } - snprintf(sopath, sizeof(sopath), "%s/%s", sshfs_program_path_base, - SSHNODELAY_SO); - res = access(sopath, R_OK); - if (res == -1) { - goto nobundle; - } - goto pathok; - -nobundle: -#endif /* __APPLE__ */ - - snprintf(sopath, sizeof(sopath), "%s/%s", LIBDIR, SSHNODELAY_SO); - res = access(sopath, R_OK); - if (res == -1) { - char *s; - if (!realpath(sshfs.progname, sopath)) - return -1; - - s = strrchr(sopath, '/'); - if (!s) - s = sopath; - else - s++; - - if (s + strlen(SSHNODELAY_SO) >= sopath + sizeof(sopath)) - return -1; - - strcpy(s, SSHNODELAY_SO); - res = access(sopath, R_OK); - if (res == -1) { - fprintf(stderr, "sshfs: cannot find %s\n", - SSHNODELAY_SO); - return -1; - } - } - -#ifdef __APPLE__ -pathok: -#endif - - newpreload = g_strdup_printf("%s%s%s", - oldpreload ? oldpreload : "", - oldpreload ? " " : "", - sopath); - -#ifdef __APPLE__ - if (!newpreload || setenv("DYLD_INSERT_LIBRARIES", newpreload, 1) == -1) - fprintf(stderr, "warning: failed set DYLD_INSERT_LIBRARIES for ssh nodelay workaround\n"); -#else /* !__APPLE__ */ - if (!newpreload || setenv("LD_PRELOAD", newpreload, 1) == -1) { - fprintf(stderr, "warning: failed set LD_PRELOAD " - "for ssh nodelay workaround\n"); - } -#endif /* __APPLE__ */ - g_free(newpreload); - return 0; -} -#endif static int pty_expect_loop(void) { @@ -1089,29 +1009,6 @@ static int start_ssh(void) } else if (pid == 0) { int devnull; -#ifdef SSH_NODELAY_WORKAROUND - if (sshfs.nodelay_workaround && - do_ssh_nodelay_workaround() == -1) { - fprintf(stderr, - "warning: ssh nodelay workaround disabled\n"); - } -#endif - - if (sshfs.nodelaysrv_workaround) { - int i; - /* - * Hack to work around missing TCP_NODELAY - * setting in sshd - */ - for (i = 1; i < sshfs.ssh_args.argc; i++) { - if (strcmp(sshfs.ssh_args.argv[i], "-x") == 0) { - replace_arg(&sshfs.ssh_args.argv[i], - "-X"); - break; - } - } - } - devnull = open("/dev/null", O_WRONLY); if (dup2(sockpair[1], 0) == -1 || dup2(sockpair[1], 1) == -1) { @@ -2178,11 +2075,16 @@ static int sftp_readdir_async(struct buffer *handle, fuse_cache_dirh_t h, outstanding--; if (done) { + /* We need to cache want_reply, since processing + thread may free req right after unlock() if + want_reply == 0 */ + int want_reply; pthread_mutex_lock(&sshfs.lock); if (sshfs_req_pending(req)) req->want_reply = 0; + want_reply = req->want_reply; pthread_mutex_unlock(&sshfs.lock); - if (!req->want_reply) + if (!want_reply) continue; } @@ -2645,7 +2547,8 @@ static int sshfs_fsync(const char *path, int isdatasync, int err; (void) isdatasync; - if (err = sshfs_flush(path, fi)) + err = sshfs_flush(path, fi); + if (err) return err; if (!sshfs.ext_fsync) @@ -3422,14 +3325,10 @@ static void usage(const char *progname) " cache if full (default: 5)\n" " -o workaround=LIST colon separated list of workarounds\n" " none no workarounds enabled\n" -" all all workarounds enabled\n" " [no]rename fix renaming to existing file (default: off)\n" -#ifdef SSH_NODELAY_WORKAROUND -" [no]nodelay set nodelay tcp flag in ssh (default: on)\n" -#endif -" [no]nodelaysrv set nodelay tcp flag in sshd (default: off)\n" " [no]truncate fix truncate for old servers (default: off)\n" " [no]buflimit fix buffer fillup bug in server (default: on)\n" +" [no]fstat fix fstat for old servers (default: off)\n" " -o idmap=TYPE user/group ID mapping (default: " IDMAP_DEFAULT ")\n" " none no translation of the ID space\n" " user only translate UID/GID of connecting user\n" @@ -3549,10 +3448,14 @@ static int workaround_opt_proc(void *data, const char *arg, int key, return -1; } -int parse_workarounds(void) +static int parse_workarounds(void) { int res; - char *argv[] = { "", "-o", sshfs.workarounds, NULL }; + /* Need separate variables because literals are const + char */ + char argv0[] = ""; + char argv1[] = "-o"; + char *argv[] = { argv0, argv1, sshfs.workarounds, NULL }; struct fuse_args args = FUSE_ARGS_INIT(3, argv); char *s = sshfs.workarounds; if (!s) @@ -3958,14 +3861,11 @@ int main(int argc, char *argv[]) memset(sshfs_program_path, 0, PATH_MAX); } #endif /* __APPLE__ */ - g_thread_init(NULL); sshfs.blksize = 4096; /* SFTP spec says all servers should allow at least 32k I/O */ sshfs.max_read = 32768; sshfs.max_write = 32768; - sshfs.nodelay_workaround = 1; - sshfs.nodelaysrv_workaround = 0; #ifdef __APPLE__ sshfs.rename_workaround = 1; #else @@ -4164,6 +4064,13 @@ int main(int argc, char *argv[]) exit(1); } + res = fuse_set_signal_handlers(fuse_get_session(fuse)); + if (res == -1) { + fuse_unmount(mountpoint, ch); + fuse_destroy(fuse); + exit(1); + } + /* * FIXME: trim $PATH so it doesn't contain anything inside the * mountpoint, which would deadlock. @@ -4176,9 +4083,6 @@ int main(int argc, char *argv[]) } res = fuse_daemonize(foreground); - if (res != -1) - res = fuse_set_signal_handlers(fuse_get_session(fuse)); - if (res == -1) { fuse_unmount(mountpoint, ch); fuse_destroy(fuse); |