93 lines
2.8 KiB
C
93 lines
2.8 KiB
C
// This file is part of Snownews - A lightweight console RSS newsreader
|
|
//
|
|
// Copyright (c) 2003-2004 Oliver Feiler <kiza@kcore.de>
|
|
// Copyright (c) 2021 Mike Sharov <msharov@users.sourceforge.net>
|
|
//
|
|
// Snownews is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 3
|
|
// as published by the Free Software Foundation.
|
|
//
|
|
// Snownews 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 Snownews. If not, see http://www.gnu.org/licenses/.
|
|
|
|
#include "netio.h"
|
|
#include "ui-support.h"
|
|
#include <curl/curl.h>
|
|
|
|
static size_t FeedReceiver (void* buffer, size_t msz, size_t nm, void* vpfeed)
|
|
{
|
|
struct feed* fp = vpfeed;
|
|
size_t size = msz * nm;
|
|
char* t = realloc (fp->xmltext, fp->content_length + size + 1);
|
|
if (!t) {
|
|
fprintf (stderr, "Error: out of memory\n");
|
|
exit (EXIT_FAILURE);
|
|
}
|
|
fp->xmltext = t;
|
|
memcpy (&fp->xmltext[fp->content_length], buffer, size);
|
|
fp->content_length += size;
|
|
fp->xmltext [fp->content_length] = 0;
|
|
return size;
|
|
}
|
|
|
|
// Returns allocated string with body of webserver reply.
|
|
// Various status info put into struct feed* fp.
|
|
void DownloadFeed (const char* url, struct feed* fp)
|
|
{
|
|
// Default to error
|
|
if (fp->xmltext) {
|
|
free (fp->xmltext);
|
|
fp->xmltext = NULL;
|
|
fp->content_length = 0;
|
|
}
|
|
fp->problem = true;
|
|
|
|
// libcurl global init must be called only once
|
|
// snownews is single threaded, so no fancy locks needed
|
|
static bool s_curl_initialized = false;
|
|
if (!s_curl_initialized) {
|
|
if (0 != curl_global_init (CURL_GLOBAL_DEFAULT)) {
|
|
UIStatus ("Error: failed to initialize libcurl", 2, 1);
|
|
syslog (LOG_ERR, "failed to initialize libcurl");
|
|
return;
|
|
}
|
|
atexit (curl_global_cleanup);
|
|
s_curl_initialized = true;
|
|
}
|
|
|
|
CURL* curl = curl_easy_init();
|
|
if (!curl)
|
|
return;
|
|
|
|
curl_easy_setopt (curl, CURLOPT_URL, url);
|
|
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, FeedReceiver);
|
|
curl_easy_setopt (curl, CURLOPT_WRITEDATA, fp);
|
|
|
|
char cookiefile [PATH_MAX];
|
|
unsigned cfnl = snprintf (cookiefile, sizeof(cookiefile), SNOWNEWS_CONFIG_DIR "cookies", getenv("HOME"));
|
|
if (cfnl < sizeof(cookiefile) && access (cookiefile, R_OK) == 0)
|
|
curl_easy_setopt (curl, CURLOPT_COOKIEFILE, cookiefile);
|
|
|
|
CURLcode rc = curl_easy_perform (curl);
|
|
|
|
curl_easy_cleanup (curl);
|
|
|
|
if (rc == CURLE_OK)
|
|
fp->problem = false;
|
|
else if (fp->xmltext) {
|
|
free (fp->xmltext);
|
|
fp->xmltext = NULL;
|
|
fp->content_length = 0;
|
|
const char* cerrt = curl_easy_strerror (rc);
|
|
if (cerrt) {
|
|
UIStatus (cerrt, 2, 1);
|
|
syslog (LOG_ERR, "%s", cerrt);
|
|
}
|
|
}
|
|
}
|