Blame examples/scp_download.c

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
}