From 5744a3338ab916056b90d7eea0df83ca1ba8a87f Mon Sep 17 00:00:00 2001 From: Fufu Fang Date: Mon, 30 Jul 2018 14:20:04 +0100 Subject: [PATCH] added username and password support --- link.c | 16 ++++++++--- main.c | 79 ++++++++++++++++++++++++++++++++++++++----------------- network.c | 41 ++++++++++++++++++----------- network.h | 25 ++++++++++++++---- 4 files changed, 113 insertions(+), 48 deletions(-) diff --git a/link.c b/link.c index f70a4c4..04f7c92 100644 --- a/link.c +++ b/link.c @@ -14,7 +14,7 @@ #define HTTP_RANGE_NOT_SATISFIABLE 416 /* ---------------- External variables -----------------------*/ -LinkTable *ROOT_LINK_TBL; +LinkTable *ROOT_LINK_TBL = NULL; static void HTML_to_LinkTable(GumboNode *node, LinkTable *linktbl); static Link *Link_new(const char *p_url, LinkType type); @@ -90,12 +90,20 @@ static CURL *Link_to_curl(Link *link) curl_easy_setopt(curl, CURLOPT_URL, link->f_url); curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15); - curl_easy_setopt(curl, CURLOPT_SHARE, curl_share); + curl_easy_setopt(curl, CURLOPT_SHARE, CURL_SHARE); /* * The write back function pointer has to be set at curl handle creation, * for thread safety */ - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback); + + if (NETWORK_CONFIG.username) { + curl_easy_setopt(curl, CURLOPT_USERNAME, NETWORK_CONFIG.username); + } + + if (NETWORK_CONFIG.password) { + curl_easy_setopt(curl, CURLOPT_PASSWORD, NETWORK_CONFIG.password); + } return curl; } @@ -229,7 +237,7 @@ LinkTable *LinkTable_new(const char *url) curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp); if (http_resp != HTTP_OK) { fprintf(stderr, "link.c: LinkTable_new() cannot retrive the base URL, \ - URL: %s, HTTP %ld\n", url, http_resp); +URL: %s, HTTP %ld\n", url, http_resp); LinkTable_free(linktbl); linktbl = NULL; diff --git a/main.c b/main.c index fd203f4..da2d5fe 100644 --- a/main.c +++ b/main.c @@ -4,20 +4,11 @@ #include #include -void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string); -static void print_help(char *program_name); +#define ARG_LEN_MAX 64 -/** - * \brief add an argument to an argv array - * \details This is basically how you add a string to an array of string - */ -void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string) -{ - (*fuse_argc)++; - *fuse_argv_ptr = realloc(*fuse_argv_ptr, *fuse_argc * sizeof(char *)); - char **fuse_argv = *fuse_argv_ptr; - fuse_argv[*fuse_argc - 1] = opt_string; -} +void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string); +static void print_help(char *program_name, int long_help); +static void print_http_options(); int main(int argc, char **argv) { @@ -28,17 +19,23 @@ int main(int argc, char **argv) add_arg(&fuse_argv, &fuse_argc, argv[0]); /* Automatically print help if not enough arguments are supplied */ if (argc < 2) { - add_arg(&fuse_argv, &fuse_argc, "--help"); - goto fuse_start; + print_help(argv[0], 0); + fprintf(stderr, "For more information, run \"%s --help.\"\n", argv[0]); + exit(EXIT_FAILURE); } + /* initialise network configuration struct */ + network_config_init(); + char c; int opts_index = 0; - const char *short_opts = "o:hVdfs"; + const char *short_opts = "o:hVdfsp:u:"; const struct option long_opts[] = { {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {"debug", no_argument, NULL, 'd'}, + {"username", required_argument, NULL, 'u'}, + {"password", required_argument, NULL, 'p'}, {0, 0, 0, 0} }; while ((c = @@ -50,7 +47,7 @@ int main(int argc, char **argv) add_arg(&fuse_argv, &fuse_argc, optarg); break; case 'h': - print_help(argv[0]); + print_help(argv[0], 1); add_arg(&fuse_argv, &fuse_argc, "-h"); goto fuse_start; break; @@ -66,22 +63,33 @@ int main(int argc, char **argv) case 's': add_arg(&fuse_argv, &fuse_argc, "-s"); break; + case 'p': + NETWORK_CONFIG.username = strndup(optarg, ARG_LEN_MAX); + break; + case 'u': + NETWORK_CONFIG.password = strndup(optarg, ARG_LEN_MAX); + break; case '?': - exit(EXIT_FAILURE); + fprintf(stderr, "Error: Invalid option\n"); + add_arg(&fuse_argv, &fuse_argc, "--help"); + goto fuse_start; } }; - /* Add the last remaining argument, which is the mount point */ + /* Add the last remaining argument, which is the mountpoint */ add_arg(&fuse_argv, &fuse_argc, argv[argc-1]); /* The second last remaining argument is the URL */ char *base_url = argv[argc-2]; if (strncmp(base_url, "http://", 7) && strncmp(base_url, "https://", 8)) { fprintf(stderr, "Error: Please supply a valid URL.\n"); - print_help(argv[0]); + print_help(argv[0], 0); exit(EXIT_FAILURE); } else { - network_init(base_url); + if(!network_init(base_url)) { + fprintf(stderr, "Error: Network initialisation failed.\n"); + exit(EXIT_FAILURE); + } } fuse_start: @@ -90,9 +98,32 @@ int main(int argc, char **argv) return 0; } -static void print_help(char *program_name) +/** + * \brief add an argument to an argv array + * \details This is basically how you add a string to an array of string + */ +void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string) { - fprintf(stderr, - "Usage: %s [options] URL mount_point\n", program_name); + (*fuse_argc)++; + *fuse_argv_ptr = realloc(*fuse_argv_ptr, *fuse_argc * sizeof(char *)); + char **fuse_argv = *fuse_argv_ptr; + fuse_argv[*fuse_argc - 1] = strndup(opt_string, ARG_LEN_MAX); } +static void print_help(char *program_name, int long_help) +{ + fprintf(stderr, + "Usage: %s [options] URL mountpoint\n", program_name); + if (long_help) { + print_http_options(); + } +} + +static void print_http_options() +{ + fprintf(stderr, +"HTTP options:\n\ + -u --username HTTP authentication username\n\ + -p --password HTTP authentication password\n\n\ +libfuse options:\n"); +} diff --git a/network.c b/network.c index 635d263..234db61 100644 --- a/network.c +++ b/network.c @@ -8,8 +8,9 @@ #include #include -/* ----------------- External variables ----------------------*/ -CURLSH *curl_share; +/* ----------------- External variables ---------------------- */ +CURLSH *CURL_SHARE; +NetworkConfigStruct NETWORK_CONFIG; /* ----------------- Static variable ----------------------- */ /** \brief curl multi interface handle */ @@ -18,8 +19,9 @@ static CURLM *curl_multi; static pthread_mutex_t transfer_lock; /** \brief the lock array for cryptographic functions */ static pthread_mutex_t *crypto_lockarray; -/** \brief mutex for curl share interface itself */ +/** \brief mutex for curl share interface itself */ static pthread_mutex_t curl_lock; +/** \brief network configuration */ /* ---------------- Static function prototype ---------------*/ static void crypto_lock_callback(int mode, int type, char *file, int line); @@ -188,10 +190,18 @@ void curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs) } } -void network_init(const char *url) +void network_config_init() { + NETWORK_CONFIG.username = NULL; + NETWORK_CONFIG.password = NULL; + NETWORK_CONFIG.proxy_url = NULL; + NETWORK_CONFIG.proxy_password = NULL; + NETWORK_CONFIG.proxy_password = NULL; + NETWORK_CONFIG.max_conns = NETWORK_MAX_CONNS; +} - +LinkTable *network_init(const char *url) +{ /* ------- Global related ----------*/ if (curl_global_init(CURL_GLOBAL_ALL)) { fprintf(stderr, "network_init(): curl_global_init() failed!\n"); @@ -199,22 +209,22 @@ void network_init(const char *url) } /* -------- Share related ----------*/ - curl_share = curl_share_init(); - if (!(curl_share)) { + CURL_SHARE = curl_share_init(); + if (!(CURL_SHARE)) { fprintf(stderr, "network_init(): curl_share_init() failed!\n"); exit(EXIT_FAILURE); } - curl_share_setopt(curl_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); - curl_share_setopt(curl_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); - curl_share_setopt(curl_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); + curl_share_setopt(CURL_SHARE, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); + curl_share_setopt(CURL_SHARE, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); + curl_share_setopt(CURL_SHARE, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT); if (pthread_mutex_init(&curl_lock, NULL) != 0) { printf( "network_init(): curl_lock initialisation failed!\n"); exit(EXIT_FAILURE); } - curl_share_setopt(curl_share, CURLSHOPT_LOCKFUNC, curl_callback_lock); - curl_share_setopt(curl_share, CURLSHOPT_UNLOCKFUNC, curl_callback_unlock); + curl_share_setopt(CURL_SHARE, CURLSHOPT_LOCKFUNC, curl_callback_lock); + curl_share_setopt(CURL_SHARE, CURLSHOPT_UNLOCKFUNC, curl_callback_unlock); /* ------------- Multi related -----------*/ curl_multi = curl_multi_init(); @@ -223,7 +233,7 @@ void network_init(const char *url) exit(EXIT_FAILURE); } curl_multi_setopt(curl_multi, CURLMOPT_MAXCONNECTS, - CURL_MULTI_MAX_CONNECTION); + NETWORK_CONFIG.max_conns); /* ------------ Initialise locks ---------*/ if (pthread_mutex_init(&transfer_lock, NULL) != 0) { @@ -244,6 +254,7 @@ void network_init(const char *url) /* ----------- create the root link table --------------*/ ROOT_LINK_TBL = LinkTable_new(url); + return ROOT_LINK_TBL; } void transfer_blocking(CURL *curl) @@ -295,7 +306,7 @@ static unsigned long thread_id(void) } size_t -WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) +write_memory_callback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; MemoryStruct *mem = (MemoryStruct *)userp; @@ -303,7 +314,7 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) mem->memory = realloc(mem->memory, mem->size + realsize + 1); if(!mem->memory) { /* out of memory! */ - fprintf(stderr, "WriteMemoryCallback(): realloc failure!\n"); + fprintf(stderr, "write_memory_callback(): realloc failure!\n"); exit(EXIT_FAILURE); return 0; } diff --git a/network.h b/network.h index 152949e..125ac01 100644 --- a/network.h +++ b/network.h @@ -3,7 +3,7 @@ #include "link.h" -#define CURL_MULTI_MAX_CONNECTION 20 +#define NETWORK_MAX_CONNS 20 typedef struct { char *memory; @@ -21,14 +21,29 @@ typedef struct { Link *link; } TransferStruct; +typedef struct { + char *username; + char *password; + char *proxy_url; + char *proxy_username; + char *proxy_password; + long max_conns; +} NetworkConfigStruct; + +/** \brief CURL configuration */ +extern NetworkConfigStruct NETWORK_CONFIG; + /** \brief curl shared interface */ -extern CURLSH *curl_share; +extern CURLSH *CURL_SHARE; /** \brief perform one transfer cycle */ int curl_multi_perform_once(); -/** \brief Initialise the network module */ -void network_init(const char *url); +/** \brief initialise network config struct */ +void network_config_init(); + +/** \brief initialise the network module */ +LinkTable *network_init(const char *url); /** \brief blocking file transfer */ void transfer_blocking(CURL *curl); @@ -38,6 +53,6 @@ void transfer_nonblocking(CURL *curl); /** \brief callback function for file transfer */ size_t -WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp); +write_memory_callback(void *contents, size_t size, size_t nmemb, void *userp); #endif