2009-09-06 15:26:02 +04:00
|
|
|
/* scp_download.c
|
|
|
|
* Sample implementation of a tiny SCP downloader 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 <sys/stat.h>
|
|
|
|
|
|
|
|
#include <libssh/libssh.h>
|
|
|
|
#include "examples_common.h"
|
|
|
|
|
|
|
|
int verbosity=0;
|
|
|
|
const char *createcommand="rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
|
|
|
|
char *host=NULL;
|
|
|
|
static void usage(const char *argv0){
|
|
|
|
fprintf(stderr,"Usage : %s [options] host\n"
|
|
|
|
"sample tiny scp downloader client - libssh-%s\n"
|
|
|
|
"This program will create files in /tmp and try to fetch them\n",
|
|
|
|
// "Options :\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;
|
|
|
|
while((i=getopt(argc,argv,"v"))!=-1){
|
|
|
|
switch(i){
|
|
|
|
case 'v':
|
|
|
|
verbosity++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fprintf(stderr,"unknown option %c\n",optopt);
|
|
|
|
usage(argv[0]);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
host = argv[optind];
|
|
|
|
if(host == NULL)
|
|
|
|
usage(argv[0]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void create_files(ssh_session session){
|
2010-05-14 02:51:08 +04:00
|
|
|
ssh_channel channel=ssh_channel_new(session);
|
2009-09-06 15:26:02 +04:00
|
|
|
char buffer[1];
|
|
|
|
if(channel == NULL){
|
|
|
|
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2010-05-14 02:51:08 +04:00
|
|
|
if(ssh_channel_open_session(channel) != SSH_OK){
|
2009-09-06 15:26:02 +04:00
|
|
|
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2010-05-14 02:51:08 +04:00
|
|
|
if(ssh_channel_request_exec(channel,createcommand) != SSH_OK){
|
2009-09-06 15:26:02 +04:00
|
|
|
fprintf(stderr,"Error executing command: %s\n",ssh_get_error(session));
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2010-05-14 02:51:08 +04:00
|
|
|
while(!ssh_channel_is_eof(channel)){
|
|
|
|
ssh_channel_read(channel,buffer,1,1);
|
2010-03-30 00:46:03 +04:00
|
|
|
if (write(1,buffer,1) < 0) {
|
|
|
|
fprintf(stderr, "Error writing to buffer\n");
|
|
|
|
return;
|
|
|
|
}
|
2009-09-06 15:26:02 +04:00
|
|
|
}
|
2010-05-14 02:51:08 +04:00
|
|
|
ssh_channel_close(channel);
|
|
|
|
ssh_channel_free(channel);
|
2009-09-06 15:26:02 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int fetch_files(ssh_session session){
|
|
|
|
int size;
|
|
|
|
char buffer[16384];
|
|
|
|
int mode;
|
|
|
|
char *filename;
|
|
|
|
int r;
|
2009-09-06 20:35:40 +04:00
|
|
|
ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*");
|
2009-09-06 15:26:02 +04:00
|
|
|
if(ssh_scp_init(scp) != SSH_OK){
|
|
|
|
fprintf(stderr,"error initializing scp: %s\n",ssh_get_error(session));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n");
|
|
|
|
do {
|
|
|
|
|
|
|
|
r=ssh_scp_pull_request(scp);
|
|
|
|
switch(r){
|
|
|
|
case SSH_SCP_REQUEST_NEWFILE:
|
|
|
|
size=ssh_scp_request_get_size(scp);
|
|
|
|
filename=strdup(ssh_scp_request_get_filename(scp));
|
|
|
|
mode=ssh_scp_request_get_permissions(scp);
|
|
|
|
printf("downloading file %s, size %d, perms 0%o\n",filename,size,mode);
|
|
|
|
free(filename);
|
|
|
|
ssh_scp_accept_request(scp);
|
|
|
|
r=ssh_scp_read(scp,buffer,sizeof(buffer));
|
|
|
|
if(r==SSH_ERROR){
|
|
|
|
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(session));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
printf("done\n");
|
|
|
|
break;
|
|
|
|
case SSH_ERROR:
|
|
|
|
fprintf(stderr,"Error: %s\n",ssh_get_error(session));
|
2009-09-06 20:43:23 +04:00
|
|
|
return -1;
|
|
|
|
case SSH_SCP_REQUEST_WARNING:
|
|
|
|
fprintf(stderr,"Warning: %s\n",ssh_scp_request_get_warning(scp));
|
2009-09-06 15:26:02 +04:00
|
|
|
break;
|
|
|
|
case SSH_SCP_REQUEST_NEWDIR:
|
|
|
|
filename=strdup(ssh_scp_request_get_filename(scp));
|
|
|
|
mode=ssh_scp_request_get_permissions(scp);
|
|
|
|
printf("downloading directory %s, perms 0%o\n",filename,mode);
|
|
|
|
free(filename);
|
|
|
|
ssh_scp_accept_request(scp);
|
|
|
|
break;
|
2009-09-06 20:35:40 +04:00
|
|
|
case SSH_SCP_REQUEST_ENDDIR:
|
|
|
|
printf("End of directory\n");
|
|
|
|
break;
|
2009-09-06 15:26:02 +04:00
|
|
|
case SSH_SCP_REQUEST_EOF:
|
|
|
|
printf("End of requests\n");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
} while (1);
|
|
|
|
end:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv){
|
|
|
|
ssh_session session;
|
|
|
|
if(opts(argc,argv)<0)
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
session=connect_ssh(host,NULL,verbosity);
|
|
|
|
if(session == NULL)
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
create_files(session);
|
|
|
|
fetch_files(session);
|
|
|
|
ssh_disconnect(session);
|
|
|
|
ssh_finalize();
|
|
|
|
return 0;
|
|
|
|
}
|