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; --===============1718117579== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="jaoouwwPWoQSJZYp" Content-Disposition: ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
--===============1718117579== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="jaoouwwPWoQSJZYp" Content-Disposition: inline --jaoouwwPWoQSJZYp Content-Type: multipart/mixed; boundary="B8ONY/mu/bqBak9m" Content-Disposition: inline --B8ONY/mu/bqBak9m 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 --B8ONY/mu/bqBak9m 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; --B8ONY/mu/bqBak9m-- --jaoouwwPWoQSJZYp 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) iD8DBQFGPpF1XDqn6DSH7HERAmdOAJ9pvgFHZjmWO/WJ0f8xWYlUNMCwkACgu7yz bcEPJ4Yj4/6yS8JPKtQ8z+A= =5Ejn -----END PGP SIGNATURE----- --jaoouwwPWoQSJZYp-- --===============1718117579== 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 --===============1718117579==-- |
![]() |
| Thread Tools | |
| Display Modes | |
|
|