[PATCH] Adds support for SSH_FXP_LINK request to sftp-server and sftp

This is a discussion on [PATCH] Adds support for SSH_FXP_LINK request to sftp-server and sftp within the OpenSSH Development forums, part of the Networking and Network Related category; --===============1807613385== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="LvAn5G4Ewe70kJ1i" Content-Disposition: ...


Go Back   Usenet Forums > Networking and Network Related > OpenSSH Development

FAQ Members List Calendar Search Today's Posts Mark Forums Read
  #1 (permalink)  
Old 05-07-2007
Peter Collingbourne
 
Posts: n/a
Default [PATCH] Adds support for SSH_FXP_LINK request to sftp-server and sftp


--===============1807613385==
Content-Type: multipart/signed; micalg=pgp-sha1;
protocol="application/pgp-signature"; boundary="LvAn5G4Ewe70kJ1i"
Content-Disposition: inline


--LvAn5G4Ewe70kJ1i
Content-Type: multipart/mixed; boundary="TxukmIqg3MmZ0Kmh"
Content-Disposition: inline


--TxukmIqg3MmZ0Kmh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Dear list,

Attached is a patch that adds support for the SSH_FXP_LINK request, as
described in draft-ietf-secsh-filexfer-07 onwards, to the sftp server
and client. It is for and has been tested on the current portable
snapshot but also applies to openbsd CVS.

Thanks,
--=20
Peter

--TxukmIqg3MmZ0Kmh
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="openssh-sftp-hardlink-pcvs-v2.patch"
Content-Transfer-Encoding: quoted-printable

diff -ur openssh.orig/sftp.1 openssh/sftp.1
--- openssh.orig/sftp.1 2006-01-20 00:31:47.000000000 +0000
+++ openssh/sftp.1 2007-05-07 03:27:27.000000000 +0100
@@ -321,11 +321,17 @@
.It Ic lmkdir Ar path
Create local directory specified by
.Ar path .
-.It Ic ln Ar oldpath Ar newpath
-Create a symbolic link from
+.It Xo Ic ln
+.Op Fl s
+.Ar oldpath Ar newpath
+.Xc
+Create a hard link from
.Ar oldpath
to
-.Ar newpath .
+.Ar newpath ,
+or a symbolic link if the
+.Fl s
+flag is specified.
.It Ic lpwd
Print local working directory.
.It Xo Ic ls
diff -ur openssh.orig/sftp.c openssh/sftp.c
--- openssh.orig/sftp.c 2007-01-05 05:30:41.000000000 +0000
+++ openssh/sftp.c 2007-05-07 02:34:48.000000000 +0100
@@ -122,6 +122,7 @@
#define I_SYMLINK 21
#define I_VERSION 22
#define I_PROGRESS 23
+#define I_LINK 24
=20
struct CMD {
const char *c;
@@ -144,7 +145,7 @@
{ "lchdir", I_LCHDIR },
{ "lls", I_LLS },
{ "lmkdir", I_LMKDIR },
- { "ln", I_SYMLINK },
+ { "ln", I_LINK },
{ "lpwd", I_LPWD },
{ "ls", I_LS },
{ "lumask", I_LUMASK },
@@ -202,7 +203,7 @@
printf("help Display this help text\n");
printf("get remote-path [local-path] Download file\n");
printf("lls [ls-options [path]] Display local directory listing\n");
- printf("ln oldpath newpath Symlink remote file\n");
+ printf("ln [-s] oldpath newpath (Sym)link remote file\n");
printf("lmkdir path Create local directory\n");
printf("lpwd Print local working directory\n");
printf("ls [path] Display remote directory listing\n"=
);
@@ -369,6 +370,29 @@
}
=20
static int
+parse_link_flags(const char **cpp, int *sflag)
+{
+ const char *cp =3D *cpp;
+
+ /* Check for flags */
+ if (cp[0] =3D=3D '-' && cp[1] && strchr(WHITESPACE, cp[2])) {
+ switch (cp[1]) {
+ case 's':
+ case 'S':
+ *sflag =3D 1;
+ break;
+ default:
+ error("Invalid flag -%c", cp[1]);
+ return(-1);
+ }
+ cp +=3D 2;
+ *cpp =3D cp + strspn(cp, WHITESPACE);
+ }
+
+ return(0);
+}
+
+static int
parse_ls_flags(const char **cpp, int *lflag)
{
const char *cp =3D *cpp;
@@ -867,7 +891,7 @@
}
=20
static int
-parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
+parse_args(const char **cpp, int *pflag, int *lflag, int *sflag, int *ifla=
g,
unsigned long *n_arg, char **path1, char **path2)
{
const char *cmd, *cp =3D *cpp;
@@ -915,7 +939,7 @@
}
=20
/* Get arguments and parse flags */
- *lflag =3D *pflag =3D *n_arg =3D 0;
+ *sflag =3D *lflag =3D *pflag =3D *n_arg =3D 0;
*path1 =3D *path2 =3D NULL;
switch (cmdnum) {
case I_GET:
@@ -934,6 +958,9 @@
if (get_pathname(&cp, path2))
return(-1);
break;
+ case I_LINK:
+ if (parse_link_flags(&cp, sflag))
+ return(-1);
case I_RENAME:
case I_SYMLINK:
if (get_pathname(&cp, path1))
@@ -1027,7 +1054,7 @@
int err_abort)
{
char *path1, *path2, *tmp;
- int pflag, lflag, iflag, cmdnum, i;
+ int pflag, lflag, sflag, iflag, cmdnum, i;
unsigned long n_arg;
Attrib a, *aa;
char path_buf[MAXPATHLEN];
@@ -1035,7 +1062,7 @@
glob_t g;
=20
path1 =3D path2 =3D NULL;
- cmdnum =3D parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
+ cmdnum =3D parse_args(&cmd, &pflag, &lflag, &sflag, &iflag, &n_arg,
&path1, &path2);
=20
if (iflag !=3D 0)
@@ -1067,6 +1094,13 @@
path2 =3D make_absolute(path2, *pwd);
err =3D do_symlink(conn, path1, path2);
break;
+ case I_LINK:
+ if (!sflag) {
+ path1 =3D make_absolute(path1, *pwd);
+ }
+ path2 =3D make_absolute(path2, *pwd);
+ err =3D do_link(conn, path1, path2, sflag);
+ break;
case I_RM:
path1 =3D make_absolute(path1, *pwd);
remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
diff -ur openssh.orig/sftp-client.c openssh/sftp-client.c
--- openssh.orig/sftp-client.c 2007-02-19 11:13:39.000000000 +0000
+++ openssh/sftp-client.c 2007-05-07 02:34:48.000000000 +0100
@@ -686,6 +686,39 @@
return(status);
}
=20
+int
+do_link(struct sftp_conn *conn, char *oldpath, char *newpath, int sym)
+{
+ Buffer msg;
+ u_int status, id;
+
+ if (conn->version < 3) {
+ error("This server does not support the link operation");
+ return(SSH2_FX_OP_UNSUPPORTED);
+ }
+
+ buffer_init(&msg);
+
+ /* Send link request */
+ id =3D conn->msg_id++;
+ buffer_put_char(&msg, SSH2_FXP_LINK);
+ buffer_put_int(&msg, id);
+ buffer_put_cstring(&msg, newpath);
+ buffer_put_cstring(&msg, oldpath);
+ buffer_put_char(&msg, sym);
+ send_msg(conn->fd_out, &msg);
+ debug3("Sent message SSH2_FXP_LINK \"%s\" -> \"%s\" (sym=3D%d)", oldpath,
+ newpath, sym);
+ buffer_free(&msg);
+
+ status =3D get_status(conn->fd_in, id);
+ if (status !=3D SSH2_FX_OK)
+ error("Couldn't link file \"%s\" to \"%s\": %s", oldpath,
+ newpath, fx2txt(status));
+
+ return(status);
+}
+
char *
do_readlink(struct sftp_conn *conn, char *path)
{
diff -ur openssh.orig/sftp-client.h openssh/sftp-client.h
--- openssh.orig/sftp-client.h 2005-05-26 03:05:49.000000000 +0100
+++ openssh/sftp-client.h 2007-05-07 02:34:48.000000000 +0100
@@ -76,9 +76,12 @@
/* Rename 'oldpath' to 'newpath' */
int do_rename(struct sftp_conn *, char *, char *);
=20
-/* Rename 'oldpath' to 'newpath' */
+/* Symlink 'oldpath' to 'newpath' */
int do_symlink(struct sftp_conn *, char *, char *);
=20
+/* Link 'oldpath' to 'newpath', with a symlink if 'sflag' is set */
+int do_link(struct sftp_conn *, char *, char *, int);
+
/* Return target of symlink 'path' - caller must free result */
char *do_readlink(struct sftp_conn *, char *);
=20
diff -ur openssh.orig/sftp.h openssh/sftp.h
--- openssh.orig/sftp.h 2006-03-26 04:30:02.000000000 +0100
+++ openssh/sftp.h 2007-05-07 02:34:48.000000000 +0100
@@ -52,6 +52,7 @@
#define SSH2_FXP_RENAME 18
#define SSH2_FXP_READLINK 19
#define SSH2_FXP_SYMLINK 20
+#define SSH2_FXP_LINK 21
=20
/* server to client */
#define SSH2_FXP_VERSION 2
diff -ur openssh.orig/sftp-server.c openssh/sftp-server.c
--- openssh.orig/sftp-server.c 2007-01-05 05:31:03.000000000 +0000
+++ openssh/sftp-server.c 2007-05-07 02:34:48.000000000 +0100
@@ -48,6 +48,7 @@
/* helper */
#define get_int64() buffer_get_int64(&iqueue);
#define get_int() buffer_get_int(&iqueue);
+#define get_char() buffer_get_char(&iqueue);
#define get_string(lenp) buffer_get_string(&iqueue, lenp);
=20
/* Our verbosity */
@@ -1070,6 +1071,32 @@
}
=20
static void
+process_link(void)
+{
+ u_int32_t id;
+ char *oldpath, *newpath;
+ u_int sym;
+ int ret, status;
+
+ id =3D get_int();
+ newpath =3D get_string(NULL);
+ oldpath =3D get_string(NULL);
+ sym =3D get_char();
+ debug3("request %u: link", id);
+ logit("link old \"%s\" new \"%s\" sym %u", oldpath, newpath, sym);
+ /* this will fail if 'newpath' exists */
+ if (sym) {
+ ret =3D symlink(oldpath, newpath);
+ } else {
+ ret =3D link(oldpath, newpath);
+ }
+ status =3D (ret =3D=3D -1) ? errno_to_portable(errno) : SSH2_FX_OK;
+ send_status(id, status);
+ xfree(oldpath);
+ xfree(newpath);
+}
+
+static void
process_extended(void)
{
u_int32_t id;
@@ -1165,6 +1192,9 @@
case SSH2_FXP_SYMLINK:
process_symlink();
break;
+ case SSH2_FXP_LINK:
+ process_link();
+ break;
case SSH2_FXP_EXTENDED:
process_extended();
break;

--TxukmIqg3MmZ0Kmh--

--LvAn5G4Ewe70kJ1i
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: Digital signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFGPrPJXDqn6DSH7HERAikGAJ9XDEg4rBdfoQa2g95LHH l31hh6SACfcu8Q
6Xw1aHHw2u3+CsnubxUb8Uw=
=3fUK
-----END PGP SIGNATURE-----

--LvAn5G4Ewe70kJ1i--

--===============1807613385==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
http://lists.mindrot.org/mailman/lis...enssh-unix-dev

--===============1807613385==--
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT +1. The time now is 07:24 PM.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO 3.0.0