From 3c767cb5c1113d2b9a340fb2dae2527f71a52a39 Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <gnu@gisladisker.se>
Date: Sat, 23 Jan 2016 22:47:41 +0100
Subject: [PATCH 14/60] ftp: Allow remote user in command.

Implement the extended host argument form `user@host'
for quick selection of the remote user name.
---
 ChangeLog          | 12 ++++++++++++
 NEWS               |  5 +++++
 doc/inetutils.texi |  9 +++++++++
 ftp/ftp.c          | 17 +++++++++++++++--
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f9c72ba8..78c783f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2016-01-23  Mats Erik Andersson  <gnu@gisladisker.se>
+
+	ftp: Allow remote user in command.
+
+	* ftp/ftp.c (hookup): Check for an embedded at-sign in the input
+	variable `host', keeping the rightmost part.  New variable P.
+	(login): Likewise, but also using the string part to the left of
+	the last at-sign as remote user name.
+
+	* doc/inetutils.texi (ftp invocation): Document this ability.
+	* NEWS: Likewise.
+
 2015-12-29  Mats Erik Andersson  <gnu@gisladisker.se>
 
 	tests/ftp-localhost.sh: Incomplete error handling.
diff --git a/NEWS b/NEWS
index ddab50a0..53cacfa2 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,11 @@ Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
 Foundation, Inc.  See the end of this file for license conditions.
 
 Please send inetutils bug reports to <bug-inetutils@gnu.org>.
+
+* ftp
+
+Allow invocation, as well as command `open', to accept an explicit
+remote user name as extended host argument: `user@host'.
 
 June 9, 2015
 Version 1.9.4:
diff --git a/doc/inetutils.texi b/doc/inetutils.texi
index 775b9a82..4fd9e2c2 100644
--- a/doc/inetutils.texi
+++ b/doc/inetutils.texi
@@ -1328,6 +1328,9 @@ Synopsis:
 @example
 ftp [@var{option}@dots{}] [@var{host} [@var{port}]]
 pftp [@var{option}@dots{}] [@var{host} [@var{port}]]
+
+ftp [@var{option}@dots{}] @var{user@@host} [@var{port}]
+pftp [@var{option}@dots{}] @var{user@@host} [@var{port}]
 @end example
 
 @noindent
@@ -1338,6 +1341,7 @@ The client host with which @command{ftp} is to communicate may be
 specified on the command line.
 If this is done, @command{ftp} will immediately attempt to establish
 a connection to the FTP server running on that host.
+Optionally, a remote user name can be specified at will.
 Otherwise, the program will start a command interpreter and will await
 further instructions from the user.
 Commands can either be entered interactively,
@@ -1805,6 +1809,7 @@ character's position in @var{inchars} is longer than the length of
 @var{outchars}, the character is deleted from the file name.
 
 @item open @var{host} [@var{port}]
+@itemx open @var{user@@host} [@var{port}]
 Establish a connection to the specified FTP server
 at @var{host}.  An optional port number may be supplied,
 in which case, @command{ftp} will attempt to contact the server
@@ -1812,6 +1817,10 @@ at that specific TCP port.  If the @code{autologin} option
 is on (is so by default), @command{ftp} will also attempt to
 automatically log the user in to the FTP server.
 
+The second form of invocation sets the remote user name to @var{user},
+which otherwise is taken as identical to the user identity owning the
+local session.
+
 @item passive
 Toggle passive mode.  If passive mode is turned on (default is off),
 the @command{ftp} client will send a @code{PASV} command for all data
diff --git a/ftp/ftp.c b/ftp/ftp.c
index 98135865..d3726069 100644
--- a/ftp/ftp.c
+++ b/ftp/ftp.c
@@ -133,7 +133,11 @@ hookup (char *host, int port)
   int s, tos;
   socklen_t len;
   static char hostnamebuf[80];
-  char *rhost;
+  char *rhost, *p;
+
+  p = strrchr (host, '@');
+  if (p && p != host && isprint (p[1]))
+    host = ++p;
 
 #ifdef HAVE_IDN
   status = idna_to_ascii_lz (host, &rhost, 0);
@@ -293,7 +297,7 @@ int
 login (char *host)
 {
   char tmp[80];
-  char *user, *pass, *acct;
+  char *user, *pass, *acct, *p;
   int n, aflag = 0;
 
   user = pass = acct = 0;
@@ -302,6 +306,15 @@ login (char *host)
       code = -1;
       return (0);
     }
+
+  p = strrchr (host, '@');
+  if (user == NULL && p && p != host && isprint (p[1]))
+    {
+      *p = 0;
+      user = host;
+      host = ++p;
+    }
+
   while (user == NULL)
     {
       char *myname = getlogin ();
-- 
2.26.0.292.g33ef6b2f38

