Initial commit
This commit is contained in:
parent
f7b3598e0e
commit
9d995ee1cf
10 changed files with 848 additions and 2 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -16,8 +16,6 @@
|
|||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
|
|
27
LICENSE
27
LICENSE
|
@ -1,3 +1,5 @@
|
|||
LICENSE FOR THE RANGITAKI SYNC LIBRARY AND THE TEST FILES
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Marcel Kapfer
|
||||
|
@ -20,3 +22,28 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
LICENSE FOR ZED A. SHAW's AWESEOME DEBUGGING MACROS
|
||||
|
||||
Right know unknown. Will add it as soon as possible.
|
||||
|
||||
LICENSE FOR LIBSSH
|
||||
|
||||
COPYRIGHT (c) 2015 libssh
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
This 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.
|
||||
|
||||
This 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 this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
|
10
Makefile
Normal file
10
Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
CFLAGS=-g -Wall -DNDEBUG
|
||||
|
||||
all: rsl-download-test rsl-upload-test
|
||||
|
||||
rsl-download-test: rangitaki-sync.o libssh.so
|
||||
|
||||
rsl-upload-test: rangitaki-sync.o libssh.so
|
||||
|
||||
clean:
|
||||
rm -r rangitaki-sync.o rsl-download-test rsl-upload-test
|
52
README.md
Normal file
52
README.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# Rangitaki Sync Library
|
||||
|
||||
First of all: **I'm really sorry** for my bad code style, the bad design, all the ugliness , the missing comments (I will add them as soon as possible), for some things that may not work as expected, for every C developer who is used to read good code, for all the bugs that may happen. I'm sorry, but I'm not a good C developer. I just started coding in that language.
|
||||
|
||||
But, however, the funny part is: IT ACTUALLY WORKS! (or at least it should and did in my tests)
|
||||
|
||||
Anyway, this is a library written for synchronizing a Rangitaki blog with your device. (Actually you can download every directory recursive and upload single files...).
|
||||
|
||||
For testing purposes I wrote two test programs: One for uploading (single file), one for downloading (recursive, into /tmp).
|
||||
|
||||
*These library is written on Linux and tested on Linux. It may works on other systems, but I don't know.*
|
||||
|
||||
Even if I write all of my programs in the hope, that they will be useful for someone one day, I don't think that this will be used by anyone else than me. But look also in the 'Useful Stuff' section of this README.
|
||||
|
||||
## Test programs
|
||||
|
||||
After running `make` you have following programs:
|
||||
|
||||
### rsl-download-test
|
||||
|
||||
Just run it with `./rsl-download-test`. You don't need to give any arguments, since it will ask you everything.
|
||||
|
||||
This program will download you all files and subdirectory of the entered remote directory into `/tmp/rangitaki-sync`. Normally the program should create this directory, if it isn't already there. If it fails to create it and it isn't already there, you will receive a nice and friendly error message...
|
||||
|
||||
## rsl-upload-test
|
||||
|
||||
Just run it with `./rsl-upload-test`. You don't need to give any arguments, since it will ask you everything.
|
||||
|
||||
This program will upload a single file form the entered path to the entered path on your server.
|
||||
|
||||
## Credits
|
||||
|
||||
### libssh project ([libssh.org](http://libssh.org))
|
||||
|
||||
For there great ssh library and the awesome documentation.
|
||||
|
||||
## Zed A. Shaw ([zedshaw.com](http://zedshaw.com))
|
||||
|
||||
For his great book ["Learn C the hard way"](http://c.learncodethehardway.org/book/).
|
||||
|
||||
For his awesome debug macros (The `dbg.h` file).
|
||||
|
||||
## Useful Stuff
|
||||
|
||||
I wrote one function in this library which could be more useful for many people than the library: the **char \*getFilename(const char \*input)** function, which returns the filename of a path to a file.
|
||||
|
||||
E.g.
|
||||
|
||||
```
|
||||
char *path = "/var/www/html/index.html";
|
||||
printf("%s\n", getFilename(path)); // Will print 'index.html'
|
||||
```
|
42
dbg.h
Normal file
42
dbg.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This it NOT my work!!!
|
||||
*
|
||||
* All credit for these awesome macros goes to Zed A. Shaw
|
||||
*
|
||||
* http://zedshaw.com/
|
||||
*
|
||||
* Buy his book "Learn C the hard way" to support him and
|
||||
* to learn this awesome language
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __dgb_h__
|
||||
#define __dbg_h__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define debug(M, ...)
|
||||
#else
|
||||
#define debug(M, ...) fprintf(stderr, "DEBUG %s:%s:%d: " M "\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
|
||||
|
||||
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%s:%d: errno %s) " M "\n", __FILE__, __FUNCTION__, __LINE__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%s:%d: errno %s) " M "\n", __FILE__, __FUNCTION__, __LINE__, clean_errno(), ##__VA_ARGS__)
|
||||
|
||||
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%s:%d) " M "\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define check(A, M, ...) if(!(A)) {log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#define check_mem(A) check((A), "Out of memory.")
|
||||
|
||||
#define check_debug(A, M, ...) if(!(A)) { debug(M, ##__VA_ARGS__); errno=0; goto error; }
|
||||
|
||||
#endif
|
BIN
libssh.so
Normal file
BIN
libssh.so
Normal file
Binary file not shown.
347
rangitaki-sync.c
Normal file
347
rangitaki-sync.c
Normal file
|
@ -0,0 +1,347 @@
|
|||
/* Rangitaki Sync Library
|
||||
*
|
||||
* A program for downloading and uploading blog posts,
|
||||
* blogs file and media files from a rangitaki blog.
|
||||
*
|
||||
* Proudly written in C and with use of libssh (libssh.org)
|
||||
*
|
||||
* Version: 0.1
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* COPYRIGHT (c) 2015 The Rangitaki Project
|
||||
* COPYRIGHT (c) 2015 Marcel Kapfer (mmk2410) <marcelmichaelkapfer@yahoo.co.nz>
|
||||
*
|
||||
* License: MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include "rangitaki-sync.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dbg.h"
|
||||
|
||||
char * combine(const char * begin, char * end){
|
||||
char * result = malloc(strlen(begin) + strlen(end) + 1);
|
||||
strcpy(result, begin);
|
||||
strcat(result, end);
|
||||
return result;
|
||||
}
|
||||
|
||||
char * getFilename(char *input)
|
||||
{
|
||||
check(input != NULL, "Invalid input");
|
||||
char* string;
|
||||
|
||||
string = strdup(input);
|
||||
|
||||
int buffer[100];
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
for(i = 0; i <= strlen(string); i++) {
|
||||
if(string[i] == '/') {
|
||||
buffer[j] = i;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
j--;
|
||||
int size = strlen(string) - buffer[j]; // Includes the \0
|
||||
char *result = malloc(size);
|
||||
strcpy(result, &string[buffer[j]+1]);
|
||||
result[size] = '\0';
|
||||
free(string);
|
||||
return result;
|
||||
|
||||
error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ssh_initialize(const char *host, const char *user, const char *password,
|
||||
const char *remote_dir, const char *local_dir,
|
||||
const unsigned int port, ssh_data *data)
|
||||
{
|
||||
data->host = strdup(host);
|
||||
data->user = strdup(user);
|
||||
data->password = strdup(password);
|
||||
data->remote_dir = strdup(remote_dir);
|
||||
data->local_dir = strdup(local_dir);
|
||||
data->port = port;
|
||||
data->verbosity = SSH_LOG_PROTOCOL;
|
||||
}
|
||||
|
||||
int ssh_server_auth(ssh_session ssh)
|
||||
{
|
||||
char *hexa;
|
||||
int state;
|
||||
unsigned char *hash = NULL;
|
||||
size_t hlen;
|
||||
ssh_key srv_pubkey;
|
||||
int rc;
|
||||
|
||||
state = ssh_is_server_known(ssh);
|
||||
|
||||
rc = ssh_get_publickey(ssh, &srv_pubkey);
|
||||
check(rc >= 0, "Couldn't not authenticate the server.");
|
||||
|
||||
rc = ssh_get_publickey_hash(srv_pubkey,
|
||||
SSH_PUBLICKEY_HASH_SHA1,
|
||||
&hash,
|
||||
&hlen);
|
||||
ssh_key_free(srv_pubkey);
|
||||
check(rc >= 0, "Couldn't not authenticate the server.");
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SSH_SERVER_KNOWN_OK:
|
||||
log_info("Found host key");
|
||||
break;
|
||||
|
||||
case SSH_SERVER_KNOWN_CHANGED:
|
||||
log_err("The host key of the server changed. Aborting connection.");
|
||||
ssh_print_hexa("Public key hash", hash, hlen);
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
|
||||
case SSH_SERVER_FOUND_OTHER:
|
||||
log_err("The host key for this server was not found but an other. Aborting connection.");
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
|
||||
case SSH_SERVER_FILE_NOT_FOUND:
|
||||
log_warn("Couldn't find known hosts file.");
|
||||
|
||||
case SSH_SERVER_NOT_KNOWN:
|
||||
hexa = ssh_get_hexa(hash, hlen);
|
||||
log_info("Adding %s to known hosts.", hexa);
|
||||
free(hexa);
|
||||
if (ssh_write_knownhost(ssh) < 0) {
|
||||
log_err("Error adding server to known hosts file: %s", strerror(errno));
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log_err("%s", ssh_get_error(ssh));
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
ssh_clean_pubkey_hash(&hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_session ssh_open(ssh_data *data)
|
||||
{
|
||||
int rc = 0;
|
||||
ssh_session ssh = ssh_new();
|
||||
|
||||
if(ssh == NULL) {
|
||||
log_err("Failed th create ssh session.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssh_options_set(ssh, SSH_OPTIONS_HOST, data->host) < 0) {
|
||||
ssh_free(ssh);
|
||||
log_err("Failed to set host.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssh_options_set(ssh, SSH_OPTIONS_USER, data->user) < 0) {
|
||||
ssh_free(ssh);
|
||||
log_err("Failed to set user.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssh_options_set(ssh, SSH_OPTIONS_PORT, &data->port)) {
|
||||
ssh_free(ssh);
|
||||
log_err("Failed to set port.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssh_options_set(ssh, SSH_OPTIONS_LOG_VERBOSITY, &data->verbosity)) {
|
||||
ssh_free(ssh);
|
||||
log_err("Failed to set verbosity.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssh_connect(ssh)) {
|
||||
log_err("Connection failed: %s.", ssh_get_error(ssh));
|
||||
ssh_disconnect(ssh);
|
||||
ssh_free(ssh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ssh_server_auth < 0) {
|
||||
log_err("Couldn't authenticate the server.");
|
||||
ssh_disconnect(ssh);
|
||||
ssh_free(ssh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = ssh_userauth_password(ssh, data->user, data->password);
|
||||
if(rc == SSH_AUTH_SUCCESS) {
|
||||
return ssh;
|
||||
} else if(rc == SSH_AUTH_DENIED) {
|
||||
log_err("Authentication failed.");
|
||||
} else {
|
||||
log_err("Error while authenticating");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
int ssh_close(ssh_session ssh)
|
||||
{
|
||||
ssh_disconnect(ssh);
|
||||
ssh_free(ssh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssh_scp scp_open(ssh_session ssh, ssh_data *data, int mode)
|
||||
{
|
||||
int rc = 0;
|
||||
ssh_scp scp = ssh_scp_new(ssh, mode, data->remote_dir);
|
||||
check(scp != NULL, "Failed to create the scp session: %s", ssh_get_error(ssh));
|
||||
|
||||
rc = ssh_scp_init(scp);
|
||||
if(rc == -1)
|
||||
{
|
||||
log_err("Failed to initialize the scp connection.");
|
||||
goto error;
|
||||
}
|
||||
check(rc == SSH_OK, "Failed to initialize the scp session: %s", ssh_get_error(ssh));
|
||||
|
||||
return scp;
|
||||
|
||||
error:
|
||||
if(scp) ssh_scp_free(scp);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
int scp_close(ssh_scp scp)
|
||||
{
|
||||
ssh_scp_close(scp);
|
||||
ssh_scp_free(scp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int scp_download(ssh_session ssh, ssh_scp scp, ssh_data *data)
|
||||
{
|
||||
int rc;
|
||||
int rv;
|
||||
int size, mode;
|
||||
char buffer[16384];
|
||||
const char *local_dir = strdup(data->local_dir);
|
||||
|
||||
do {
|
||||
rc = ssh_scp_pull_request(scp);
|
||||
|
||||
switch (rc) {
|
||||
case SSH_SCP_REQUEST_NEWFILE:
|
||||
size = ssh_scp_request_get_size(scp);
|
||||
mode = ssh_scp_request_get_permissions(scp);
|
||||
char *filename = strdup(ssh_scp_request_get_filename(scp));
|
||||
check(filename != NULL, "Couldn't get the filename.");
|
||||
printf("DOWNLOAD: %s %d %d\n", filename, size, mode);
|
||||
char *dir = combine(local_dir, filename);
|
||||
FILE *output = fopen(dir, "w+");
|
||||
check(output != NULL, "FILE couldn't be created");
|
||||
ssh_scp_accept_request(scp);
|
||||
rc = ssh_scp_read(scp, buffer, sizeof(buffer));
|
||||
check(rc != SSH_ERROR, "Error downloading the file. %s",
|
||||
ssh_get_error(ssh));
|
||||
rv = fwrite(buffer, size, 1, output);
|
||||
check(rv != 0, "Failed to write file");
|
||||
rv = fclose(output);
|
||||
free(dir);
|
||||
free(filename);
|
||||
check(rv == 0, "Failed to close FILE");
|
||||
printf("Done.\n");
|
||||
break;
|
||||
|
||||
case SSH_ERROR:
|
||||
log_err("Error: %s", ssh_get_error(ssh));
|
||||
goto error;
|
||||
|
||||
case SSH_SCP_REQUEST_WARNING:
|
||||
log_warn("Warning: %s", ssh_scp_request_get_warning(scp));
|
||||
break;
|
||||
|
||||
case SSH_SCP_REQUEST_NEWDIR:
|
||||
filename = strdup(ssh_scp_request_get_filename(scp));
|
||||
mode = ssh_scp_request_get_permissions(scp);
|
||||
printf("DOWNLOAD: %s %d\n", filename, mode);
|
||||
ssh_scp_accept_request(scp);
|
||||
break;
|
||||
|
||||
case SSH_SCP_REQUEST_ENDDIR:
|
||||
break;
|
||||
|
||||
case SSH_SCP_REQUEST_EOF:
|
||||
log_info("DONE");
|
||||
return 0;
|
||||
|
||||
}
|
||||
} while (1);
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int scp_upload(ssh_session ssh, ssh_scp scp, ssh_data *data)
|
||||
{
|
||||
int rc = 0;
|
||||
FILE *fisz = fopen(data->local_dir, "rb");
|
||||
fseek(fisz, 0L, SEEK_END);
|
||||
int size = ftell(fisz);
|
||||
fclose(fisz);
|
||||
|
||||
rc = ssh_scp_push_file64(scp, getFilename(data->local_dir), size,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
|
||||
check(rc == SSH_OK, "Failed to create file: %s", ssh_get_error(ssh));
|
||||
|
||||
char *buffer = malloc(size + 100);
|
||||
FILE *file = fopen(data->local_dir, "r");
|
||||
check(file != NULL, "Error opening local file.");
|
||||
rc = 0;
|
||||
rc = fread(buffer, size, 1, file);
|
||||
rc = ssh_scp_write(scp, buffer, size);
|
||||
check(rc == SSH_OK, "Error while writing remote file: %s", ssh_get_error(ssh));
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
64
rangitaki-sync.h
Normal file
64
rangitaki-sync.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Rangitaki Sync Library
|
||||
*
|
||||
* A program for downloading and uploading blog posts,
|
||||
* blogs file and media files from a rangitaki blog.
|
||||
*
|
||||
* Proudly written in C and with use of libssh (libssh.org)
|
||||
*
|
||||
* Version: 0.1
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* COPYRIGHT (c) 2015 The Rangitaki Project
|
||||
* COPYRIGHT (c) 2015 Marcel Kapfer (mmk2410) <marcelmichaelkapfer@yahoo.co.nz>
|
||||
*
|
||||
* License: MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _rangitakisync_h
|
||||
#define _rangitakisync_h
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
|
||||
typedef struct{
|
||||
char *host;
|
||||
char *user;
|
||||
char *password;
|
||||
char *remote_dir;
|
||||
char *local_dir;
|
||||
unsigned int port;
|
||||
unsigned int verbosity;
|
||||
} ssh_data;
|
||||
|
||||
|
||||
void ssh_initialize(const char *host, const char *user, const char *password,
|
||||
const char *remote_dir, const char *local_dir,
|
||||
const unsigned int port, ssh_data *data);
|
||||
ssh_session ssh_open(ssh_data *data);
|
||||
int ssh_close(ssh_session ssh);
|
||||
ssh_scp scp_open(ssh_session ssh, ssh_data *data, int mode);
|
||||
int scp_close(ssh_scp scp);
|
||||
int scp_download(ssh_session ssh, ssh_scp scp, ssh_data *data);
|
||||
int scp_upload(ssh_session ssh, ssh_scp scp, ssh_data *data);
|
||||
|
||||
#endif
|
149
rsl-download-test.c
Normal file
149
rsl-download-test.c
Normal file
|
@ -0,0 +1,149 @@
|
|||
/* Rangitaki Sync Library
|
||||
*
|
||||
* Download Test
|
||||
*
|
||||
* A program for downloading and uploading blog posts,
|
||||
* blogs file and media files from a rangitaki blog.
|
||||
*
|
||||
* Proudly written in C and with use of libssh (libssh.org)
|
||||
*
|
||||
* Version: 0.1
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* COPYRIGHT (c) 2015 The Rangitaki Project
|
||||
* COPYRIGHT (c) 2015 Marcel Kapfer (mmk2410) <marcelmichaelkapfer@yahoo.co.nz>
|
||||
*
|
||||
* License: MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include "rangitaki-sync.h"
|
||||
#include "dbg.h"
|
||||
|
||||
#define MAX_DATA 512
|
||||
|
||||
int run(const char *host, const char *user, const char *password, const char *remote_dir, const int port)
|
||||
{
|
||||
// Print the ssh struct
|
||||
ssh_data *data = malloc(sizeof(ssh_data));
|
||||
ssh_session ssh;
|
||||
ssh_scp scp;
|
||||
int rc;
|
||||
|
||||
ssh_initialize(host, user, password,
|
||||
remote_dir, "/tmp/rangitaki-sync/", port, data);
|
||||
|
||||
mkdir(data->local_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
|
||||
ssh = ssh_open(data);
|
||||
check(ssh != NULL, "Error while connecting to the server.");
|
||||
|
||||
scp = scp_open(ssh, data, SSH_SCP_READ | SSH_SCP_RECURSIVE);
|
||||
check(scp != NULL, "Error while creating a scp connection");
|
||||
|
||||
rc = scp_download(ssh, scp, data);
|
||||
check(rc == 0, "Error while downloading");
|
||||
|
||||
|
||||
scp_close(scp);
|
||||
|
||||
ssh_close(ssh);
|
||||
|
||||
free(data->host);
|
||||
free(data->user);
|
||||
free(data->password);
|
||||
free(data->remote_dir);
|
||||
free(data->local_dir);
|
||||
free(data);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(scp) scp_close(scp);
|
||||
if(ssh) ssh_close(ssh);
|
||||
|
||||
free(data->host);
|
||||
free(data->user);
|
||||
free(data->password);
|
||||
free(data->remote_dir);
|
||||
free(data->local_dir);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
check(argc == 1, "Too much arguments");
|
||||
|
||||
printf("RANGITAKI SYNC LIBRARY\n");
|
||||
printf("Version: 0.1\n");
|
||||
printf("COPYRIGHT (c) 2015 The Rangitaki Project\n");
|
||||
printf("COPYRIGHT (c) 2015 Marcel Kapfer (mmk2410) <marcelmichaelkapfer@yahoo.co.nz>\n");
|
||||
printf("MIT License\n\n");
|
||||
printf("RSL Download test\n\n");
|
||||
|
||||
char *in = NULL;
|
||||
int rc = 0;
|
||||
char host[MAX_DATA];
|
||||
char user[MAX_DATA];
|
||||
char password[MAX_DATA];
|
||||
char remote_dir[MAX_DATA];
|
||||
int port;
|
||||
|
||||
printf("Host: ");
|
||||
in = fgets(host, MAX_DATA - 1, stdin);
|
||||
strtok(host, "\n");
|
||||
check(in != NULL, "Failed to read host.");
|
||||
|
||||
printf("User: ");
|
||||
in = fgets(user, MAX_DATA - 1, stdin);
|
||||
strtok(user, "\n");
|
||||
check(in != NULL, "Failed to read host.");
|
||||
|
||||
printf("Password: ");
|
||||
in = fgets(password, MAX_DATA - 1, stdin);
|
||||
strtok(password, "\n");
|
||||
check(in != NULL, "Failed to read password.");
|
||||
|
||||
printf("Remote Directory: ");
|
||||
in = fgets(remote_dir, MAX_DATA - 1, stdin);
|
||||
strtok(remote_dir, "\n");
|
||||
check(in != NULL, "Failed to read directory.");
|
||||
|
||||
printf("Port: ");
|
||||
rc = fscanf(stdin, "%i", &port);
|
||||
check(rc > 0, "Failed to read port.");
|
||||
|
||||
printf("\nRunning Download now.\n\n");
|
||||
|
||||
run(host, user, password, remote_dir, port);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
157
rsl-upload-test.c
Normal file
157
rsl-upload-test.c
Normal file
|
@ -0,0 +1,157 @@
|
|||
/* Rangitaki Sync Library
|
||||
*
|
||||
* Upload Test
|
||||
*
|
||||
* A program for downloading and uploading blog posts,
|
||||
* blogs file and media files from a rangitaki blog.
|
||||
*
|
||||
* Proudly written in C and with use of libssh (libssh.org)
|
||||
*
|
||||
* Version: 0.1
|
||||
*
|
||||
* Authors:
|
||||
*
|
||||
* COPYRIGHT (c) 2015 The Rangitaki Project
|
||||
* COPYRIGHT (c) 2015 Marcel Kapfer (mmk2410) <marcelmichaelkapfer@yahoo.co.nz>
|
||||
*
|
||||
* License: MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <libssh/libssh.h>
|
||||
#include "rangitaki-sync.h"
|
||||
#include "dbg.h"
|
||||
|
||||
#define MAX_DATA 512
|
||||
|
||||
int run(const char *host, const char *user, const char *password, const char *remote_dir,
|
||||
const char *local_dir, const int port)
|
||||
{
|
||||
// Print the ssh struct
|
||||
ssh_data *data = malloc(sizeof(ssh_data));
|
||||
ssh_session ssh;
|
||||
ssh_scp scp;
|
||||
int rc;
|
||||
|
||||
ssh_initialize(host, user, password,
|
||||
remote_dir, local_dir, port, data);
|
||||
|
||||
mkdir(data->local_dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
|
||||
|
||||
ssh = ssh_open(data);
|
||||
check(ssh != NULL, "Error while connecting to the server.");
|
||||
|
||||
scp = scp_open(ssh, data, SSH_SCP_WRITE);
|
||||
check(scp != NULL, "Error while creating a scp connection");
|
||||
|
||||
rc = scp_upload(ssh, scp, data);
|
||||
check(rc == 0, "Error while uploading");
|
||||
|
||||
|
||||
scp_close(scp);
|
||||
|
||||
ssh_close(ssh);
|
||||
|
||||
free(data->host);
|
||||
free(data->user);
|
||||
free(data->password);
|
||||
free(data->remote_dir);
|
||||
free(data->local_dir);
|
||||
free(data);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if(scp) scp_close(scp);
|
||||
if(ssh) ssh_close(ssh);
|
||||
|
||||
free(data->host);
|
||||
free(data->user);
|
||||
free(data->password);
|
||||
free(data->remote_dir);
|
||||
free(data->local_dir);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
check(argc == 1, "Too much arguments");
|
||||
|
||||
printf("RANGITAKI SYNC LIBRARY\n");
|
||||
printf("Version: 0.1\n");
|
||||
printf("COPYRIGHT (c) 2015 The Rangitaki Project\n");
|
||||
printf("COPYRIGHT (c) 2015 Marcel Kapfer (mmk2410) <marcelmichaelkapfer@yahoo.co.nz>\n");
|
||||
printf("MIT License\n\n");
|
||||
printf("RSL Download test\n\n");
|
||||
|
||||
char *in = NULL;
|
||||
int rc = 0;
|
||||
char host[MAX_DATA];
|
||||
char user[MAX_DATA];
|
||||
char password[MAX_DATA];
|
||||
char remote_dir[MAX_DATA];
|
||||
char local_dir[MAX_DATA];
|
||||
int port;
|
||||
|
||||
printf("Host: ");
|
||||
in = fgets(host, MAX_DATA - 1, stdin);
|
||||
strtok(host, "\n");
|
||||
check(in != NULL, "Failed to read host.");
|
||||
|
||||
printf("User: ");
|
||||
in = fgets(user, MAX_DATA - 1, stdin);
|
||||
strtok(user, "\n");
|
||||
check(in != NULL, "Failed to read host.");
|
||||
|
||||
printf("Password: ");
|
||||
in = fgets(password, MAX_DATA - 1, stdin);
|
||||
strtok(password, "\n");
|
||||
check(in != NULL, "Failed to read password.");
|
||||
|
||||
printf("Remote Directory: ");
|
||||
in = fgets(remote_dir, MAX_DATA - 1, stdin);
|
||||
strtok(remote_dir, "\n");
|
||||
check(in != NULL, "Failed to read directory.");
|
||||
|
||||
printf("Local File: ");
|
||||
in = fgets(local_dir, MAX_DATA - 1, stdin);
|
||||
strtok(local_dir, "\n");
|
||||
check(in != NULL, "Failed to read file");
|
||||
|
||||
printf("Port: ");
|
||||
rc = fscanf(stdin, "%i", &port);
|
||||
check(rc > 0, "Failed to read port.");
|
||||
|
||||
printf("\nRunning Upload now.\n\n");
|
||||
|
||||
run(host, user, password, remote_dir, local_dir, port);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
Reference in a new issue