aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-08-09 02:01:54 +0200
committerAris Adamantiadis <aris@0xbadc0de.be>2009-08-09 02:01:54 +0200
commite4da8b99feb82f4b86ec158b8056d24c3a2dde7d (patch)
treed5746e066620a8b1d94b98dbe14f36daf9e4f91f /libssh
parentb9935790791ac6f4708522353f652e769b7ecf6b (diff)
downloadlibssh-e4da8b99feb82f4b86ec158b8056d24c3a2dde7d.tar.gz
libssh-e4da8b99feb82f4b86ec158b8056d24c3a2dde7d.tar.xz
libssh-e4da8b99feb82f4b86ec158b8056d24c3a2dde7d.zip
Initial scp implementation in source tree
Diffstat (limited to 'libssh')
-rw-r--r--libssh/CMakeLists.txt1
-rw-r--r--libssh/libssh.def4
-rw-r--r--libssh/libssh.map4
-rw-r--r--libssh/scp.c94
4 files changed, 103 insertions, 0 deletions
diff --git a/libssh/CMakeLists.txt b/libssh/CMakeLists.txt
index d05d54ce..fa8eb413 100644
--- a/libssh/CMakeLists.txt
+++ b/libssh/CMakeLists.txt
@@ -100,6 +100,7 @@ set(libssh_SRCS
packet.c
poll.c
session.c
+ scp.c
socket.c
string.c
wrapper.c
diff --git a/libssh/libssh.def b/libssh/libssh.def
index 7d8abd4a..b2848ce8 100644
--- a/libssh/libssh.def
+++ b/libssh/libssh.def
@@ -167,6 +167,10 @@ ssh_options_set_timeout
ssh_options_set_username
ssh_options_set_wanted_algos
ssh_print_hexa
+ssh_scp_close
+ssh_scp_free
+ssh_scp_init
+ssh_scp_new
ssh_select
ssh_service_request
ssh_set_blocking
diff --git a/libssh/libssh.map b/libssh/libssh.map
index f925f4ae..b3e22065 100644
--- a/libssh/libssh.map
+++ b/libssh/libssh.map
@@ -188,6 +188,10 @@ SSH_0.4 {
channel_write_stderr;
channel_request_x11;
channel_accept_x11;
+ ssh_scp_new;
+ ssh_scp_free;
+ ssh_scp_init;
+ ssh_scp_close;
sftp_extensions_get_count;
sftp_extensions_get_data;
sftp_extensions_get_name;
diff --git a/libssh/scp.c b/libssh/scp.c
new file mode 100644
index 00000000..84db3b51
--- /dev/null
+++ b/libssh/scp.c
@@ -0,0 +1,94 @@
+/*
+ * scp - SSH scp wrapper functions
+ *
+ * This file is part of the SSH Library
+ *
+ * Copyright (c) 2009 by Aris Adamantiadis <aris@0xbadc0de.be>
+ *
+ * The SSH Library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The SSH Library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the SSH Library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "libssh/priv.h"
+#include <string.h>
+
+/** @brief Creates a new scp session
+ * @param session the SSH session to use
+ * @param mode one of SSH_SCP_WRITE or SSH_SCP_READ, depending if you need to drop files remotely or read them.
+ * It is not possible to combine read and write.
+ * @returns NULL if the creation was impossible.
+ * @returns a ssh_scp handle if it worked.
+ */
+ssh_scp ssh_scp_new(ssh_session session, int mode, const char *location){
+ ssh_scp scp=malloc(sizeof(struct ssh_scp_struct));
+ if(scp == NULL){
+ ssh_set_error(session,SSH_FATAL,"Error allocating memory for ssh_scp");
+ return NULL;
+ }
+ ZERO_STRUCTP(scp);
+ if(mode != SSH_SCP_WRITE && mode != SSH_SCP_READ){
+ ssh_set_error(session,SSH_FATAL,"Invalid mode %d for ssh_scp_new()",mode);
+ ssh_scp_free(scp);
+ return NULL;
+ }
+ scp->session=session;
+ scp->mode=mode;
+ scp->location=strdup(location);
+ scp->channel=NULL;
+ return scp;
+}
+
+int ssh_scp_init(ssh_scp scp){
+ int r;
+ char execbuffer[1024];
+ u_int8_t code;
+ scp->channel=channel_new(scp->session);
+ if(scp->channel == NULL)
+ return SSH_ERROR;
+ r= channel_open_session(scp->channel);
+ if(r==SSH_ERROR){
+ return SSH_ERROR;
+ }
+ if(scp->mode == SSH_SCP_WRITE)
+ snprintf(execbuffer,sizeof(execbuffer),"scp -t %s",scp->location);
+ else
+ snprintf(execbuffer,sizeof(execbuffer),"scp -f %s",scp->location);
+ if(channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){
+ return SSH_ERROR;
+ }
+ r=channel_read(scp->channel,&code,1,0);
+ if(code != 0){
+ ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
+ return SSH_ERROR;
+ }
+ return SSH_OK;
+}
+
+int ssh_scp_close(ssh_scp scp){
+ if(channel_send_eof(scp->channel) == SSH_ERROR)
+ return SSH_ERROR;
+ if(channel_close(scp->channel) == SSH_ERROR)
+ return SSH_ERROR;
+ channel_free(scp->channel);
+ scp->channel=NULL;
+ return SSH_OK;
+}
+
+void ssh_scp_free(ssh_scp scp){
+ if(scp->channel)
+ channel_free(scp->channel);
+ SAFE_FREE(scp->location);
+ SAFE_FREE(scp);
+}