git_connect(): factor out SSH variant handling
We handle plink and tortoiseplink as OpenSSH replacements, by passing the correct command-line options when detecting that they are used. To let users override that auto-detection (in case Git gets it wrong), we need to introduce new code to that end. In preparation for this code, let's factor out the SSH variant handling into its own function, handle_ssh_variant(). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Feb 1, 2017 at 13:01 UTC
e2824e47e792ad1b2862108bc78af4d3468633fb
1 file changed
+46
-26
connect.c
+46
-26
@@ -691,6 +691,44 @@ static const char *get_ssh_command(void)
691
return NULL;
692
}
693
694
+static int handle_ssh_variant(const char *ssh_command, int is_cmdline,
695
+ int *port_option, int *needs_batch)
696
+{
697
+ const char *variant;
698
+ char *p = NULL;
699
+
700
+ if (!is_cmdline) {
701
+ p = xstrdup(ssh_command);
702
+ variant = basename(p);
703
+ } else {
704
+ const char **ssh_argv;
705
+
706
+ p = xstrdup(ssh_command);
707
+ if (split_cmdline(p, &ssh_argv)) {
708
+ variant = basename((char *)ssh_argv[0]);
709
+ /*
710
+ * At this point, variant points into the buffer
711
+ * referenced by p, hence we do not need ssh_argv
712
+ * any longer.
713
+ */
714
+ free(ssh_argv);
715
+ } else
716
+ return 0;
717
+ }
718
+
719
+ if (!strcasecmp(variant, "plink") ||
720
+ !strcasecmp(variant, "plink.exe"))
721
+ *port_option = 'P';
722
+ else if (!strcasecmp(variant, "tortoiseplink") ||
723
+ !strcasecmp(variant, "tortoiseplink.exe")) {
724
+ *port_option = 'P';
725
+ *needs_batch = 1;
726
+ }
727
+ free(p);
728
+
729
+ return 1;
730
+}
731
+
732
/*
733
* This returns a dummy child_process if the transport protocol does not
734
* need fork(2), or a struct child_process object if it does. Once done,
@@ -773,7 +811,6 @@ struct child_process *git_connect(int fd[2], const char *url,
811
int port_option = 'p';
812
char *ssh_host = hostandport;
813
const char *port = NULL;
776
- char *ssh_argv0 = NULL;
814
transport_check_allowed("ssh");
815
get_host_and_port(&ssh_host, &port);
816
@@ -794,15 +831,10 @@ struct child_process *git_connect(int fd[2], const char *url,
831
}
832
833
ssh = get_ssh_command();
797
- if (ssh) {
798
- char *split_ssh = xstrdup(ssh);
799
- const char **ssh_argv;
800
-
801
- if (split_cmdline(split_ssh, &ssh_argv))
802
- ssh_argv0 = xstrdup(ssh_argv[0]);
803
- free(split_ssh);
804
- free((void *)ssh_argv);
805
- } else {
834
+ if (ssh)
835
+ handle_ssh_variant(ssh, 1, &port_option,
836
+ &needs_batch);
837
+ else {
838
/*
839
* GIT_SSH is the no-shell version of
840
* GIT_SSH_COMMAND (and must remain so for
@@ -813,22 +845,10 @@ struct child_process *git_connect(int fd[2], const char *url,
845
ssh = getenv("GIT_SSH");
846
if (!ssh)
847
ssh = "ssh";
816
-
817
- ssh_argv0 = xstrdup(ssh);
818
- }
819
-
820
- if (ssh_argv0) {
821
- const char *base = basename(ssh_argv0);
822
-
823
- if (!strcasecmp(base, "tortoiseplink") ||
824
- !strcasecmp(base, "tortoiseplink.exe")) {
825
- port_option = 'P';
826
- needs_batch = 1;
827
- } else if (!strcasecmp(base, "plink") ||
828
- !strcasecmp(base, "plink.exe")) {
829
- port_option = 'P';
830
- }
831
- free(ssh_argv0);
848
+ else
849
+ handle_ssh_variant(ssh, 0,
850
+ &port_option,
851
+ &needs_batch);
852
}
853
854
argv_array_push(&conn->args, ssh);