|
Packit Service |
31306d |
/* scp_download.c
|
|
Packit Service |
31306d |
* Sample implementation of a tiny SCP downloader client
|
|
Packit Service |
31306d |
*/
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
/*
|
|
Packit Service |
31306d |
Copyright 2009 Aris Adamantiadis
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
This file is part of the SSH Library
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
You are free to copy this file, modify it in any way, consider it being public
|
|
Packit Service |
31306d |
domain. This does not apply to the rest of the library though, but it is
|
|
Packit Service |
31306d |
allowed to cut-and-paste working code from this file to any license of
|
|
Packit Service |
31306d |
program.
|
|
Packit Service |
31306d |
*/
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
#include <stdio.h>
|
|
Packit Service |
31306d |
#include <stdlib.h>
|
|
Packit Service |
31306d |
#include <string.h>
|
|
Packit Service |
31306d |
#include <errno.h>
|
|
Packit Service |
31306d |
#include <sys/stat.h>
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
#include <libssh/libssh.h>
|
|
Packit Service |
31306d |
#include "examples_common.h"
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
static int verbosity = 0;
|
|
Packit Service |
31306d |
static const char *createcommand =
|
|
Packit Service |
31306d |
"rm -fr /tmp/libssh_tests && mkdir /tmp/libssh_tests && "
|
|
Packit Service |
31306d |
"cd /tmp/libssh_tests && date > a && date > b && mkdir c && date > d";
|
|
Packit Service |
31306d |
static char *host = NULL;
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
static void usage(const char *argv0){
|
|
Packit Service |
31306d |
fprintf(stderr,"Usage : %s [options] host\n"
|
|
Packit Service |
31306d |
"sample tiny scp downloader client - libssh-%s\n"
|
|
Packit Service |
31306d |
"This program will create files in /tmp and try to fetch them\n",
|
|
Packit Service |
31306d |
// "Options :\n",
|
|
Packit Service |
31306d |
// " -r : use RSA to verify host public key\n",
|
|
Packit Service |
31306d |
argv0,
|
|
Packit Service |
31306d |
ssh_version(0));
|
|
Packit Service |
31306d |
exit(0);
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
static int opts(int argc, char **argv){
|
|
Packit Service |
31306d |
int i;
|
|
Packit Service |
31306d |
while((i=getopt(argc,argv,"v"))!=-1){
|
|
Packit Service |
31306d |
switch(i){
|
|
Packit Service |
31306d |
case 'v':
|
|
Packit Service |
31306d |
verbosity++;
|
|
Packit Service |
31306d |
break;
|
|
Packit Service |
31306d |
default:
|
|
Packit Service |
31306d |
fprintf(stderr,"unknown option %c\n",optopt);
|
|
Packit Service |
31306d |
usage(argv[0]);
|
|
Packit Service |
31306d |
return -1;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
host = argv[optind];
|
|
Packit Service |
31306d |
if(host == NULL)
|
|
Packit Service |
31306d |
usage(argv[0]);
|
|
Packit Service |
31306d |
return 0;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
static void create_files(ssh_session session){
|
|
Packit Service |
31306d |
ssh_channel channel=ssh_channel_new(session);
|
|
Packit Service |
31306d |
char buffer[1];
|
|
Packit Service |
31306d |
int rc;
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
if(channel == NULL){
|
|
Packit Service |
31306d |
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
|
Packit Service |
31306d |
exit(EXIT_FAILURE);
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
if(ssh_channel_open_session(channel) != SSH_OK){
|
|
Packit Service |
31306d |
fprintf(stderr,"Error creating channel: %s\n",ssh_get_error(session));
|
|
Packit Service |
31306d |
ssh_channel_free(channel);
|
|
Packit Service |
31306d |
exit(EXIT_FAILURE);
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
if(ssh_channel_request_exec(channel,createcommand) != SSH_OK){
|
|
Packit Service |
31306d |
fprintf(stderr,"Error executing command: %s\n",ssh_get_error(session));
|
|
Packit Service |
31306d |
ssh_channel_close(channel);
|
|
Packit Service |
31306d |
ssh_channel_free(channel);
|
|
Packit Service |
31306d |
exit(EXIT_FAILURE);
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
while(!ssh_channel_is_eof(channel)){
|
|
Packit Service |
31306d |
rc = ssh_channel_read(channel,buffer,1,1);
|
|
Packit Service |
31306d |
if (rc != 1) {
|
|
Packit Service |
31306d |
fprintf(stderr, "Error reading from channel\n");
|
|
Packit Service |
31306d |
ssh_channel_close(channel);
|
|
Packit Service |
31306d |
ssh_channel_free(channel);
|
|
Packit Service |
31306d |
return;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
rc = write(1, buffer, 1);
|
|
Packit Service |
31306d |
if (rc < 0) {
|
|
Packit Service |
31306d |
fprintf(stderr, "Error writing to buffer\n");
|
|
Packit Service |
31306d |
ssh_channel_close(channel);
|
|
Packit Service |
31306d |
ssh_channel_free(channel);
|
|
Packit Service |
31306d |
return;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
ssh_channel_close(channel);
|
|
Packit Service |
31306d |
ssh_channel_free(channel);
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
static int fetch_files(ssh_session session){
|
|
Packit Service |
31306d |
int size;
|
|
Packit Service |
31306d |
char buffer[16384];
|
|
Packit Service |
31306d |
int mode;
|
|
Packit Service |
31306d |
char *filename;
|
|
Packit Service |
31306d |
int r;
|
|
Packit Service |
31306d |
ssh_scp scp=ssh_scp_new(session, SSH_SCP_READ | SSH_SCP_RECURSIVE, "/tmp/libssh_tests/*");
|
|
Packit Service |
31306d |
if(ssh_scp_init(scp) != SSH_OK){
|
|
Packit Service |
31306d |
fprintf(stderr,"error initializing scp: %s\n",ssh_get_error(session));
|
|
Packit Service |
31306d |
ssh_scp_free(scp);
|
|
Packit Service |
31306d |
return -1;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
printf("Trying to download 3 files (a,b,d) and 1 directory (c)\n");
|
|
Packit Service |
31306d |
do {
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
r=ssh_scp_pull_request(scp);
|
|
Packit Service |
31306d |
switch(r){
|
|
Packit Service |
31306d |
case SSH_SCP_REQUEST_NEWFILE:
|
|
Packit Service |
31306d |
size=ssh_scp_request_get_size(scp);
|
|
Packit Service |
31306d |
filename=strdup(ssh_scp_request_get_filename(scp));
|
|
Packit Service |
31306d |
mode=ssh_scp_request_get_permissions(scp);
|
|
Packit Service |
31306d |
printf("downloading file %s, size %d, perms 0%o\n",filename,size,mode);
|
|
Packit Service |
31306d |
free(filename);
|
|
Packit Service |
31306d |
ssh_scp_accept_request(scp);
|
|
Packit Service |
31306d |
r=ssh_scp_read(scp,buffer,sizeof(buffer));
|
|
Packit Service |
31306d |
if(r==SSH_ERROR){
|
|
Packit Service |
31306d |
fprintf(stderr,"Error reading scp: %s\n",ssh_get_error(session));
|
|
Packit Service |
31306d |
ssh_scp_close(scp);
|
|
Packit Service |
31306d |
ssh_scp_free(scp);
|
|
Packit Service |
31306d |
return -1;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
printf("done\n");
|
|
Packit Service |
31306d |
break;
|
|
Packit Service |
31306d |
case SSH_ERROR:
|
|
Packit Service |
31306d |
fprintf(stderr,"Error: %s\n",ssh_get_error(session));
|
|
Packit Service |
31306d |
ssh_scp_close(scp);
|
|
Packit Service |
31306d |
ssh_scp_free(scp);
|
|
Packit Service |
31306d |
return -1;
|
|
Packit Service |
31306d |
case SSH_SCP_REQUEST_WARNING:
|
|
Packit Service |
31306d |
fprintf(stderr,"Warning: %s\n",ssh_scp_request_get_warning(scp));
|
|
Packit Service |
31306d |
break;
|
|
Packit Service |
31306d |
case SSH_SCP_REQUEST_NEWDIR:
|
|
Packit Service |
31306d |
filename=strdup(ssh_scp_request_get_filename(scp));
|
|
Packit Service |
31306d |
mode=ssh_scp_request_get_permissions(scp);
|
|
Packit Service |
31306d |
printf("downloading directory %s, perms 0%o\n",filename,mode);
|
|
Packit Service |
31306d |
free(filename);
|
|
Packit Service |
31306d |
ssh_scp_accept_request(scp);
|
|
Packit Service |
31306d |
break;
|
|
Packit Service |
31306d |
case SSH_SCP_REQUEST_ENDDIR:
|
|
Packit Service |
31306d |
printf("End of directory\n");
|
|
Packit Service |
31306d |
break;
|
|
Packit Service |
31306d |
case SSH_SCP_REQUEST_EOF:
|
|
Packit Service |
31306d |
printf("End of requests\n");
|
|
Packit Service |
31306d |
goto end;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
} while (1);
|
|
Packit Service |
31306d |
end:
|
|
Packit Service |
31306d |
ssh_scp_close(scp);
|
|
Packit Service |
31306d |
ssh_scp_free(scp);
|
|
Packit Service |
31306d |
return 0;
|
|
Packit Service |
31306d |
}
|
|
Packit Service |
31306d |
|
|
Packit Service |
31306d |
int main(int argc, char **argv){
|
|
Packit Service |
31306d |
ssh_session session;
|
|
Packit Service |
31306d |
if(opts(argc,argv)<0)
|
|
Packit Service |
31306d |
return EXIT_FAILURE;
|
|
Packit Service |
31306d |
session=connect_ssh(host,NULL,verbosity);
|
|
Packit Service |
31306d |
if(session == NULL)
|
|
Packit Service |
31306d |
return EXIT_FAILURE;
|
|
Packit Service |
31306d |
create_files(session);
|
|
Packit Service |
31306d |
fetch_files(session);
|
|
Packit Service |
31306d |
ssh_disconnect(session);
|
|
Packit Service |
31306d |
ssh_free(session);
|
|
Packit Service |
31306d |
ssh_finalize();
|
|
Packit Service |
31306d |
return 0;
|
|
Packit Service |
31306d |
}
|