aurora / rmate

Remote TextMate 2 implemented as shell script
GNU General Public License v3.0
887 stars 123 forks source link

Add support for connecting via UNIX socket #63

Closed jordemort closed 6 years ago

jordemort commented 7 years ago

This adds support for connecting via a UNIX socket. I am not aware of any editors that actually implement listening on a UNIX socket, but recent versions of OpenSSH are capable of forwarding a remote socket to a local TCP port, which is how I'm using it. It's nice to have the option for a bit more privacy if you're SSHing into a shared machine, and a bit easier to script around contention between multiple sessions all wanting to forward the same socket.

The socket path can be specified via unix in the config file, -u or --unix on the command-line, or in the RMATE_UNIX environment variable.

This implementation requires that a version of nc that understands the -U option is installed; unfortunately, bash doesn't seem to have a facility for connecting to UNIX sockets like it does for TCP sockets. It could also be implemented in terms of socat or possibly other tools. I'm not sure if it's worth implementing a fallback or some way to customize the command used to connect to the socket; I'd be willing to look into that if there's interest.

aurora commented 7 years ago

Nice! Thank you! I have to play around with this a little before merging :-)

jordemort commented 7 years ago

Cool, I might iterate a bit more on this later tonight to tighten up the error checking and add socat and custom command support.

aurora commented 7 years ago

Btw.: what i am always wondering when writing a shell script -- is there a "best-practice" to check command compatibility? Eg. to verify that nc supports -U in this case? Or is it best to just let it crash, if there's a nc without unix domain socket support?

jordemort commented 7 years ago

@aurora I'm not sure what the best way to detect a nc that supports -U vs an nc that doesn't, which is why I think maybe I should add a way to customize what command is used. I also had the idea that perhaps I could embed a minimal UNIX socket client in perl into rmate as a heredoc, and then write it out and use it. This is the shortest I could get it while still being confident in its correctness:

#!/usr/bin/env perl
use strict; use IO::Socket::UNIX; use IO::Select;

our $U = IO::Socket::UNIX->new($ARGV[0]) or die "$!";
our $S = IO::Select->new(\*STDIN, $U);
map { $_->blocking(0) or die "$!" } $S->handles;
our ($TIMEOUT, $BUFFER);

while (my @in = $S->can_read($TIMEOUT)) {
  HANDLE: for my $in (@in) {
    my $out = $in eq $U ? \*STDOUT : $U;
    unless (read $in, $BUFFER, 1024) {
      shutdown($U, $in eq $U ? 1 : 0); close($out) unless $out eq $U;
      $S->remove($in); $TIMEOUT = 0; next HANDLE;
    }
    print $out $BUFFER; $out->flush();
  }
}

If you don't think that's too big of a chunk of Perl to embed, I think a lot more systems are going to have perl installed by default over socat or an appropriately-enabed nc

aurora commented 7 years ago

Cool. I am undecided whether to include it, though: someone could come up with the question, why rmate wasn't implemented as perl script, instead ;) ... i have to think about this ... too bad, that this can't be done in 100% bash :( ...

jordemort commented 7 years ago

Yeah I was really surprised that bash can connect to TCP sockets on its own but not UNIX ones. If you'd like, I could rework this as a sort of "generic proxy command" support, and leave out any opinions on what that proxy command should be. I could then document examples of how to use nc or socat to connect to a UNIX socket, but actually specifying what command to use would be left as an exercise to the end-user. That would maintain the bash purity of rmate and also absolves us of having to write a lot of fancy error-checking code to see if they have the right version of nc.

aurora commented 7 years ago

@jordemort thought a little more on this, yes i think if you could rework this as "generic proxy command" support and would write an example in the README, that would be awesome. I think in this case we could also include your perl-client as example as standalone script in this repository. Would this be ok for you?

jordemort commented 7 years ago

Sounds good!

aurora commented 7 years ago

@jordemort cool! looking forward to it ...

jordemort commented 7 years ago

@aurora Hey I do intend to come back to this, just have a lot of different things I'm hacking on right now. Hopefully by the end of August :D

aurora commented 7 years ago

@jordemort no problem, i fully understand -- so i am looking forward to end of august or early september ;)

randy3k commented 7 years ago

@jordemort Textmate does support unix socket, see https://github.com/textmate/rmate/pull/38

Is this compatible with it?

jordemort commented 7 years ago

@randy3k Should be; same protocol, different transport

aurora commented 6 years ago

@jordemort Hey, ... i am still interested in having this feature in rmate :). I think i could also help with this, if you do not have time for further development regarding this. Am i right, that it would be "just" a matter of replacing the nc command in line 401 of your pull request https://github.com/aurora/rmate/pull/63/files#diff-047298641ecfdd3128084b5759e836beR401 with a configurable command? The only other question would be, how to specify the proxy-command -- as comandline-argument or make it just configurable in the config-file?

jordemort commented 6 years ago

@aurora Sorry, I have really still been intending to get back to this, but there are a great many things going on for me right now. You're correct, all that would be needed is to replace nc -u "$unix" there with something like $proxy_command, and then replace the --unix switch with a mechanism for the user to specify $proxy_command. If you'd like to go ahead and finish this up yourself instead of waiting for my "someday" to come, I would not be offended :D

aurora commented 6 years ago

@jordemort no worries, i totally understand. No need to hurry, I am currently just between two projects, so i have some spare time to work on rmate. Thanks!