* instead of (only) local files. Local files (ie those that can be directly
* fopened) will drop back to using the underlying clib implementations
*
- * See the main() function at the bottom that shows an app that retrives from a
- * specified url using fgets() and fread() and saves as two output files.
+ * See the main() function at the bottom that shows an app that retrieves from
+ * a specified url using fgets() and fread() and saves as two output files.
*
- * Copyright (c) 2003 Simtec Electronics
+ * Copyright (c) 2003, 2017 Simtec Electronics
*
* Re-implemented by Vincent Sanders <vince@kyllikki.org> with extensive
* reference to original curl example code
#include <curl/curl.h>
enum fcurl_type_e {
- CFTYPE_NONE=0,
- CFTYPE_FILE=1,
- CFTYPE_CURL=2
+ CFTYPE_NONE = 0,
+ CFTYPE_FILE = 1,
+ CFTYPE_CURL = 2
};
struct fcurl_data
typedef struct fcurl_data URL_FILE;
/* exported functions */
-URL_FILE *url_fopen(const char *url,const char *operation);
+URL_FILE *url_fopen(const char *url, const char *operation);
int url_fclose(URL_FILE *file);
int url_feof(URL_FILE *file);
size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file);
-char * url_fgets(char *ptr, size_t size, URL_FILE *file);
+char *url_fgets(char *ptr, size_t size, URL_FILE *file);
void url_rewind(URL_FILE *file);
/* we use a global one for convenience */
-CURLM *multi_handle;
+static CURLM *multi_handle;
/* curl calls this routine to get more data */
static size_t write_callback(char *buffer,
URL_FILE *url = (URL_FILE *)userp;
size *= nitems;
- rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */
+ rembuff = url->buffer_len - url->buffer_pos; /* remaining space in buffer */
if(size > rembuff) {
/* not enough space in buffer */
- newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff));
- if(newbuff==NULL) {
- fprintf(stderr,"callback buffer grow failed\n");
- size=rembuff;
+ newbuff = realloc(url->buffer, url->buffer_len + (size - rembuff));
+ if(newbuff == NULL) {
+ fprintf(stderr, "callback buffer grow failed\n");
+ size = rembuff;
}
else {
/* realloc succeeded increase buffer size*/
- url->buffer_len+=size - rembuff;
- url->buffer=newbuff;
+ url->buffer_len += size - rembuff;
+ url->buffer = newbuff;
}
}
/* get file descriptors from the transfers */
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
- if(mc != CURLM_OK)
- {
+ if(mc != CURLM_OK) {
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}
else {
/* Note that on some platforms 'timeout' may be modified by select().
If you need access to the original value save a copy beforehand. */
- rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
+ rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
}
switch(rc) {
static int use_buffer(URL_FILE *file, size_t want)
{
/* sort out buffer */
- if((file->buffer_pos - want) <=0) {
+ if((file->buffer_pos - want) <= 0) {
/* ditch buffer - write will recreate */
free(file->buffer);
- file->buffer=NULL;
- file->buffer_pos=0;
- file->buffer_len=0;
+ file->buffer = NULL;
+ file->buffer_pos = 0;
+ file->buffer_len = 0;
}
else {
/* move rest down make it available for later */
return 0;
}
-URL_FILE *url_fopen(const char *url,const char *operation)
+URL_FILE *url_fopen(const char *url, const char *operation)
{
/* this code could check for URLs or types in the 'url' and
basically use the real fopen() for standard files */
memset(file, 0, sizeof(URL_FILE));
- if((file->handle.file=fopen(url,operation)))
+ file->handle.file = fopen(url, operation);
+ if(file->handle.file)
file->type = CFTYPE_FILE; /* marked as URL */
else {
int url_fclose(URL_FILE *file)
{
- int ret=0;/* default is good return */
+ int ret = 0;/* default is good return */
switch(file->type) {
case CFTYPE_FILE:
- ret=fclose(file->handle.file); /* passthrough */
+ ret = fclose(file->handle.file); /* passthrough */
break;
case CFTYPE_CURL:
break;
default: /* unknown or supported type - oh dear */
- ret=EOF;
- errno=EBADF;
+ ret = EOF;
+ errno = EBADF;
break;
}
int url_feof(URL_FILE *file)
{
- int ret=0;
+ int ret = 0;
switch(file->type) {
case CFTYPE_FILE:
- ret=feof(file->handle.file);
+ ret = feof(file->handle.file);
break;
case CFTYPE_CURL:
break;
default: /* unknown or supported type - oh dear */
- ret=-1;
- errno=EBADF;
+ ret = -1;
+ errno = EBADF;
break;
}
return ret;
switch(file->type) {
case CFTYPE_FILE:
- want=fread(ptr,size,nmemb,file->handle.file);
+ want = fread(ptr, size, nmemb, file->handle.file);
break;
case CFTYPE_CURL:
want = nmemb * size;
- fill_buffer(file,want);
+ fill_buffer(file, want);
- /* check if theres data in the buffer - if not fill_buffer()
+ /* check if there's data in the buffer - if not fill_buffer()
* either errored or EOF */
if(!file->buffer_pos)
return 0;
/* xfer data to caller */
memcpy(ptr, file->buffer, want);
- use_buffer(file,want);
+ use_buffer(file, want);
want = want / size; /* number of items */
break;
default: /* unknown or supported type - oh dear */
- want=0;
- errno=EBADF;
+ want = 0;
+ errno = EBADF;
break;
}
break;
case CFTYPE_CURL:
- fill_buffer(file,want);
+ fill_buffer(file, want);
- /* check if theres data in the buffer - if not fill either errored or
+ /* check if there's data in the buffer - if not fill either errored or
* EOF */
if(!file->buffer_pos)
return NULL;
/*buffer contains data */
/* look for newline or eof */
- for(loop=0;loop < want;loop++) {
+ for(loop = 0; loop < want; loop++) {
if(file->buffer[loop] == '\n') {
- want=loop+1;/* include newline */
+ want = loop + 1;/* include newline */
break;
}
}
/* xfer data to caller */
memcpy(ptr, file->buffer, want);
- ptr[want]=0;/* allways null terminate */
+ ptr[want] = 0;/* always null terminate */
- use_buffer(file,want);
+ use_buffer(file, want);
break;
default: /* unknown or supported type - oh dear */
- ptr=NULL;
- errno=EBADF;
+ ptr = NULL;
+ errno = EBADF;
break;
}
/* ditch buffer - write will recreate - resets stream pos*/
free(file->buffer);
- file->buffer=NULL;
- file->buffer_pos=0;
- file->buffer_len=0;
+ file->buffer = NULL;
+ file->buffer_pos = 0;
+ file->buffer_len = 0;
break;
}
}
-/* Small main program to retrive from a url using fgets and fread saving the
+#define FGETSFILE "fgets.test"
+#define FREADFILE "fread.test"
+#define REWINDFILE "rewind.test"
+
+/* Small main program to retrieve from a url using fgets and fread saving the
* output to two test files (note the fgets method will corrupt binary files if
* they contain 0 chars */
int main(int argc, char *argv[])
const char *url;
if(argc < 2)
- url="http://192.168.7.3/testfile";/* default to testurl */
+ url = "http://192.168.7.3/testfile";/* default to testurl */
else
- url=argv[1];/* use passed url */
+ url = argv[1];/* use passed url */
/* copy from url line by line with fgets */
- outf=fopen("fgets.test","w+");
+ outf = fopen(FGETSFILE, "wb+");
if(!outf) {
perror("couldn't open fgets output file\n");
return 1;
}
while(!url_feof(handle)) {
- url_fgets(buffer,sizeof(buffer),handle);
- fwrite(buffer,1,strlen(buffer),outf);
+ url_fgets(buffer, sizeof(buffer), handle);
+ fwrite(buffer, 1, strlen(buffer), outf);
}
url_fclose(handle);
/* Copy from url with fread */
- outf=fopen("fread.test","w+");
+ outf = fopen(FREADFILE, "wb+");
if(!outf) {
perror("couldn't open fread output file\n");
return 1;
do {
nread = url_fread(buffer, 1, sizeof(buffer), handle);
- fwrite(buffer,1,nread,outf);
+ fwrite(buffer, 1, nread, outf);
} while(nread);
url_fclose(handle);
/* Test rewind */
- outf=fopen("rewind.test","w+");
+ outf = fopen(REWINDFILE, "wb+");
if(!outf) {
perror("couldn't open fread output file\n");
return 1;
return 2;
}
- nread = url_fread(buffer, 1,sizeof(buffer), handle);
- fwrite(buffer,1,nread,outf);
+ nread = url_fread(buffer, 1, sizeof(buffer), handle);
+ fwrite(buffer, 1, nread, outf);
url_rewind(handle);
buffer[0]='\n';
- fwrite(buffer,1,1,outf);
-
- nread = url_fread(buffer, 1,sizeof(buffer), handle);
- fwrite(buffer,1,nread,outf);
+ fwrite(buffer, 1, 1, outf);
+ nread = url_fread(buffer, 1, sizeof(buffer), handle);
+ fwrite(buffer, 1, nread, outf);
url_fclose(handle);
fclose(outf);
-
return 0;/* all done */
}