220 lines
4.3 KiB
C
220 lines
4.3 KiB
C
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <getopt.h>
|
|
#include <errno.h>
|
|
#include <curl/curl.h>
|
|
#include <math.h>
|
|
|
|
#include "options.h"
|
|
#include "clainsafecli.h"
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
struct curl_httppost *post = NULL;
|
|
struct curl_httppost *last = NULL;
|
|
|
|
int tor_flag, i2p_flag;
|
|
tor_flag = i2p_flag = 0;
|
|
int ipv6_flag, ipv4_flag;
|
|
ipv6_flag = ipv4_flag = 0;
|
|
|
|
long silent_flag = 0L;
|
|
char *buffer = (char *)calloc(1024,sizeof(char));
|
|
if(buffer == NULL) {
|
|
fprintf(stderr,"Error allocating memory!\n");
|
|
return -1;
|
|
}
|
|
CURL *easy_handle = curl_easy_init();
|
|
|
|
if(!easy_handle) {
|
|
fprintf(stderr,"Error initializing libcurl\n");
|
|
return -1;
|
|
}
|
|
if(argc == optind) {
|
|
print_usage();
|
|
return -1;
|
|
}
|
|
|
|
int option_index = 0;
|
|
static struct option long_options[] = {
|
|
{"server",required_argument,0,'s'},
|
|
{"help" ,no_argument ,0,'h'},
|
|
{"tor" ,no_argument ,0,'t'},
|
|
{"i2p" ,no_argument ,0,'i'},
|
|
{"silent",no_argument ,0,'S'},
|
|
{"ipv4" ,no_argument ,0,'4'},
|
|
{"ipv6" ,no_argument ,0,'6'},
|
|
{0 ,0 ,0, 0 }
|
|
|
|
};
|
|
|
|
int c = 0;
|
|
while((c = getopt_long(argc,argv, "46htiSs:",
|
|
long_options,&option_index)) != -1) {
|
|
switch(c) {
|
|
case 's':
|
|
server = optarg;
|
|
break;
|
|
case 'h':
|
|
print_help();
|
|
return 0;
|
|
break;
|
|
case 't':
|
|
tor_flag = 1;
|
|
break;
|
|
case 'i':
|
|
i2p_flag = 1;
|
|
break;
|
|
case 'S':
|
|
silent_flag = 1L;
|
|
break;
|
|
case '4':
|
|
ipv4_flag = 1;
|
|
break;
|
|
case '6':
|
|
ipv6_flag = 1;
|
|
break;
|
|
case '?':
|
|
print_usage();
|
|
return 0;
|
|
break;
|
|
default:
|
|
print_usage();
|
|
return 0;
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
if(access(argv[optind],F_OK)) {
|
|
fprintf(stderr,"Error opening file\n");
|
|
return -1;
|
|
}
|
|
|
|
/* curl options */
|
|
curl_easy_setopt(easy_handle,CURLOPT_WRITEFUNCTION, write_data);
|
|
curl_easy_setopt(easy_handle,CURLOPT_WRITEDATA,buffer);
|
|
curl_easy_setopt(easy_handle,CURLOPT_URL,server);
|
|
|
|
/* Proxy options */
|
|
|
|
if(tor_flag && i2p_flag) {
|
|
fprintf(stderr,"Tor and I2P can't be used at once\n");
|
|
return -1;
|
|
} else if(tor_flag) {
|
|
curl_easy_setopt(easy_handle,CURLOPT_PROXY,tor_proxy_url);
|
|
curl_easy_setopt(easy_handle,CURLOPT_PROXYTYPE,
|
|
CURLPROXY_SOCKS5_HOSTNAME);
|
|
} else if(i2p_flag) {
|
|
curl_easy_setopt(easy_handle,CURLOPT_PROXY,i2p_proxy_url);
|
|
curl_easy_setopt(easy_handle,CURLOPT_PROXYTYPE,
|
|
CURLPROXY_HTTP);
|
|
}
|
|
|
|
/* Which address to use */
|
|
|
|
if(ipv6_flag)
|
|
curl_easy_setopt(easy_handle,CURLOPT_IPRESOLVE,
|
|
CURL_IPRESOLVE_V6);
|
|
else if(ipv4_flag)
|
|
curl_easy_setopt(easy_handle,CURLOPT_IPRESOLVE,
|
|
CURL_IPRESOLVE_V4);
|
|
else
|
|
curl_easy_setopt(easy_handle,CURLOPT_IPRESOLVE,
|
|
CURL_IPRESOLVE_WHATEVER);
|
|
|
|
/* Form parameters */
|
|
|
|
/* File name */
|
|
curl_formadd(&post,&last,
|
|
CURLFORM_COPYNAME,"file",
|
|
CURLFORM_FILE,argv[optind],
|
|
CURLFORM_END);
|
|
/* Actual file content */
|
|
curl_formadd(&post,&last,
|
|
CURLFORM_COPYNAME,"file",
|
|
CURLFORM_COPYCONTENTS,argv[optind],
|
|
CURLFORM_END);
|
|
|
|
/* Progress bar
|
|
*
|
|
* TODO: Use a custom progress bar rather than
|
|
* default curl progress bar
|
|
*
|
|
*/
|
|
|
|
curl_easy_setopt(easy_handle,CURLOPT_NOPROGRESS,silent_flag);
|
|
curl_easy_setopt(easy_handle,CURLOPT_PROGRESSFUNCTION,progress);
|
|
|
|
curl_easy_setopt(easy_handle,CURLOPT_HTTPPOST,post);
|
|
|
|
curl_easy_perform(easy_handle);
|
|
if(!silent_flag) puts("");
|
|
puts(buffer);
|
|
|
|
curl_formfree(post);
|
|
curl_easy_cleanup(easy_handle);
|
|
|
|
/* Store link if needed */
|
|
|
|
if(enable_links_history) {
|
|
snprintf(history_file_path,256,"%s/%s",getenv("HOME"),path);
|
|
store_link(history_file_path,buffer);
|
|
}
|
|
free(buffer);
|
|
return 0;
|
|
}
|
|
|
|
size_t static write_data(void *buffer, size_t size, size_t nmemb,
|
|
void *userp)
|
|
{
|
|
memcpy(userp, buffer, nmemb*size);
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
print_usage()
|
|
{
|
|
printf("USAGE: clainsafecli [--tor|--i2p] [--server] file\n");
|
|
return;
|
|
}
|
|
|
|
int
|
|
store_link(const char *path, const char *buf)
|
|
{
|
|
FILE *fp = fopen(path,"a+");
|
|
if(fp == NULL) {
|
|
fprintf(stderr,"Error opening file %i: %s\n",errno,
|
|
strerror(errno));
|
|
return -1;
|
|
}
|
|
fwrite(buf,strlen(buf),1,fp);
|
|
fputc('\n',fp);
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
print_help()
|
|
{
|
|
printf("--server <server>: specifies the lainsafe server\n%s\n%s",
|
|
"--tor: uses tor",
|
|
"--help: print this message\n");
|
|
return;
|
|
}
|
|
|
|
void
|
|
progress(void *clientp,
|
|
double dltotal,
|
|
double dlnow,
|
|
double ultotal,
|
|
double ulnow)
|
|
{
|
|
printf("\r%0.f uploaded of %0.f (%0.f%%)",ulnow,ultotal,
|
|
ulnow*100/ultotal);
|
|
fflush(stdout);
|
|
|
|
|
|
}
|