diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-07-25 17:03:01 +0200 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2009-07-25 17:03:01 +0200 |
commit | a935ad1857b91b6aa179d14137f520d978647341 (patch) | |
tree | d86d4f8292843caca7f9155dba40261ea24146d8 /examples/libssh_scp.c | |
parent | 7abb3941c8858204f3d3bc2d59e17fa7b04489bf (diff) | |
download | libssh-a935ad1857b91b6aa179d14137f520d978647341.tar.gz libssh-a935ad1857b91b6aa179d14137f520d978647341.tar.xz libssh-a935ad1857b91b6aa179d14137f520d978647341.zip |
New example directory with the begining of a scp
Diffstat (limited to 'examples/libssh_scp.c')
-rw-r--r-- | examples/libssh_scp.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/examples/libssh_scp.c b/examples/libssh_scp.c new file mode 100644 index 00000000..b31c6c65 --- /dev/null +++ b/examples/libssh_scp.c @@ -0,0 +1,220 @@ +/* libssh_scp.c + * Sample implementation of a SCP client + */ + +/* +Copyright 2009 Aris Adamantiadis + +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <libssh/libssh.h> +#include "examples_common.h" + +char *host; +char *user; +int sftp; + +static void usage(const char *argv0){ + fprintf(stderr,"Usage : %s [options] [login@]hostname\n" + "sample scp client - libssh-%s\n" + "Options :\n" + " -l user : log in as user\n" + " -p port : connect to port\n" + " -d : use DSS to verify host public key\n" + " -r : use RSA to verify host public key\n", + argv0, + ssh_version(0)); + exit(0); +} + +static int opts(int argc, char **argv){ + int i; + if(strstr(argv[0],"sftp")) + sftp=1; + // for(i=0;i<argc;i++) + // printf("%d : %s\n",i,argv[i]); + /* insert your own arguments here */ + while((i=getopt(argc,argv,""))!=-1){ + switch(i){ + default: + fprintf(stderr,"unknown option %c\n",optopt); + usage(argv[0]); + } + } + if(optind < argc) + host=argv[optind++]; + if(host==NULL) + usage(argv[0]); + return 0; +} + +ssh_channel chan; + +static void select_loop(SSH_SESSION *session,ssh_channel channel){ + fd_set fds; + struct timeval timeout; + char buffer[10]; + ssh_buffer readbuf=buffer_new(); + ssh_channel channels[2]; + int lus; + int eof=0; + int maxfd; + int ret; + while(channel){ + /* when a signal is caught, ssh_select will return + * with SSH_EINTR, which means it should be started + * again. It lets you handle the signal the faster you + * can, like in this window changed example. Of course, if + * your signal handler doesn't call libssh at all, you're + * free to handle signals directly in sighandler. + */ + do{ + FD_ZERO(&fds); + if(!eof) + FD_SET(0,&fds); + timeout.tv_sec=30; + timeout.tv_usec=0; + FD_SET(ssh_get_fd(session),&fds); + maxfd=ssh_get_fd(session)+1; + ret=select(maxfd,&fds,NULL,NULL,&timeout); + if(ret==EINTR) + continue; + if(FD_ISSET(0,&fds)){ + lus=read(0,buffer,10); + if(lus) + channel_write(channel,buffer,lus); + else { + eof=1; + channel_send_eof(channel); + } + } + if(FD_ISSET(ssh_get_fd(session),&fds)){ + ssh_set_fd_toread(session); + } + channels[0]=channel; // set the first channel we want to read from + channels[1]=NULL; + ret=channel_select(channels,NULL,NULL,NULL); // no specific timeout - just poll + } while (ret==EINTR || ret==SSH_EINTR); + + // we already looked for input from stdin. Now, we are looking for input from the channel + + if(channel && channel_is_closed(channel)){ + ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel)); + + channel_free(channel); + channel=NULL; + channels[0]=NULL; + } + if(channels[0]){ + while(channel && channel_is_open(channel) && channel_poll(channel,0)){ + lus=channel_read_buffer(channel,readbuf,0,0); + if(lus==-1){ + fprintf(stderr, "Error reading channel: %s\n", + ssh_get_error(session)); + return; + } + if(lus==0){ + ssh_log(session,SSH_LOG_RARE,"EOF received\n"); + ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel)); + + channel_free(channel); + channel=channels[0]=NULL; + } else + write(1,buffer_get(readbuf),lus); + } + while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */ + lus=channel_read_buffer(channel,readbuf,0,1); + if(lus==-1){ + fprintf(stderr, "Error reading channel: %s\n", + ssh_get_error(session)); + return; + } + if(lus==0){ + ssh_log(session,SSH_LOG_RARE,"EOF received\n"); + ssh_log(session,SSH_LOG_RARE,"exit-status : %d\n",channel_get_exit_status(channel)); + channel_free(channel); + channel=channels[0]=NULL; + } else + write(2,buffer_get(readbuf),lus); + } + } + if(channel && channel_is_closed(channel)){ + channel_free(channel); + channel=NULL; + } + } + buffer_free(readbuf); +} + +static void batch_shell(ssh_session session){ + ssh_channel channel; + char buffer[1024]; + channel=channel_new(session); + channel_open_session(channel); + if(channel_request_exec(channel,buffer)){ + printf("error executing \"%s\" : %s\n",buffer,ssh_get_error(session)); + return; + } + select_loop(session,channel); +} + +int main(int argc, char **argv){ + SSH_SESSION *session; + SSH_OPTIONS *options; + int auth=0; + + + options=ssh_options_new(); + if(ssh_options_getopt(options,&argc, argv)){ + fprintf(stderr,"error parsing command line :%s\n",ssh_get_error(options)); + usage(argv[0]); + } + opts(argc,argv); + if (user) { + if (ssh_options_set_username(options,user) < 0) { + ssh_options_free(options); + return 1; + } + } + + if (ssh_options_set_host(options,host) < 0) { + ssh_options_free(options); + return 1; + } + session=ssh_new(); + ssh_set_options(session,options); + if(ssh_connect(session)){ + fprintf(stderr,"Connection failed : %s\n",ssh_get_error(session)); + ssh_disconnect(session); + ssh_finalize(); + return 1; + } + if(verify_knownhost(session)<0){ + ssh_disconnect(session); + ssh_finalize(); + return 1; + } + auth=authenticate_console(session); + if(auth==SSH_AUTH_SUCCESS){ + batch_shell(session); + } else if(auth==SSH_AUTH_DENIED){ + fprintf(stderr,"Authentication failed\n"); + } else { + fprintf(stderr,"Error while authenticating : %s\n",ssh_get_error(session)); + } + ssh_disconnect(session); + ssh_finalize(); + + return 0; +} |