aboutsummaryrefslogtreecommitdiffstats
path: root/curl.c
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2019-01-18 10:33:52 +0100
committerGerd Hoffmann <kraxel@redhat.com>2019-01-18 10:34:42 +0100
commit63d51144092e0c51e65221f1544d7aef2950eec9 (patch)
tree40ea38e8639adc2d7b20d604f8717b78daeeefc3 /curl.c
parent4f83229c9b7ff9d267968a85f8f7c5ef3d18e11d (diff)
downloadfbida-63d51144092e0c51e65221f1544d7aef2950eec9.tar.gz
drop curl support
Diffstat (limited to 'curl.c')
-rw-r--r--curl.c349
1 files changed, 0 insertions, 349 deletions
diff --git a/curl.c b/curl.c
deleted file mode 100644
index f8f79bd..0000000
--- a/curl.c
+++ /dev/null
@@ -1,349 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-#include <sys/select.h>
-
-#include <curl/curl.h>
-#include <curl/easy.h>
-
-#include "curl.h"
-
-/* curl globals */
-static CURLM *curlm;
-static fd_set rd, wr, ex;
-
-/* my globals */
-static int url_debug = 0;
-static int url_timeout = 30;
-
-/* my structs */
-struct iobuf {
- off_t start;
- size_t size;
- char *data;
-};
-
-struct url_state {
- char *path;
- CURL *curl;
- char errmsg[CURL_ERROR_SIZE];
- off_t curl_pos;
- off_t buf_pos;
- struct iobuf buf;
- int eof;
-};
-
-/* ---------------------------------------------------------------------- */
-/* curl stuff */
-
-static void __attribute__ ((constructor)) curl_init(void)
-{
- curl_global_init(CURL_GLOBAL_ALL);
- curlm = curl_multi_init();
-}
-
-static void __attribute__ ((destructor)) curl_fini(void)
-{
- curl_multi_cleanup(curlm);
- curl_global_cleanup();
-}
-
-static void curl_free_buffer(struct iobuf *buf)
-{
- if (buf->data) {
- free(buf->data);
- memset(buf,0,sizeof(*buf));
- }
-}
-
-/* CURLOPT_WRITEFUNCTION */
-static int curl_write(void *data, size_t size, size_t nmemb, void *handle)
-{
- struct url_state *h = handle;
-
- curl_free_buffer(&h->buf);
- h->buf.start = h->curl_pos;
- h->buf.size = size * nmemb;
- h->buf.data = malloc(h->buf.size);
- memcpy(h->buf.data, data, h->buf.size);
- if (url_debug)
- fprintf(stderr," put %5d @ %5d\n",
- (int)h->buf.size, (int)h->buf.start);
-
- h->curl_pos += h->buf.size;
- return h->buf.size;
-}
-
-/* do transfers */
-static int curl_xfer(struct url_state *h)
-{
- CURLMcode rc;
- struct timeval tv;
- int count, maxfd;
-
- FD_ZERO(&rd);
- FD_ZERO(&wr);
- FD_ZERO(&ex);
- maxfd = -1;
- rc = curl_multi_fdset(curlm, &rd, &wr, &ex, &maxfd);
- if (CURLM_OK != rc) {
- fprintf(stderr,"curl_multi_fdset: %d %s\n",rc,h->errmsg);
- return -1;
- }
- if (-1 == maxfd) {
- /* wait 0.1 sec */
- if (url_debug)
- fprintf(stderr,"wait 0.01 sec\n");
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- } else {
- /* wait for data */
- if (url_debug)
- fprintf(stderr,"select for data [maxfd=%d]\n",maxfd);
- tv.tv_sec = url_timeout;
- tv.tv_usec = 0;
- }
- switch (select(maxfd+1, &rd, &wr, &ex, &tv)) {
- case -1:
- /* Huh? */
- perror("select");
- exit(1);
- case 0:
- /* timeout */
- return -1;
- }
- for (;;) {
- rc = curl_multi_perform(curlm,&count);
- if (CURLM_CALL_MULTI_PERFORM == rc)
- continue;
- if (CURLM_OK != rc) {
- fprintf(stderr,"curl_multi_perform: %d %s\n",rc,h->errmsg);
- return -1;
- }
- if (0 == count)
- h->eof = 1;
- break;
- }
- return 0;
-}
-
-/* curl setup */
-static int curl_setup(struct url_state *h)
-{
- if (h->curl) {
- curl_multi_remove_handle(curlm,h->curl);
- curl_easy_cleanup(h->curl);
- }
-
- h->curl = curl_easy_init();
- curl_easy_setopt(h->curl, CURLOPT_URL, h->path);
- curl_easy_setopt(h->curl, CURLOPT_ERRORBUFFER, h->errmsg);
- curl_easy_setopt(h->curl, CURLOPT_WRITEFUNCTION, curl_write);
- curl_easy_setopt(h->curl, CURLOPT_WRITEDATA, h);
- curl_multi_add_handle(curlm, h->curl);
-
- h->buf_pos = 0;
- h->curl_pos = 0;
- h->eof = 0;
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-/* GNU glibc custom stream interface */
-
-static ssize_t url_read(void *handle, char *buf, size_t size)
-{
- struct url_state *h = handle;
- size_t bytes, total;
- off_t off;
- int count;
-
- if (url_debug)
- fprintf(stderr,"url_read(size=%d)\n",(int)size);
- for (total = 0; size > 0;) {
- if (h->buf.start <= h->buf_pos &&
- h->buf.start + h->buf.size > h->buf_pos) {
- /* can satisfy from current buffer */
- bytes = h->buf.start + h->buf.size - h->buf_pos;
- off = h->buf_pos - h->buf.start;
- if (bytes > size)
- bytes = size;
- memcpy(buf+total, h->buf.data + off, bytes);
- if (url_debug)
- fprintf(stderr," get %5d @ %5d [%5d]\n",
- (int)bytes, (int)h->buf_pos, (int)off);
- size -= bytes;
- total += bytes;
- h->buf_pos += bytes;
- continue;
- }
- if (h->buf_pos < h->buf.start) {
- /* seeking backwards -- restart transfer */
- if (url_debug)
- fprintf(stderr," rewind\n");
- curl_free_buffer(&h->buf);
- curl_setup(h);
- while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlm,&count))
- /* nothing */;
- }
- if (h->eof)
- /* stop on eof */
- break;
- /* fetch more data */
- if (-1 == curl_xfer(h)) {
- if (0 == total)
- return -1;
- break;
- }
- }
- return total;
-}
-
-#if 0
-static ssize_t url_write(void *handle, const char *buf, size_t size)
-{
- //struct url_state *h = handle;
-
- if (url_debug)
- fprintf(stderr,"url_write(size=%d)\n",(int)size);
- return -1;
-}
-#endif
-
-static int url_seek(void *handle, off64_t *pos, int whence)
-{
- struct url_state *h = handle;
- int rc = 0;
-
- if (url_debug)
- fprintf(stderr,"url_seek(pos=%d,whence=%d)\n", (int)(*pos), whence);
- switch (whence) {
- case SEEK_SET:
- h->buf_pos = *pos;
- break;
- case SEEK_CUR:
- h->buf_pos += *pos;
- break;
- case SEEK_END:
- rc = -1;
- }
- *pos = h->buf_pos;
- return rc;
-}
-
-static int url_close(void *handle)
-{
- struct url_state *h = handle;
-
- if (url_debug)
- fprintf(stderr,"url_close()\n");
- curl_multi_remove_handle(curlm,h->curl);
- curl_easy_cleanup(h->curl);
- if (h->buf.data)
- free(h->buf.data);
- free(h->path);
- free(h);
- return 0;
-}
-
-static cookie_io_functions_t url_hooks = {
- .read = url_read,
-#if 0
- .write = url_write,
-#endif
- .seek = url_seek,
- .close = url_close,
-};
-
-static FILE *url_open(const char *path, const char *mode)
-{
- FILE *fp;
- struct url_state *h;
- int count;
-
- if (url_debug)
- fprintf(stderr,"url_open(%s,%s)\n",path,mode);
-
- h = malloc(sizeof(*h));
- if (NULL == h)
- goto err;
- memset(h,0,sizeof(*h));
-
- h->path = strdup(path);
- if (NULL == h->path)
- goto err;
-
- /* setup */
- curl_setup(h);
- fp = fopencookie(h, mode, url_hooks);
- if (NULL == fp)
- goto err;
-
- /* connect + start fetching */
- while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlm,&count))
- /* nothing */;
-
- /* check for errors */
- if (0 == count && NULL == h->buf.data) {
- errno = ENOENT;
- goto fetch_err;
- }
-
- /* all done */
- return fp;
-
-
- fetch_err:
- curl_multi_remove_handle(curlm,h->curl);
- err:
- if (h->curl)
- curl_easy_cleanup(h->curl);
- if (h->path)
- free(h->path);
- if (h)
- free(h);
- return NULL;
-}
-
-/* ---------------------------------------------------------------------- */
-/* hook into fopen using GNU ld's --wrap */
-
-int curl_is_url(const char *url)
-{
- static char *protocols[] = {
- "ftp://",
- "http://",
- NULL,
- };
- int i;
-
- for (i = 0; protocols[i] != NULL; i++)
- if (0 == strncasecmp(url, protocols[i], strlen(protocols[i])))
- return 1;
- return 0;
-}
-
-FILE *__wrap_fopen(const char *path, const char *mode);
-FILE *__real_fopen(const char *path, const char *mode);
-
-FILE *__wrap_fopen(const char *path, const char *mode)
-{
- if (url_debug)
- fprintf(stderr,"fopen(%s,%s)\n",path,mode);
-
- /* catch URLs */
- if (curl_is_url(path)) {
- if (strchr(mode,'w')) {
- fprintf(stderr,"write access over ftp/http is not supported, sorry\n");
- return NULL;
- }
- return url_open(path,mode);
- }
-
- /* files passed to the real fopen */
- return __real_fopen(path,mode);
-}