Cross-compile C++ with curl for ARM - c++

I've got a short C++ program to download a file with curl.
I can compile it with:
gcc main.cpp -L/usr/include/x86_64-linux-gnu/curl -lcurl
but when I try it to compile for my arm-development board with the command:
arm-linux-gnueabihf-gcc main.cpp -I/usr/include/x86_64-linux-gnu -L/usr/include/x86_64-linux-gnu/curl -lcurl
I got an error, that lcurl cannot be found.
Can somebody tell me how to compile my program the right way or how to install curl for arm on my Linux-Ubuntu-Machine
#include <curl/curl.h>
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main()
{
CURL *curl;
FILE *fp;
CURLcode res;
char *url = "...url...";
char outfilename[FILENAME_MAX] = "/home/test.txt";
curl = curl_easy_init();
if (curl)
{
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
// always cleanup
curl_easy_cleanup(curl);
fclose(fp);
}
return( 0 );
}

Related

How i can reduce curl in project

I have project with curl but size my file 720KB. This is a lot for me. I am use curl only for smtp, how i can reduce my file. I tried use defines discribed in CURL-DISABLE.md but that not worked, i think i configured them incorrectly. Can you give me instruction how i can reduce curl? My code of program.
#include <iostream>
#include <windows.h>
#define CURL_STATICLIB
#include "curl/curl.h"
#pragma comment(lib, "libcurl_a.lib")
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main(void)
{
CURL *curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://google.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
std::cout << readBuffer << std::endl;
}
return 0;
}
It work but a lot of size. SCREEN_OF_FILE_IN_PATH

Curl gives segmentation fault error

I am trying to download a .txt file from a server which I can access via the web browser on my raspberry pi.
Curl library gives segmentation error when I am trying to do this. Here is the code I am using.
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
int checkNewFiles(){
CURL *curl;
FILE *fp;
CURLcode res;
string url = "http://52.233.176.151:1880/files/device/software/text.txt";
char outfilename[FILENAME_MAX] = "/home/pi/Desktop/project/cpp/ab.txt";
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename, "wb");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
I found the problem, what is url.c_str() doing?
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
change this to
curl_easy_setopt(curl, CURLOPT_URL, url);
Example : Curl program that download the text file.
Offcourse you need to add this neccessary header file here.
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main(void) {
CURL *curl;
FILE *fp;
CURLcode res;
const char *url = "http://localhost/yourfile.txt";
char outfilename[FILENAME_MAX] = "C:\\outfile.txt";
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); /* enable failure on http errors */
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
if(res != CURLE_OK) { /* check that the operation was successful */
printf("curl_easy_perform(): %s\n", curl_easy_strerror(res));
}
/* always cleanup */
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
I noticed you're not checking for errors after fopen. If it fails, it returns a NULL pointer, which would cause a segfault when curl attempts to write to it.
I'm not convinced that c_str() was the culprit to your segfault in the original question as I have used that in numerous applications with no problems.

Error with libcurl using cygwin64 on in windows 10(x64)

I have installed the cygwin64 on windows 10, also there are installed the g++ and the libraries of libCurl. When I run the code the g++ compiler throw me this error '#error Only Win32 target is supported!'.
How I solve this error?
Have I to install another version or library?
TestCurl.cpp
#include <iostream>
#include <string>
#include <curl/curl.h>
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
int main(void)
{
CURL *curl;
CURLcode res;
std::string readBuffer;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "http://www.google.com");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
std::cout << readBuffer << std::endl;
}
return 0;
}
MakeFile
CC=g++
MIN_GW = C:\cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\include
all: call.o
call.o: call.cpp
$(CC) call.cpp -o call -I$(MIN_GW)
Error
Errorlog

Simple way to download a file with cURL

In my program, I want to download a few files. So I took cURL and used this code (taken and modified a little bit from here Download file using libcurl in C/C++):
#include "curl.h"
using namespace std;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int DlZip(){
CURL *curl;
FILE *fp;
CURLcode res;
string url = "http://wordpress.org/extend/plugins/about/readme.txt";
char outfilename[FILENAME_MAX] = "/Users/Me/Desktop/bbb.txt";
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
But nothing happened and there weren't any file on my desktop :-/
What is the problem with my code?
Or if you have a simple function to use, could you give me ?
Thanks!
Check Below code
#include <cstdio>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <string>
using namespace std;
size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int main(){
CURL *curl;
FILE *fp;
CURLcode res;
string url = "http://www.joes-hardware.com/tools.html";
char outfilename[FILENAME_MAX] = "./MyText.txt";
curl = curl_easy_init();
if (curl) {
fp = fopen(outfilename,"wb");
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(fp);
}
return 0;
}
It works fine.
The problem is - this code is not able to use https and hence when the url provided by you when opened in browser and through above code - produce separate responses.

libcurl 404 detection

I'm doing a file download with libcurl in my c++ program. How can i detect if the request is a 404, and not do the file write? The code is:
void GameImage::DownloadImage(string file_name) {
string game_name;
game_name = file_name.substr(file_name.find_last_of("/")+1);
CURL *curl;
FILE *fp;
CURLcode res;
string url = "http://site/"+game_name+".png";
string outfilename = file_name+".png";
cout<<"INFO; attempting to download "<<url<<"..."<<endl;
curl = curl_easy_init();
if (curl) {
cout<<"INFO; downloading "<<url<<"..."<<endl;
fp = fopen(outfilename.c_str(), "wb");
cout<<"INFO; trying to open "<<outfilename<<" for file output"<<endl;
if (fp != NULL) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GameImage::WriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
res = curl_easy_perform(curl);
long http_code = 0;
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code);
curl_easy_cleanup(curl);
fclose(fp);
}
else {
cout<<"GameImage::DownloadImage; Couldn't open output file"<<endl;
}
}
}
size_t GameImage::WriteData(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
I can delete the 404 response after the transfer occurs, but it would be good to not even save the response.
You can check against CURLE_HTTP_RETURNED_ERROR
This is returned if CURLOPT_FAILONERROR is set to true and the HTTP server returns an error code that is >= 400. You can't grab the specific HTTP response code, but should be enough to accomplish what you want.
I know this is an old post, but the error you're doing is that you're not checking the return value of curl_easy_perform. Setting CURLOPT_FAILONERROR will not crash the program, instead, it will notify you of the error through the return variable you named res. To get rid of the empty file, you could do something like this:
void GameImage::DownloadImage(string file_name) {
string game_name;
game_name = file_name.substr(file_name.find_last_of("/")+1);
CURL *curl;
FILE *fp;
CURLcode res;
string url = "http://site/"+game_name+".png";
string outfilename = file_name+".png";
cout<<"INFO; attempting to download "<<url<<"..."<<endl;
curl = curl_easy_init();
if (curl) {
cout<<"INFO; downloading "<<url<<"..."<<endl;
fp = fopen(outfilename.c_str(), "wb");
cout<<"INFO; trying to open "<<outfilename<<" for file output"<<endl;
if (fp == NULL) {
cout<<"GameImage::DownloadImage; Couldn't open output file"<<endl;
curl_easy_cleanup(curl);
return;
}
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GameImage::WriteData);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
res = curl_easy_perform(curl);
fclose(fp);
if (res != CURLE_OK) {
cout<<"GameImage::DownloadImage; Failed to download file"<<endl;
remove(outfilename.c_str());
}
curl_easy_cleanup(curl);
}
}
size_t GameImage::WriteData(void *ptr, size_t size, size_t nmemb, FILE *stream) {
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}