aboutsummaryrefslogtreecommitdiff
path: root/libssh/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/scp.c')
-rw-r--r--libssh/scp.c752
1 files changed, 0 insertions, 752 deletions
diff --git a/libssh/scp.c b/libssh/scp.c
deleted file mode 100644
index 4a6f6f1..0000000
--- a/libssh/scp.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <string.h>
-
-#include "libssh/priv.h"
-#include "libssh/scp.h"
-
-/**
- * @defgroup libssh_scp The SSH scp functions
- * @ingroup libssh
- *
- * SCP protocol over SSH functions
- *
- * @{
- */
-
-/**
- * @brief Create a new scp session.
- *
- * @param[in] session The SSH session to use.
- *
- * @param[in] 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.
- *
- * @param[in] location The directory in which write or read will be done. Any
- * push or pull will be relative to this place.
- *
- * @returns A ssh_scp handle, NULL if the creation was impossible.
- */
-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_RECURSIVE) != SSH_SCP_WRITE && (mode &~SSH_SCP_RECURSIVE) != SSH_SCP_READ){
- ssh_set_error(session,SSH_FATAL,"Invalid mode %d for ssh_scp_new()",mode);
- ssh_scp_free(scp);
- return NULL;
- }
- scp->location=strdup(location);
- if (scp->location == NULL) {
- ssh_set_error(session,SSH_FATAL,"Error allocating memory for ssh_scp");
- ssh_scp_free(scp);
- return NULL;
- }
- scp->session=session;
- scp->mode=mode & ~SSH_SCP_RECURSIVE;
- scp->recursive = (mode & SSH_SCP_RECURSIVE) != 0;
- scp->channel=NULL;
- scp->state=SSH_SCP_NEW;
- return scp;
-}
-
-int ssh_scp_init(ssh_scp scp){
- int r;
- char execbuffer[1024];
- uint8_t code;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_NEW){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_init called under invalid state");
- return SSH_ERROR;
- }
- ssh_log(scp->session,SSH_LOG_PROTOCOL,"Initializing scp session %s %son location '%s'",
- scp->mode==SSH_SCP_WRITE?"write":"read",
- scp->recursive?"recursive ":"",
- scp->location);
- scp->channel=ssh_channel_new(scp->session);
- if(scp->channel == NULL){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- r= ssh_channel_open_session(scp->channel);
- if(r==SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(scp->mode == SSH_SCP_WRITE)
- snprintf(execbuffer,sizeof(execbuffer),"scp -t %s %s",
- scp->recursive ? "-r":"", scp->location);
- else
- snprintf(execbuffer,sizeof(execbuffer),"scp -f %s %s",
- scp->recursive ? "-r":"", scp->location);
- if(ssh_channel_request_exec(scp->channel,execbuffer) == SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(scp->mode == SSH_SCP_WRITE){
- r=ssh_channel_read(scp->channel,&code,1,0);
- if(r<=0){
- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(code != 0){
- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- } else {
- ssh_channel_write(scp->channel,"",1);
- }
- if(scp->mode == SSH_SCP_WRITE)
- scp->state=SSH_SCP_WRITE_INITED;
- else
- scp->state=SSH_SCP_READ_INITED;
- return SSH_OK;
-}
-
-int ssh_scp_close(ssh_scp scp){
- char buffer[128];
- int err;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->channel != NULL){
- if(ssh_channel_send_eof(scp->channel) == SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- /* avoid situations where data are buffered and
- * not yet stored on disk. This can happen if the close is sent
- * before we got the EOF back
- */
- while(!ssh_channel_is_eof(scp->channel)){
- err=ssh_channel_read(scp->channel,buffer,sizeof(buffer),0);
- if(err==SSH_ERROR)
- break;
- }
- if(ssh_channel_close(scp->channel) == SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- ssh_channel_free(scp->channel);
- scp->channel=NULL;
- }
- scp->state=SSH_SCP_NEW;
- return SSH_OK;
-}
-
-void ssh_scp_free(ssh_scp scp){
- if(scp==NULL)
- return;
- if(scp->state != SSH_SCP_NEW)
- ssh_scp_close(scp);
- if(scp->channel)
- ssh_channel_free(scp->channel);
- SAFE_FREE(scp->location);
- SAFE_FREE(scp->request_name);
- SAFE_FREE(scp->warning);
- SAFE_FREE(scp);
-}
-
-/**
- * @brief Create a directory in a scp in sink mode.
- *
- * @param[in] scp The scp handle.
- *
- * @param[in] dirname The name of the directory being created.
- *
- * @param[in] mode The UNIX permissions for the new directory, e.g. 0755.
- *
- * @returns SSH_OK if the directory has been created, SSH_ERROR if
- * an error occured.
- *
- * @see ssh_scp_leave_directory()
- */
-int ssh_scp_push_directory(ssh_scp scp, const char *dirname, int mode){
- char buffer[1024];
- int r;
- uint8_t code;
- char *dir;
- char *perms;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_WRITE_INITED){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_directory called under invalid state");
- return SSH_ERROR;
- }
- dir=ssh_basename(dirname);
- perms=ssh_scp_string_mode(mode);
- snprintf(buffer, sizeof(buffer), "D%s 0 %s\n", perms, dir);
- SAFE_FREE(dir);
- SAFE_FREE(perms);
- r=ssh_channel_write(scp->channel,buffer,strlen(buffer));
- if(r==SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- r=ssh_channel_read(scp->channel,&code,1,0);
- if(r<=0){
- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(code != 0){
- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- return SSH_OK;
-}
-
-/**
- * @brief Leave a directory.
- *
- * @returns SSH_OK if the directory has been left,SSH_ERROR if an
- * error occured.
- *
- * @see ssh_scp_push_directory()
- */
- int ssh_scp_leave_directory(ssh_scp scp){
- char buffer[]="E\n";
- int r;
- uint8_t code;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_WRITE_INITED){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_leave_directory called under invalid state");
- return SSH_ERROR;
- }
- r=ssh_channel_write(scp->channel,buffer,strlen(buffer));
- if(r==SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- r=ssh_channel_read(scp->channel,&code,1,0);
- if(r<=0){
- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(code != 0){
- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- return SSH_OK;
-}
-
-/**
- * @brief Initialize the sending of a file to a scp in sink mode.
- *
- * @param[in] scp The scp handle.
- *
- * @param[in] filename The name of the file being sent. It should not contain
- * any path indicator
- *
- * @param[in] size Exact size in bytes of the file being sent.
- *
- * @param[in] mode The UNIX permissions for the new file, e.g. 0644.
- *
- * @returns SSH_OK if the file is ready to be sent, SSH_ERROR if an
- * error occured.
- */
-int ssh_scp_push_file(ssh_scp scp, const char *filename, size_t size, int mode){
- char buffer[1024];
- int r;
- uint8_t code;
- char *file;
- char *perms;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_WRITE_INITED){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_push_file called under invalid state");
- return SSH_ERROR;
- }
- file=ssh_basename(filename);
- perms=ssh_scp_string_mode(mode);
- ssh_log(scp->session,SSH_LOG_PROTOCOL,"SCP pushing file %s, size %" PRIdS " with permissions '%s'",file,size,perms);
- snprintf(buffer, sizeof(buffer), "C%s %" PRIdS " %s\n", perms, size, file);
- SAFE_FREE(file);
- SAFE_FREE(perms);
- r=ssh_channel_write(scp->channel,buffer,strlen(buffer));
- if(r==SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- r=ssh_channel_read(scp->channel,&code,1,0);
- if(r<=0){
- ssh_set_error(scp->session,SSH_FATAL, "Error reading status code: %s",ssh_get_error(scp->session));
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(code != 0){
- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- scp->filelen = size;
- scp->processed = 0;
- scp->state=SSH_SCP_WRITE_WRITING;
- return SSH_OK;
-}
-
-/**
- * @internal
- *
- * @brief Wait for a response of the scp server.
- *
- * @param[in] scp The scp handle.
- *
- * @param[out] response A pointer where the response message must be copied if
- * any. This pointer must then be free'd.
- *
- * @returns The return code, SSH_ERROR a error occured.
- */
-int ssh_scp_response(ssh_scp scp, char **response){
- unsigned char code;
- int r;
- char msg[128];
- if(scp==NULL)
- return SSH_ERROR;
- r=ssh_channel_read(scp->channel,&code,1,0);
- if(r == SSH_ERROR)
- return SSH_ERROR;
- if(code == 0)
- return 0;
- if(code > 2){
- ssh_set_error(scp->session,SSH_FATAL, "SCP: invalid status code %ud received", code);
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- r=ssh_scp_read_string(scp,msg,sizeof(msg));
- if(r==SSH_ERROR)
- return r;
- /* Warning */
- if(code == 1){
- ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Warning: status code 1 received: %s", msg);
- ssh_log(scp->session,SSH_LOG_RARE,"SCP: Warning: status code 1 received: %s", msg);
- if(response)
- *response=strdup(msg);
- return 1;
- }
- if(code == 2){
- ssh_set_error(scp->session,SSH_FATAL, "SCP: Error: status code 2 received: %s", msg);
- if(response)
- *response=strdup(msg);
- return 2;
- }
- /* Not reached */
- return SSH_ERROR;
-}
-
-/**
- * @brief Write into a remote scp file.
- *
- * @param[in] scp The scp handle.
- *
- * @param[in] buffer The buffer to write.
- *
- * @param[in] len The number of bytes to write.
- *
- * @returns SSH_OK if the write was successful, SSH_ERROR an error
- * occured while writing.
- */
-int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){
- int w;
- //int r;
- //uint8_t code;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_WRITE_WRITING){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_write called under invalid state");
- return SSH_ERROR;
- }
- if(scp->processed + len > scp->filelen)
- len = scp->filelen - scp->processed;
- /* hack to avoid waiting for window change */
- ssh_channel_poll(scp->channel,0);
- w=ssh_channel_write(scp->channel,buffer,len);
- if(w != SSH_ERROR)
- scp->processed += w;
- else {
- scp->state=SSH_SCP_ERROR;
- //return=channel_get_exit_status(scp->channel);
- return SSH_ERROR;
- }
- /* Check if we arrived at end of file */
- if(scp->processed == scp->filelen) {
-/* r=channel_read(scp->channel,&code,1,0);
- if(r==SSH_ERROR){
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- if(code != 0){
- ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code);
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
-*/
- scp->processed=scp->filelen=0;
- scp->state=SSH_SCP_WRITE_INITED;
- }
- return SSH_OK;
-}
-
-/**
- * @brief Read a string on a channel, terminated by '\n'
- *
- * @param[in] scp The scp handle.
- *
- * @param[out] buffer A pointer to a buffer to place the string.
- *
- * @param[in] len The size of the buffer in bytes. If the string is bigger
- * than len-1, only len-1 bytes are read and the string is
- * null-terminated.
- *
- * @returns SSH_OK if the string was read, SSH_ERROR if an error
- * occured while reading.
- */
-int ssh_scp_read_string(ssh_scp scp, char *buffer, size_t len){
- size_t r=0;
- int err=SSH_OK;
- if(scp==NULL)
- return SSH_ERROR;
- while(r<len-1){
- err=ssh_channel_read(scp->channel,&buffer[r],1,0);
- if(err==SSH_ERROR){
- break;
- }
- if(err==0){
- ssh_set_error(scp->session,SSH_FATAL,"End of file while reading string");
- err=SSH_ERROR;
- break;
- }
- r++;
- if(buffer[r-1] == '\n')
- break;
- }
- buffer[r]=0;
- return err;
-}
-
-/**
- * @brief Wait for a scp request (file, directory).
- *
- * @returns SSH_SCP_REQUEST_NEWFILE: The other side is sending
- * a file
- * SSH_SCP_REQUEST_NEWDIRECTORY: The other side is sending
- * a directory
- * SSH_SCP_REQUEST_END_DIRECTORY: The other side has
- * finished with the current
- * directory
- * SSH_ERROR: Some error happened
- *
- * @see ssh_scp_read()
- * @see ssh_scp_deny_request()
- * @see ssh_scp_accept_request()
- */
-int ssh_scp_pull_request(ssh_scp scp){
- char buffer[4096];
- char *mode=NULL;
- char *p,*tmp;
- size_t size;
- char *name=NULL;
- int err;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_READ_INITED){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_pull_request called under invalid state");
- return SSH_ERROR;
- }
- err=ssh_scp_read_string(scp,buffer,sizeof(buffer));
- if(err==SSH_ERROR){
- if(ssh_channel_is_eof(scp->channel)){
- scp->state=SSH_SCP_TERMINATED;
- return SSH_SCP_REQUEST_EOF;
- }
- return err;
- }
- p=strchr(buffer,'\n');
- if(p!=NULL)
- *p='\0';
- ssh_log(scp->session,SSH_LOG_PROTOCOL,"Received SCP request: '%s'",buffer);
- switch(buffer[0]){
- case 'C':
- /* File */
- case 'D':
- /* Directory */
- p=strchr(buffer,' ');
- if(p==NULL)
- goto error;
- *p='\0';
- p++;
- //mode=strdup(&buffer[1]);
- scp->request_mode=ssh_scp_integer_mode(&buffer[1]);
- tmp=p;
- p=strchr(p,' ');
- if(p==NULL)
- goto error;
- *p=0;
- size=strtoull(tmp,NULL,10);
- p++;
- name=strdup(p);
- SAFE_FREE(scp->request_name);
- scp->request_name=name;
- if(buffer[0]=='C'){
- scp->filelen=size;
- scp->request_type=SSH_SCP_REQUEST_NEWFILE;
- } else {
- scp->filelen='0';
- scp->request_type=SSH_SCP_REQUEST_NEWDIR;
- }
- scp->state=SSH_SCP_READ_REQUESTED;
- scp->processed = 0;
- return scp->request_type;
- break;
- case 'E':
- scp->request_type=SSH_SCP_REQUEST_ENDDIR;
- ssh_channel_write(scp->channel,"",1);
- return scp->request_type;
- case 0x1:
- ssh_set_error(scp->session,SSH_REQUEST_DENIED,"SCP: Warning: %s",&buffer[1]);
- scp->request_type=SSH_SCP_REQUEST_WARNING;
- SAFE_FREE(scp->warning);
- scp->warning=strdup(&buffer[1]);
- return scp->request_type;
- case 0x2:
- ssh_set_error(scp->session,SSH_FATAL,"SCP: Error: %s",&buffer[1]);
- return SSH_ERROR;
- case 'T':
- /* Timestamp */
- default:
- ssh_set_error(scp->session,SSH_FATAL,"Unhandled message: (%d)%s",buffer[0],buffer);
- return SSH_ERROR;
- }
-
- /* a parsing error occured */
- error:
- SAFE_FREE(name);
- SAFE_FREE(mode);
- ssh_set_error(scp->session,SSH_FATAL,"Parsing error while parsing message: %s",buffer);
- return SSH_ERROR;
-}
-
-/**
- * @brief Deny the transfer of a file or creation of a directory coming from the
- * remote party.
- *
- * @param[in] scp The scp handle.
- * @param[in] reason A nul-terminated string with a human-readable
- * explanation of the deny.
- *
- * @returns SSH_OK if the message was sent, SSH_ERROR if the sending
- * the message failed, or sending it in a bad state.
- */
-int ssh_scp_deny_request(ssh_scp scp, const char *reason){
- char buffer[4096];
- int err;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_READ_REQUESTED){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state");
- return SSH_ERROR;
- }
- snprintf(buffer,sizeof(buffer),"%c%s\n",2,reason);
- err=ssh_channel_write(scp->channel,buffer,strlen(buffer));
- if(err==SSH_ERROR) {
- return SSH_ERROR;
- }
- else {
- scp->state=SSH_SCP_READ_INITED;
- return SSH_OK;
- }
-}
-
-/**
- * @brief Accepts transfer of a file or creation of a directory coming from the
- * remote party.
- *
- * @param[in] scp The scp handle.
- *
- * @returns SSH_OK if the message was sent, SSH_ERROR if sending the
- * message failed, or sending it in a bad state.
- */
-int ssh_scp_accept_request(ssh_scp scp){
- char buffer[]={0x00};
- int err;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state != SSH_SCP_READ_REQUESTED){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_deny_request called under invalid state");
- return SSH_ERROR;
- }
- err=ssh_channel_write(scp->channel,buffer,1);
- if(err==SSH_ERROR) {
- return SSH_ERROR;
- }
- if(scp->request_type==SSH_SCP_REQUEST_NEWFILE)
- scp->state=SSH_SCP_READ_READING;
- else
- scp->state=SSH_SCP_READ_INITED;
- return SSH_OK;
-}
-
-/** @brief Read from a remote scp file
- * @param[in] scp The scp handle.
- *
- * @param[in] buffer The destination buffer.
- *
- * @param[in] size The size of the buffer.
- *
- * @returns The nNumber of bytes read, SSH_ERROR if an error occured
- * while reading.
- */
-int ssh_scp_read(ssh_scp scp, void *buffer, size_t size){
- int r;
- int code;
- if(scp==NULL)
- return SSH_ERROR;
- if(scp->state == SSH_SCP_READ_REQUESTED && scp->request_type == SSH_SCP_REQUEST_NEWFILE){
- r=ssh_scp_accept_request(scp);
- if(r==SSH_ERROR)
- return r;
- }
- if(scp->state != SSH_SCP_READ_READING){
- ssh_set_error(scp->session,SSH_FATAL,"ssh_scp_read called under invalid state");
- return SSH_ERROR;
- }
- if(scp->processed + size > scp->filelen)
- size = scp->filelen - scp->processed;
- if(size > 65536)
- size=65536; /* avoid too large reads */
- r=ssh_channel_read(scp->channel,buffer,size,0);
- if(r != SSH_ERROR)
- scp->processed += r;
- else {
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- /* Check if we arrived at end of file */
- if(scp->processed == scp->filelen) {
- scp->processed=scp->filelen=0;
- ssh_channel_write(scp->channel,"",1);
- code=ssh_scp_response(scp,NULL);
- if(code == 0){
- scp->state=SSH_SCP_READ_INITED;
- return r;
- }
- if(code==1){
- scp->state=SSH_SCP_READ_INITED;
- return SSH_ERROR;
- }
- scp->state=SSH_SCP_ERROR;
- return SSH_ERROR;
- }
- return r;
-}
-
-/**
- * @brief Get the name of the directory or file being pushed from the other
- * party.
- *
- * @returns The file name, NULL on error. The string should not be
- * freed.
- */
-const char *ssh_scp_request_get_filename(ssh_scp scp){
- if(scp==NULL)
- return NULL;
- return scp->request_name;
-}
-
-/**
- * @brief Get the permissions of the directory or file being pushed from the
- * other party.
- *
- * @returns The UNIX permission, e.g 0644, -1 on error.
- */
-int ssh_scp_request_get_permissions(ssh_scp scp){
- if(scp==NULL)
- return -1;
- return scp->request_mode;
-}
-
-/** @brief Get the size of the file being pushed from the other party.
- *
- * @returns The numeric size of the file being read.
- */
-size_t ssh_scp_request_get_size(ssh_scp scp){
- if(scp==NULL)
- return 0;
- return scp->filelen;
-}
-
-/**
- * @brief Convert a scp text mode to an integer.
- *
- * @param[in] mode The mode to convert, e.g. "0644".
- *
- * @returns An integer value, e.g. 420 for "0644".
- */
-int ssh_scp_integer_mode(const char *mode){
- int value=strtoul(mode,NULL,8) & 0xffff;
- return value;
-}
-
-/**
- * @brief Convert a unix mode into a scp string.
- *
- * @param[in] mode The mode to convert, e.g. 420 or 0644.
- *
- * @returns A pointer to a malloc'ed string containing the scp mode,
- * e.g. "0644".
- */
-char *ssh_scp_string_mode(int mode){
- char buffer[16];
- snprintf(buffer,sizeof(buffer),"%.4o",mode);
- return strdup(buffer);
-}
-
-/**
- * @brief Get the warning string from a scp handle.
- *
- * @param[in] scp The scp handle.
- *
- * @returns A warning string, or NULL on error. The string should
- * not be freed.
- */
-const char *ssh_scp_request_get_warning(ssh_scp scp){
- if(scp==NULL)
- return NULL;
- return scp->warning;
-}
-
-/** @} */
-
-/* vim: set ts=4 sw=4 et cindent: */