Replace cfile.c with connection.c

- cfile.h needed too many function calls and was too complex
 - connection.h does
     - only download in binary mode (json can handle that)
     - have no excess of getters and setters
     - allow to execute the whole request in a single function call
     - allow to be re-used for multiple requests
 - as a result, the code has 600 lines of code less
 - originally, connection.h was developed to use a global curl
   handle for all requests such that the same connection could be
   re-used. Unfortunately the MediaFire servers will close the
   connection after each request from their end:

      Bryan: "Unfortunately, we won't ever do keep-alive.  Closing the
      connection is a small part of a larger set of heuristics we have in
      place to prevent DOS/DDOS attacks."

   This causes massive performance impacts and those grow even larger when
   using SSL because the handshake has to be executed for every single
   request again.
This commit is contained in:
josch
2014-09-17 11:20:23 +02:00
parent fe42b6e668
commit ebedf596db
20 changed files with 346 additions and 974 deletions

View File

@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.8)
project(mediafire-tools)
set(mf-sources account.c cfile.c cmd_auth.c cmd_chdir.c cmd_debug.c cmd_file.c cmd_get.c cmd_help.c cmd_host.c cmd_lcd.c cmd_links.c cmd_list.c cmd_lpwd.c cmd_mkdir.c cmd_pwd.c cmd_whoami.c console.c download.c file.c file_info.c file_links.c folder.c folder_create.c folder_info.c json.c keys.c list.c mfshell.c signals.c signature.c strings.c stringv.c user_session.c)
set(mf-headers account.h cfile.h chdir.h command.h console.h download.h file_info.h file_links.h folder_create.h folder_info.h json.h list.h macros.h mfshell.h private.h signals.h strings.h stringv.h user_session.h)
set(mf-sources account.c cmd_auth.c cmd_chdir.c cmd_debug.c cmd_file.c cmd_get.c cmd_help.c cmd_host.c cmd_lcd.c cmd_links.c cmd_list.c cmd_lpwd.c cmd_mkdir.c cmd_pwd.c cmd_whoami.c connection.c console.c download.c file.c file_info.c file_links.c folder.c folder_create.c folder_info.c json.c keys.c list.c mfshell.c signals.c signature.c strings.c stringv.c user_session.c)
set(mf-headers account.h chdir.h command.h connection.h console.h download.h file_info.h file_links.h folder_create.h folder_info.h json.h list.h macros.h mfshell.h private.h signals.h strings.h stringv.h user_session.h)
add_library(mf-obj OBJECT ${mf-sources} ${mf-headers})

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -27,17 +28,16 @@
#include "mfshell.h"
#include "private.h"
#include "account.h"
#include "cfile.h"
#include "strings.h"
#include "json.h"
#include "connection.h"
static int
_decode_user_get_info(mfshell_t *mfshell,cfile_t *cfile);
_decode_user_get_info(conn_t *conn, void *data);
int
_user_get_info(mfshell_t *mfshell)
{
cfile_t *cfile;
char *api_call;
int retval;
// char *rx_buffer;
@@ -45,33 +45,20 @@ _user_get_info(mfshell_t *mfshell)
if(mfshell == NULL) return -1;
if(mfshell->user_signature == NULL) return -1;
// create the object as a sender
cfile = cfile_create();
// take the traditional defaults
cfile_set_defaults(cfile);
api_call = mfshell->create_signed_get(mfshell,0,"user/get_info.php",
"?session_token=%s"
"&response_format=json",
mfshell->session_token);
cfile_set_url(cfile,api_call);
retval = cfile_exec(cfile);
// print an error code if something went wrong
if(retval != CURLE_OK) printf("error %d\n\r",retval);
retval = _decode_user_get_info(mfshell,cfile);
cfile_destroy(cfile);
conn_t* conn = conn_create();
retval = conn_get_buf(conn, api_call, _decode_user_get_info, NULL);
conn_destroy(conn);
return retval;
}
static int
_decode_user_get_info(mfshell_t *mfshell,cfile_t *cfile)
_decode_user_get_info(conn_t *conn, void *data)
{
json_error_t error;
json_t *root;
@@ -80,10 +67,7 @@ _decode_user_get_info(mfshell_t *mfshell,cfile_t *cfile)
json_t *first_name;
json_t *last_name;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
node = json_object_by_path(root,"response/user_info");

620
cfile.c
View File

@@ -1,620 +0,0 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
* the Free Software Foundation.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <curl/curl.h>
#include "cfile.h"
#include "strings.h"
struct _cfile_s
{
CURL *curl_handle;
char *url;
int mode;
uint32_t opts;
char *get_args;
char *post_args;
size_t (*curl_rx_io) (char *,size_t,size_t,void *);
size_t (*curl_tx_io) (char *,size_t,size_t,void *);
void (*user_io) (cfile_t *);
void *userptr;
void (*progress) (cfile_t *);
char *rx_buffer;
ssize_t rx_buffer_sz;
char *tx_buffer;
ssize_t tx_buffer_sz;
double rx_length;
double rx_count;
double tx_length;
double tx_count;
};
/*
according to libcurl doc the payload of these two callbacks (data)
is size * nmemb which is logistically similar to calloc().
*/
/*
static size_t
curl_send_callback(char *data,size_t size,size_t nmemb,void *user_ptr);
*/
static size_t
_cfile_rx_callback(char *data,size_t size,size_t nmemb,void *user_ptr);
static size_t
_cfile_tx_callback(char *data,size_t size,size_t nmemb,void *user_ptr);
static int
_cfile_progress_callback(void *user_ptr,double dltotal,double dlnow,
double ultotal,double ulnow);
cfile_t*
cfile_create(void)
{
cfile_t *cfile;
CURL *curl_handle;
curl_handle = curl_easy_init();
if(curl_handle == NULL) return NULL;
cfile = (cfile_t*)calloc(1,sizeof(cfile_t));
cfile->curl_handle = curl_handle;
cfile->curl_tx_io = &_cfile_tx_callback;
curl_easy_setopt(cfile->curl_handle,
CURLOPT_READFUNCTION,cfile->curl_tx_io);
curl_easy_setopt(cfile->curl_handle,
CURLOPT_READDATA,(void*)cfile);
cfile->curl_rx_io = &_cfile_rx_callback;
curl_easy_setopt(cfile->curl_handle,
CURLOPT_WRITEFUNCTION,cfile->curl_rx_io);
curl_easy_setopt(cfile->curl_handle,
CURLOPT_WRITEDATA,(void*)cfile);
// enable progress reporting
curl_easy_setopt(cfile->curl_handle,
CURLOPT_NOPROGRESS,0);
curl_easy_setopt(cfile->curl_handle,
CURLOPT_PROGRESSFUNCTION,_cfile_progress_callback);
curl_easy_setopt(cfile->curl_handle,
CURLOPT_PROGRESSDATA,(void*)cfile);
return cfile;
}
int
cfile_exec(cfile_t *cfile)
{
char *url = NULL;
size_t len;
int retval;
if(cfile == NULL) return -1;
if(cfile->curl_handle == NULL) return -1;
// use an appended URL if GET arguments are supplied
if(cfile->get_args != NULL)
{
len = strlen(cfile->get_args) + strlen(cfile->url) + 1;
url = (char*)calloc(1,len);
strcpy(url,cfile->url);
strcat(url,cfile->get_args);
curl_easy_setopt(cfile->curl_handle,CURLOPT_URL,url);
}
// has the user supplied POST arguments?
if(cfile->post_args != NULL)
{
curl_easy_setopt(cfile->curl_handle,CURLOPT_POSTFIELDS,
cfile->post_args);
}
retval = curl_easy_perform(cfile->curl_handle);
// restore the URL to the cURL handle if it was modified
if(url != NULL)
{
curl_easy_setopt(cfile->curl_handle,CURLOPT_URL,cfile->url);
free(url);
url = NULL;
}
/*
if the user specified CFILE_MODE_TEXT, ensure that the buffer is
NULL terminated.
*/
if(cfile->mode == CFILE_MODE_TEXT)
{
if(cfile->rx_buffer[cfile->rx_buffer_sz - 1] != '\0')
{
cfile->rx_buffer = (char*)realloc(cfile->rx_buffer,
cfile->rx_buffer_sz + 1);
cfile->rx_buffer_sz++;
cfile->rx_buffer[cfile->rx_buffer_sz - 1] = '\0';
}
}
return retval;
}
void
cfile_destroy(cfile_t *cfile)
{
if(cfile == NULL) return;
if(cfile->url != NULL) free(cfile->url);
if(cfile->get_args != NULL) free(cfile->get_args);
if(cfile->post_args != NULL) free(cfile->post_args);
if(cfile->rx_buffer != NULL) free(cfile->rx_buffer);
if(cfile->tx_buffer != NULL) free(cfile->tx_buffer);
if(cfile->curl_handle != NULL)
{
curl_easy_cleanup(cfile->curl_handle);
}
free(cfile);
}
void
cfile_set_mode(cfile_t *cfile,int mode)
{
if(cfile == NULL) return;
if(mode <= 0) return;
/*
CFILE_MODE_TEXT ensure that the final buffer contents is NULL
terminated.
CFILE_MODE_BINARY does not modify the contents of the final
buffer at all.
*/
cfile->mode = mode;
return;
}
void
cfile_set_defaults(cfile_t *cfile)
{
if(cfile == NULL) return;
cfile->mode = CFILE_MODE_TEXT;
// if the protocol supports following redirects, do so
cfile_set_opts(cfile,CFILE_OPT_FOLLOW_REDIRECTS);
// enable SSL engine
cfile_set_opts(cfile,CFILE_OPT_ENABLE_SSL);
return;
}
void
cfile_set_url(cfile_t *cfile,const char *url)
{
if(cfile == NULL) return;
if(url == NULL) return;
// make sure curl handle was successfully instantiated
if(cfile->curl_handle == NULL) return;
// reject the request if a source already exists
if(cfile->url != NULL) return;
// escape the url
// cfile->url = curl_easy_escape(cfile->url,url,0);
cfile->url = strdup(url);
curl_easy_setopt(cfile->curl_handle,CURLOPT_URL,cfile->url);
return;
}
int
cfile_get_url(cfile_t *cfile,char *buf,size_t buf_sz)
{
if(cfile == NULL) return -1;
if(cfile->url == NULL) return -1;
if(buf == NULL) return -1;
if(buf_sz <=1 ) return -1;
strncpy(buf,cfile->url,buf_sz-1);
return 0;
}
void
cfile_set_args(cfile_t *cfile,int type,const char *args)
{
int len;
if(cfile == NULL) return;
if(args == NULL) return;
if(cfile->curl_handle == NULL) return;
len = strlen(args);
if(len == 0) return;
if(type == CFILE_ARGS_POST)
{
cfile->post_args = (char*)realloc(cfile->post_args,len + 1);
strcpy(cfile->post_args,args);
return;
}
if(type == CFILE_ARGS_GET)
{
cfile->get_args = (char*)realloc(cfile->get_args,len + 1);
strcpy(cfile->get_args,args);
return;
}
// todo: handle custome headers
return;
}
void
cfile_add_args(cfile_t *cfile,int type,const char *args)
{
char *new_args;
if(cfile == NULL) return;
if(type == CFILE_ARGS_POST)
{
if(cfile->post_args == NULL)
{
cfile_set_args(cfile,CFILE_ARGS_POST,args);
return;
}
new_args = strdup_printf("%s%s",cfile->post_args,(char*)args);
free(cfile->post_args);
cfile->post_args = new_args;
return;
}
if(type == CFILE_ARGS_GET)
{
if(cfile->get_args == NULL)
{
cfile_set_args(cfile,CFILE_ARGS_GET,args);
return;
}
new_args = strdup_printf("%s%s",cfile->get_args,(char*)args);
free(cfile->get_args);
cfile->get_args = new_args;
return;
}
return;
}
int
cfile_set_opts(cfile_t *cfile,uint32_t opts)
{
if(cfile == NULL) return -1;
if(cfile->curl_handle == NULL) return -1;
cfile->opts = opts;
if(cfile->opts & CFILE_OPT_FOLLOW_REDIRECTS)
{
curl_easy_setopt(cfile->curl_handle,CURLOPT_FOLLOWLOCATION,1);
}
else
{
curl_easy_setopt(cfile->curl_handle,CURLOPT_FOLLOWLOCATION,0);
}
if(cfile->opts & CFILE_OPT_ENABLE_SSL)
{
curl_easy_setopt(cfile->curl_handle,CURLOPT_SSLENGINE,NULL);
curl_easy_setopt(cfile->curl_handle,CURLOPT_SSLENGINE_DEFAULT,1L);
// libcurl will use built-in CA certificate if none specified
//curl_easy_setopt(cfile->curl_handle,CURLOPT_SSLCERTTYPE,"PEM");
//curl_easy_setopt(cfile->curl_handle,CURLOPT_CAINFO,"cacert.pem");
}
if(cfile->opts & CFILE_OPT_ENABLE_SSL_LAX)
{
curl_easy_setopt(cfile->curl_handle,CURLOPT_SSL_VERIFYPEER,0);
}
return 0;
}
void
cfile_set_io_func(cfile_t *cfile,CFileFunc user_io)
{
if(cfile == NULL) return;
cfile->user_io = user_io;
return;
}
void
cfile_set_progress_func(cfile_t *cfile,CFileFunc progress)
{
if(cfile == NULL) return;
cfile->progress = progress;
return;
}
const char*
cfile_get_rx_buffer(cfile_t *cfile)
{
if(cfile == NULL) return NULL;
if(cfile->curl_handle == NULL) return NULL;
return cfile->rx_buffer;
}
size_t
cfile_get_rx_buffer_size(cfile_t *cfile)
{
if(cfile == NULL) return 0;
return cfile->rx_buffer_sz;
}
const char*
cfile_get_tx_buffer(cfile_t *cfile)
{
if(cfile == NULL) return NULL;
if(cfile->curl_handle == NULL) return NULL;
return cfile->tx_buffer;
}
size_t
cfile_get_tx_buffer_size(cfile_t *cfile)
{
if(cfile == NULL) return 0;
return cfile->tx_buffer_sz;
}
void
cfile_reset_rx_buffer(cfile_t *cfile)
{
if(cfile == NULL) return;
if(cfile->rx_buffer != NULL)
{
free(cfile->rx_buffer);
cfile->rx_buffer = NULL;
}
cfile->rx_buffer_sz = 0;
return;
}
void
cfile_reset_tx_buffer(cfile_t *cfile)
{
if(cfile == NULL) return;
if(cfile->tx_buffer != NULL)
{
free(cfile->tx_buffer);
cfile->tx_buffer = NULL;
}
cfile->tx_buffer_sz = 0;
return;
}
double
cfile_get_rx_count(cfile_t *cfile)
{
if(cfile == NULL) return 0;
if(cfile->curl_handle == NULL) return 0;
return cfile->rx_count;
}
double
cfile_get_rx_length(cfile_t *cfile)
{
if(cfile == NULL) return 0;
if(cfile->curl_handle == NULL) return 0;
return cfile->rx_length;
}
double
cfile_get_tx_count(cfile_t *cfile)
{
if(cfile == NULL) return 0;
if(cfile->curl_handle == NULL) return 0;
return cfile->tx_count;
}
double
cfile_get_tx_length(cfile_t *cfile)
{
if(cfile == NULL) return 0;
if(cfile->curl_handle == NULL) return 0;
return cfile->tx_length;
}
void
cfile_set_userptr(cfile_t *cfile,void *anything)
{
if(cfile == NULL) return;
cfile->userptr = anything;
return;
}
void*
cfile_get_userptr(cfile_t *cfile)
{
if(cfile == NULL) return NULL;
return cfile->userptr;
}
static size_t
_cfile_tx_callback(char *data,size_t size,size_t nmemb,void *user_ptr)
{
cfile_t *cfile;
size_t data_sz = 0;
char *buffer_tail;
/*
Your function must return the actual number of bytes that you stored
in that memory area. Returning 0 will signal end-of-file to the
library and cause it to stop the current transfer.
*/
if(user_ptr == NULL) return 0;
cfile = (cfile_t*)user_ptr;
data_sz = size * nmemb;
if(data_sz > 0)
{
cfile->tx_buffer = (char*)realloc(cfile->tx_buffer,
cfile->tx_buffer_sz);
buffer_tail = cfile->tx_buffer + cfile->tx_buffer_sz;
memcpy(buffer_tail,data,data_sz);
cfile->tx_buffer_sz += data_sz;
}
if(cfile->user_io != NULL)
{
cfile->user_io(cfile);
}
if(cfile->progress != NULL)
{
cfile->progress(cfile);
}
return data_sz;
}
static size_t
_cfile_rx_callback(char *data,size_t size,size_t nmemb,void *user_ptr)
{
cfile_t *cfile;
size_t data_sz = 0;
char *buffer_tail = NULL;
/*
Your function must return the actual number of bytes that you stored
in that memory area. Returning 0 will signal end-of-file to the
library and cause it to stop the current transfer.
*/
if(user_ptr == NULL) return 0;
cfile = (cfile_t*)user_ptr;
data_sz = size * nmemb;
if(data_sz > 0)
{
cfile->rx_buffer = (char*)realloc(cfile->rx_buffer,
cfile->rx_buffer_sz + data_sz);
buffer_tail = cfile->rx_buffer + cfile->rx_buffer_sz;
memcpy(buffer_tail,data,data_sz);
cfile->rx_buffer_sz += data_sz;
}
if(cfile->user_io != NULL)
{
cfile->user_io(cfile);
}
if(cfile->progress != NULL)
{
cfile->progress(cfile);
}
return data_sz;
}
static int
_cfile_progress_callback(void *user_ptr,double dltotal,double dlnow,
double ultotal,double ulnow)
{
cfile_t *cfile;
if(user_ptr == NULL) return 0;
cfile = (cfile_t*)user_ptr;
cfile->tx_length = ultotal;
cfile->tx_count = ulnow;
cfile->rx_length = dltotal;
cfile->rx_count = dlnow;
return 0;
}

96
cfile.h
View File

@@ -1,96 +0,0 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
* the Free Software Foundation.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef _CFILE_H_
#define _CFILE_H_
#include <stdint.h>
typedef struct _cfile_s cfile_t;
typedef void (*CFileFunc) (cfile_t *cfile);
#define CFILE_MODE_TEXT 1
#define CFILE_MODE_BINARY 2
#define CFILE_OPT_FOLLOW_REDIRECTS (1 << 0)
#define CFILE_OPT_ENABLE_SSL (1 << 1)
#define CFILE_OPT_ENABLE_SSL_LAX (1 << 2)
enum
{
CFILE_ARGS_POST,
CFILE_ARGS_GET,
CFILE_ARGS_HEADER,
};
cfile_t* cfile_create(void);
int cfile_exec(cfile_t *cfile);
void cfile_destroy(cfile_t *cfile);
void cfile_set_mode(cfile_t *cfile,int mode);
void cfile_set_defaults(cfile_t *cfile);
void cfile_set_url(cfile_t *cfile,const char *url);
int cfile_get_url(cfile_t *cfile,char *buf,size_t buf_sz);
void cfile_set_args(cfile_t *cfile,int type,const char *args);
void cfile_add_args(cfile_t *cfile,int type,const char *args);
int cfile_set_opts(cfile_t *cfile,uint32_t opts);
uint32_t cfile_get_opts(cfile_t *cfile);
void cfile_set_io_func(cfile_t *cfile,CFileFunc io_func);
void cfile_set_progress_func(cfile_t *cfile,CFileFunc progress);
const char* cfile_get_rx_buffer(cfile_t *cfile);
size_t cfile_get_rx_buffer_size(cfile_t *cfile);
void cfile_reset_rx_buffer(cfile_t *cfile);
const char* cfile_get_tx_buffer(cfile_t *cfile);
size_t cfile_get_tx_buffer_size(cfile_t *cfile);
void cfile_reset_tx_buffer(cfile_t *cfile);
void cfile_copy_buffer(cfile_t *cfile,char *buffer,size_t sz);
double cfile_get_tx_length(cfile_t *cfile);
double cfile_get_rx_length(cfile_t *cfile);
double cfile_get_rx_count(cfile_t *cfile);
double cfile_get_tx_count(cfile_t *cfile);
void cfile_set_userptr(cfile_t *cfile,void *anything);
void* cfile_get_userptr(cfile_t *cfile);
#endif

View File

@@ -82,7 +82,7 @@ mfshell_cmd_get(mfshell_t *mfshell, int argc, char **argv)
getcwd(mfshell->local_working_dir,PATH_MAX);
}
retval = download_direct(file,mfshell->local_working_dir);
retval = download_direct(mfshell, file, mfshell->local_working_dir);
if(retval != -1)
printf("\r Downloaded %zd bytes OK!\n\r",bytes_read);

210
connection.c Normal file
View File

@@ -0,0 +1,210 @@
/*
* Copyright (C) 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
* the Free Software Foundation.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <stdlib.h>
#include <string.h>
#include "private.h"
#include "mfshell.h"
static int conn_progress_cb(void *user_ptr, double dltotal, double dlnow, double ultotal, double ulnow);
static size_t conn_read_buf_cb(char *data, size_t size, size_t nmemb, void *user_ptr);
static size_t conn_write_buf_cb(char *data, size_t size, size_t nmemb, void *user_ptr);
static size_t conn_write_file_cb(char *data, size_t size, size_t nmemb, void *user_ptr);
/*
* This set of functions is made such that the conn_t struct and the curl
* handle it stores can be reused for multiple operations
*
* We do not use a single global instance because mediafire does not support
* keep-alive anyways.
*/
conn_t*
conn_create(void)
{
conn_t *conn;
CURL *curl_handle;
curl_handle = curl_easy_init();
if(curl_handle == NULL) return NULL;
conn = (conn_t*)calloc(1,sizeof(conn_t));
conn->curl_handle = curl_handle;
conn->show_progress = false;
curl_easy_setopt(conn->curl_handle, CURLOPT_NOPROGRESS,0);
curl_easy_setopt(conn->curl_handle, CURLOPT_PROGRESSFUNCTION, conn_progress_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_PROGRESSDATA, (void *)conn);
curl_easy_setopt(conn->curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(conn->curl_handle, CURLOPT_SSLENGINE, NULL);
curl_easy_setopt(conn->curl_handle, CURLOPT_SSLENGINE_DEFAULT, 1L);
curl_easy_setopt(conn->curl_handle, CURLOPT_ERRORBUFFER, conn->error_buf);
return conn;
}
void
conn_destroy(conn_t* conn)
{
curl_easy_cleanup(conn->curl_handle);
free(conn->write_buf);
free(conn);
}
static int conn_progress_cb(void *user_ptr, double dltotal, double dlnow,
double ultotal, double ulnow)
{
conn_t *conn;
if (user_ptr == NULL) return 0;
conn = (conn_t *)user_ptr;
conn->ul_len = ultotal;
conn->ul_now = ulnow;
conn->dl_len = dltotal;
conn->dl_now = dlnow;
return 0;
}
int
conn_get_buf(conn_t *conn, char *url, int (*data_handler)(conn_t *conn, void *data), void *data)
{
int retval;
curl_easy_reset(conn->curl_handle);
curl_easy_setopt(conn->curl_handle, CURLOPT_URL, url);
curl_easy_setopt(conn->curl_handle, CURLOPT_READFUNCTION, conn_read_buf_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_READDATA, (void*)conn);
curl_easy_setopt(conn->curl_handle, CURLOPT_WRITEFUNCTION, conn_write_buf_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_WRITEDATA, (void*)conn);
retval = curl_easy_perform(conn->curl_handle);
if(retval != CURLE_OK) {
fprintf(stderr, "error curl_easy_perform %s\n\r", conn->error_buf);
return retval;
}
if (data_handler != NULL)
retval = data_handler(conn, data);
conn->write_buf_len = 0;
return retval;
}
static size_t
conn_read_buf_cb(char *data, size_t size, size_t nmemb, void *user_ptr)
{
conn_t *conn;
size_t data_len;
if (user_ptr == NULL) return 0;
conn = (conn_t*)user_ptr;
data_len = size*nmemb;
if (data_len > 0) {
fprintf(stderr, "Not implemented");
exit(1);
}
return 0;
}
static size_t
conn_write_buf_cb(char *data, size_t size, size_t nmemb, void *user_ptr)
{
conn_t *conn;
size_t data_len;
if (user_ptr == NULL) return 0;
conn = (conn_t*)user_ptr;
data_len = size*nmemb;
if (data_len > 0) {
conn->write_buf = (char *)realloc(conn->write_buf,
conn->write_buf_len + data_len);
memcpy(conn->write_buf + conn->write_buf_len, data, data_len);
conn->write_buf_len += data_len;
}
return data_len;
}
int
conn_post_buf(conn_t *conn, char *url, char *post_args, int (*data_handler)(conn_t *conn, void *data), void *data)
{
int retval;
curl_easy_reset(conn->curl_handle);
curl_easy_setopt(conn->curl_handle, CURLOPT_URL, url);
curl_easy_setopt(conn->curl_handle, CURLOPT_READFUNCTION, conn_read_buf_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_READDATA, (void*)conn);
curl_easy_setopt(conn->curl_handle, CURLOPT_WRITEFUNCTION, conn_write_buf_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_WRITEDATA, (void*)conn);
curl_easy_setopt(conn->curl_handle, CURLOPT_POSTFIELDS, post_args);
retval = curl_easy_perform(conn->curl_handle);
if(retval != CURLE_OK) {
fprintf(stderr, "error curl_easy_perform %s\n\r", conn->error_buf);
return retval;
}
if (data_handler != NULL)
retval = data_handler(conn, data);
conn->write_buf_len = 0;
return retval;
}
int
conn_get_file(conn_t *conn, char *url, char *path)
{
int retval;
curl_easy_reset(conn->curl_handle);
curl_easy_setopt(conn->curl_handle, CURLOPT_URL, url);
curl_easy_setopt(conn->curl_handle, CURLOPT_READFUNCTION, conn_read_buf_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_READDATA, (void*)conn);
curl_easy_setopt(conn->curl_handle, CURLOPT_WRITEFUNCTION, conn_write_file_cb);
curl_easy_setopt(conn->curl_handle, CURLOPT_WRITEDATA, (void*)conn);
// FIXME: handle fopen() return value
conn->stream = fopen(path, "w+");
retval = curl_easy_perform(conn->curl_handle);
fclose(conn->stream);
if(retval != CURLE_OK) {
fprintf(stderr, "error curl_easy_perform %s\n\r", conn->error_buf);
return retval;
}
return retval;
}
static size_t
conn_write_file_cb(char *data, size_t size, size_t nmemb, void *user_ptr)
{
conn_t *conn;
if (user_ptr == NULL) return 0;
conn = (conn_t*)user_ptr;
fwrite(data, size, nmemb, conn->stream);
fprintf(stderr, "\r %.0f / %.0f", conn->dl_now, conn->dl_len);
}
int
conn_post_file(conn_t *conn, char *url, char *post_args, FILE *fd)
{
}

29
connection.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by█
* the Free Software Foundation.
*
* This program 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 General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with█
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef _MFSHELL_CONNECTION_H_
#define _MFSHELL_CONNECTION_H_
conn_t* conn_create(void);
void conn_destroy(conn_t* conn);
int conn_get_buf(conn_t *conn, const char *url, int (*data_handler)(conn_t *conn, void *data), void *data);
int conn_post_buf(conn_t *conn, const char *url, char *post_args, int (*data_handler)(conn_t *conn, void *data), void *data);
int conn_get_file(conn_t *conn, const char *url, char *path);
int conn_post_file(conn_t *conn, const char *url, char *post_args, FILE *fd);
#endif

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -31,20 +32,13 @@
#include "mfshell.h"
#include "private.h"
#include "account.h"
#include "cfile.h"
#include "strings.h"
#include "download.h"
void
_download_direct_cbio(cfile_t *cfile);
void
_download_direct_cbprogress(cfile_t *cfile);
#include "connection.h"
ssize_t
download_direct(file_t *file,char *local_dir)
download_direct(mfshell_t *mfshell, file_t *file, char *local_dir)
{
cfile_t *cfile;
const char *url;
const char *file_name;
char *file_path;
@@ -62,32 +56,14 @@ download_direct(file_t *file,char *local_dir)
if(file_name == NULL) return -1;
if(strlen(file_name) < 1) return -1;
// create the object as a sender
cfile = cfile_create();
// take the defaults but switch to binary mode
cfile_set_defaults(cfile);
cfile_set_mode(cfile,CFILE_MODE_BINARY);
cfile_set_url(cfile,url);
cfile_set_io_func(cfile,_download_direct_cbio);
cfile_set_progress_func(cfile,_download_direct_cbprogress);
if(local_dir[strlen(local_dir) - 1] == '/')
file_path = strdup_printf("%s%s",local_dir,file_name);
else
file_path = strdup_printf("%s/%s",local_dir,file_name);
cfile_set_userptr(cfile,(void*)file_path);
retval = cfile_exec(cfile);
cfile_destroy(cfile);
if(retval != CURLE_OK)
{
free(file_path);
return -1;
}
conn_t *conn = conn_create();
retval = conn_get_file(conn, url, file_path);
conn_destroy(conn);
/*
it is preferable to have the vfs tell us how many bytes the
@@ -104,50 +80,3 @@ download_direct(file_t *file,char *local_dir)
return bytes_read;
}
void
_download_direct_cbio(cfile_t *cfile)
{
FILE *file;
char *file_path;
size_t bytes_ready = 0;
const char *rx_buffer;
if(cfile == NULL) return;
file_path = (char*)cfile_get_userptr(cfile);
if(file_path == NULL) return;
bytes_ready = cfile_get_rx_buffer_size(cfile);
if(bytes_ready == 0) return;
file = fopen(file_path,"a+");
if(file != NULL)
{
rx_buffer = cfile_get_rx_buffer(cfile);
fwrite((const void*)rx_buffer,sizeof(char),bytes_ready,file);
}
fclose(file);
cfile_reset_rx_buffer(cfile);
return;
}
void
_download_direct_cbprogress(cfile_t *cfile)
{
double total;
double recv;
if(cfile == NULL) return;
total = cfile_get_rx_length(cfile);
recv = cfile_get_rx_count(cfile);
printf("\r %.0f / %.0f",recv,total);
return;
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -20,6 +21,6 @@
#ifndef _MFSHELL_DOWNLOAD_H_
#define _MFSHELL_DOWNLOAD_H_
ssize_t download_direct(file_t *file,char *local_dir);
ssize_t download_direct(mfshell_t *mfshell, file_t *file,char *local_dir);
#endif

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -27,17 +28,16 @@
#include "mfshell.h"
#include "private.h"
#include "account.h"
#include "cfile.h"
#include "strings.h"
#include "json.h"
#include "connection.h"
static int
_decode_file_get_info(mfshell_t *mfshell,cfile_t *cfile,file_t *file);
_decode_file_get_info(conn_t *conn, void *data);
int
_file_get_info(mfshell_t *mfshell,file_t *file,char *quickkey)
{
cfile_t *cfile;
char *api_call;
int retval;
int len;
@@ -54,35 +54,21 @@ _file_get_info(mfshell_t *mfshell,file_t *file,char *quickkey)
// key must either be 11 or 15 chars
if(len != 11 && len != 15) return -1;
// create the object as a sender
cfile = cfile_create();
// take the traditional defaults
cfile_set_defaults(cfile);
// cfile_set_opts(cfile,CFILE_OPT_ENABLE_SSL_LAX);
api_call = mfshell->create_signed_get(mfshell,0,"file/get_info.php",
api_call = mfshell->create_signed_get(mfshell, 1, "file/get_info.php",
"?quick_key=%s"
"&session_token=%s"
"&response_format=json",
quickkey,mfshell->session_token);
cfile_set_url(cfile,api_call);
retval = cfile_exec(cfile);
if(retval != CURLE_OK) printf("error %d\n\r",retval);
retval = _decode_file_get_info(mfshell,cfile,file);
cfile_destroy(cfile);
conn_t *conn = conn_create();
retval = conn_get_buf(conn, api_call, _decode_file_get_info, file);
conn_destroy(conn);
return retval;
}
static int
_decode_file_get_info(mfshell_t *mfshell,cfile_t *cfile,file_t *file)
_decode_file_get_info(conn_t *conn, void *data)
{
json_error_t error;
json_t *root;
@@ -92,11 +78,13 @@ _decode_file_get_info(mfshell_t *mfshell,cfile_t *cfile,file_t *file)
json_t *file_name;
json_t *file_folder;
int retval = 0;
file_t *file;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
if(data == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
file = (file_t *)data;
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
node = json_object_by_path(root,"response/file_info");

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -27,17 +28,16 @@
#include "mfshell.h"
#include "private.h"
#include "account.h"
#include "cfile.h"
#include "strings.h"
#include "json.h"
#include "connection.h"
static int
_decode_file_get_links(mfshell_t *mfshell,cfile_t *cfile,file_t *file);
_decode_file_get_links(conn_t *conn, void *data);
int
_file_get_links(mfshell_t *mfshell,file_t *file,char *quickkey)
{
cfile_t *cfile;
char *api_call;
int retval;
int len;
@@ -54,35 +54,21 @@ _file_get_links(mfshell_t *mfshell,file_t *file,char *quickkey)
// key must either be 11 or 15 chars
if(len != 11 && len != 15) return -1;
// create the object as a sender
cfile = cfile_create();
// take the traditional defaults
cfile_set_defaults(cfile);
// cfile_set_opts(cfile,CFILE_OPT_ENABLE_SSL_LAX);
api_call = mfshell->create_signed_get(mfshell,0,"file/get_links.php",
"?quick_key=%s"
"&session_token=%s"
"&response_format=json",
quickkey,mfshell->session_token);
cfile_set_url(cfile,api_call);
retval = cfile_exec(cfile);
if(retval != CURLE_OK) printf("error %d\n\r",retval);
retval = _decode_file_get_links(mfshell,cfile,file);
cfile_destroy(cfile);
conn_t *conn = conn_create();
retval = conn_get_buf(conn, api_call, _decode_file_get_links, file);
conn_destroy(conn);
return retval;
}
static int
_decode_file_get_links(mfshell_t *mfshell,cfile_t *cfile,file_t *file)
_decode_file_get_links(conn_t *conn, void *data)
{
json_error_t error;
json_t *root;
@@ -93,11 +79,13 @@ _decode_file_get_links(mfshell_t *mfshell,cfile_t *cfile,file_t *file)
json_t *onetime_link;
json_t *links_array;
int retval = 0;
file_t *file;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
if(data == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
file = (file_t *)data;
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
node = json_object_by_path(root,"response");

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -26,13 +27,12 @@
#include "mfshell.h"
#include "private.h"
#include "account.h"
#include "cfile.h"
#include "connection.h"
#include "strings.h"
int
_folder_create(mfshell_t *mfshell,char *parent,char *name)
{
cfile_t *cfile;
char *api_call;
int retval;
@@ -53,12 +53,6 @@ _folder_create(mfshell_t *mfshell,char *parent,char *name)
}
}
// create the object as a sender
cfile = cfile_create();
// take the traditional defaults
cfile_set_defaults(cfile);
if(parent != NULL)
{
api_call = mfshell->create_signed_get(mfshell,0,"folder/create.php",
@@ -77,13 +71,9 @@ _folder_create(mfshell_t *mfshell,char *parent,char *name)
name,mfshell->session_token);
}
cfile_set_url(cfile,api_call);
retval = cfile_exec(cfile);
if(retval != CURLE_OK) printf("error %d\n\r",retval);
cfile_destroy(cfile);
conn_t *conn = conn_create();
retval = conn_get_buf(conn, api_call, NULL, NULL);
conn_destroy(conn);
return retval;
}

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -27,17 +28,16 @@
#include "mfshell.h"
#include "private.h"
#include "account.h"
#include "cfile.h"
#include "strings.h"
#include "json.h"
#include "connection.h"
static int
_decode_folder_get_info(mfshell_t *mfshell,cfile_t *cfile,folder_t *folder);
_decode_folder_get_info(conn_t *conn, void *data);
int
_folder_get_info(mfshell_t *mfshell,folder_t *folder,char *folderkey)
{
cfile_t *cfile;
char *api_call;
int retval;
@@ -54,33 +54,21 @@ _folder_get_info(mfshell_t *mfshell,folder_t *folder,char *folderkey)
if(strcmp(folderkey,"myfiles") == 0) return -1;
}
// create the object as a sender
cfile = cfile_create();
// take the traditional defaults
cfile_set_defaults(cfile);
api_call = mfshell->create_signed_get(mfshell,0,"folder/get_info.php",
"?folder_key=%s"
"&session_token=%s"
"&response_format=json",
folderkey,mfshell->session_token);
cfile_set_url(cfile,api_call);
retval = cfile_exec(cfile);
if(retval != CURLE_OK) printf("error %d\n\r",retval);
retval = _decode_folder_get_info(mfshell,cfile,folder);
cfile_destroy(cfile);
conn_t *conn = conn_create();
retval = conn_get_buf(conn, api_call, _decode_folder_get_info, folder);
conn_destroy(conn);
return retval;
}
static int
_decode_folder_get_info(mfshell_t *mfshell,cfile_t *cfile,folder_t *folder)
_decode_folder_get_info(conn_t *conn, void *data)
{
json_error_t error;
json_t *root;
@@ -89,11 +77,13 @@ _decode_folder_get_info(mfshell_t *mfshell,cfile_t *cfile,folder_t *folder)
json_t *folder_name;
json_t *parent_folder;
int retval = 0;
folder_t *folder;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
if(data == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
folder = (folder_t *)data;
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
node = json_object_by_path(root,"response/folder_info");

49
list.c
View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -26,21 +27,20 @@
#include "mfshell.h"
#include "private.h"
#include "cfile.h"
#include "strings.h"
#include "json.h"
#include "list.h"
#include "connection.h"
static int
_decode_folder_get_content_folders(mfshell_t *mfshell,cfile_t *cfile);
_decode_folder_get_content_folders(conn_t *conn, void *data);
static int
_decode_folder_get_content_files(mfshell_t *mfshell,cfile_t *cfile);
_decode_folder_get_content_files(conn_t *conn, void *data);
long
_folder_get_content(mfshell_t *mfshell,int mode)
{
cfile_t *cfile;
char *api_call;
int retval;
char *rx_buffer;
@@ -50,14 +50,6 @@ _folder_get_content(mfshell_t *mfshell,int mode)
if(mfshell->user_signature == NULL) return -1;
if(mfshell->session_token == NULL) return -1;
// create the object as a sender
cfile = cfile_create();
// take the traditional defaults
cfile_set_defaults(cfile);
// cfile_set_opts(cfile,CFILE_OPT_ENABLE_SSL_LAX);
if(mode == 0)
content_type = "folders";
else
@@ -72,30 +64,19 @@ _folder_get_content(mfshell_t *mfshell,int mode)
folder_get_key(mfshell->folder_curr),
content_type);
cfile_set_url(cfile,api_call);
retval = cfile_exec(cfile);
// print an error code if something went wrong
if(retval != CURLE_OK) printf("error %d\n\r",retval);
// rx_buffer = cfile_get_rx_buffer(cfile);
// printf("\n\r%s\n\r",rx_buffer);
conn_t* conn = conn_create();
if(mode == 0)
retval = _decode_folder_get_content_folders(mfshell,cfile);
retval = conn_get_buf(conn, api_call, _decode_folder_get_content_folders, NULL);
else
retval = _decode_folder_get_content_files(mfshell,cfile);
cfile_destroy(cfile);
retval = conn_get_buf(conn, api_call, _decode_folder_get_content_files, NULL);
conn_destroy(conn);
return retval;
}
static int
_decode_folder_get_content_folders(mfshell_t *mfshell,cfile_t *cfile)
_decode_folder_get_content_folders(conn_t *conn, void *user_ptr)
{
extern int term_width;
@@ -112,10 +93,7 @@ _decode_folder_get_content_folders(mfshell_t *mfshell,cfile_t *cfile)
int array_sz;
int i = 0;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
node = json_object_by_path(root,"response/folder_content");
@@ -158,7 +136,7 @@ _decode_folder_get_content_folders(mfshell_t *mfshell,cfile_t *cfile)
}
static int
_decode_folder_get_content_files(mfshell_t *mfshell,cfile_t *cfile)
_decode_folder_get_content_files(conn_t *conn, void *user_ptr)
{
extern int term_width;
@@ -173,10 +151,7 @@ _decode_folder_get_content_files(mfshell_t *mfshell,cfile_t *cfile)
int array_sz;
int i = 0;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
node = json_object_by_path(root,"response/folder_content");

1
main.c
View File

@@ -29,7 +29,6 @@
#include "mfshell.h"
#include "console.h"
#include "private.h"
#include "cfile.h"
#include "strings.h"
#include "signals.h"

View File

@@ -25,7 +25,6 @@
#include <curl/curl.h>
#include "cfile.h"
#include "strings.h"
#include "mfshell.h"
#include "private.h"
@@ -37,6 +36,7 @@
#include "file_info.h"
#include "file_links.h"
#include "folder_create.h"
#include "connection.h"
struct _cmd_s commands[] = {
{"help", "", "show this help", mfshell_cmd_help},

View File

@@ -25,6 +25,7 @@ typedef struct _mfshell_s mfshell_t;
typedef struct _folder_s folder_t;
typedef struct _file_s file_t;
typedef struct _cmd_s cmd_t;
typedef struct _conn_s conn_t;
mfshell_t* mfshell_create(int app_id,char *app_key,char *server);

View File

@@ -22,11 +22,14 @@
#define _MFSHELL_PRIVATE_H_
#include <inttypes.h>
#include <stdbool.h>
#include <curl/curl.h>
typedef struct _mfshell_s _mfshell_t;
typedef struct _folder_s _folder_t;
typedef struct _file_s _file_t;
typedef struct _cmd_s _cmd_t;
typedef struct _conn_s _conn_t;
struct _cmd_s
{
@@ -59,6 +62,20 @@ struct _file_s
char *onetime_link;
};
struct _conn_s
{
CURL *curl_handle;
char *write_buf;
size_t write_buf_len;
double ul_len;
double ul_now;
double dl_len;
double dl_now;
bool show_progress;
char error_buf[CURL_ERROR_SIZE];
FILE *stream;
};
struct _mfshell_s
{
int app_id;

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -24,7 +25,6 @@
#include <openssl/sha.h>
#include <openssl/md5.h>
#include "cfile.h"
#include "strings.h"
#include "private.h"

View File

@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Bryan Christ <bryan.christ@mediafire.com>
* 2014 Johannes Schauer <j.schauer@email.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2, as published by
@@ -27,35 +28,25 @@
#include "mfshell.h"
#include "private.h"
#include "user_session.h"
#include "cfile.h"
#include "connection.h"
#include "strings.h"
#include "json.h"
static int
_decode_get_session_token(mfshell_t *mfshell,cfile_t *cfile);
_decode_get_session_token(conn_t *conn, void *data);
int
_get_session_token(mfshell_t *mfshell)
{
cfile_t *cfile;
char *login_url;
char *post_args;
int retval;
if(mfshell == NULL) return -1;
// create the object as a sender
cfile = cfile_create();
cfile_set_defaults(cfile);
// cfile_set_opts(cfile,CFILE_OPT_ENABLE_SSL_LAX);
// configure url for operation
login_url = strdup_printf("https://%s/api/user/get_session_token.php",
mfshell->server);
cfile_set_url(cfile,login_url);
free(login_url);
// invalidate an existing user signature
if(mfshell->user_signature != NULL)
@@ -77,24 +68,18 @@ _get_session_token(mfshell_t *mfshell)
"&response_format=json",
mfshell->user,mfshell->passwd,mfshell->user_signature);
cfile_set_args(cfile,CFILE_ARGS_POST,post_args);
conn_t *conn = conn_create();
retval = conn_post_buf(conn, login_url, post_args, _decode_get_session_token, (void *)mfshell);
conn_destroy(conn);
free(login_url);
free(post_args);
retval = cfile_exec(cfile);
// print an error code if something went wrong
if(retval != CURLE_OK) printf("error %d\n\r",retval);
// printf("\n\r%s\n\r",cfile_get_rx_buffer(cfile));
retval = _decode_get_session_token(mfshell,cfile);
cfile_destroy(cfile);
return retval;
}
static int
_decode_get_session_token(mfshell_t *mfshell,cfile_t *cfile)
_decode_get_session_token(conn_t *conn, void *user_ptr)
{
json_error_t error;
json_t *root = NULL;
@@ -102,11 +87,13 @@ _decode_get_session_token(mfshell_t *mfshell,cfile_t *cfile)
json_t *session_token;
json_t *secret_key;
json_t *secret_time;
mfshell_t *mfshell;
if(mfshell == NULL) return -1;
if(cfile == NULL) return -1;
if(user_ptr == NULL) return -1;
root = json_loads(cfile_get_rx_buffer(cfile),0,&error);
mfshell = (mfshell_t *)user_ptr;
root = json_loadb(conn->write_buf, conn->write_buf_len, 0, &error);
data = json_object_by_path(root,"response");
if(data == NULL) return -1;